Re: Gcc Digest, Vol 5, Issue 52
On Tue, Jul 28, 2020 at 11:02 PM Gary Oblock wrote: > > Richard, > > I wasn't aware of release_defs so I'll add that for certain. > > When I do a single transformation as part of the transformation pass > each transformation uses the correct types internally but on the edges > emits glue code that will be transformed via a dangling type fixup pass. > > For example when adding something to a pointer: > > _2 = _1 + k > > Where _1 & _2 are the old point types I'll > emit > > new_3 = (type_convert)_1 > new_4 = (type_convert)k > new_5 = new_4 / struct_size // truncating divide > new_6 = new_3 + new_5 > _2 = (type_convert)_new_6 > > Note, the casting is done with CONVERT_EXPR > which is harmless when I create new ssa names > and set the appropriate operands in OK, so you're funneling the new "index" values through the original pointer variable _1? But then I don't see where the patching up of SSA names and the default def issue happens. > new_3 = (type_convert)_1 > _2 = (type_convert)new_6 > > to > > new_3 = new_7 > new_8 = new_6 > > Now I might actually find via a look up that > _1 and/or _2 were already mapped to > new_7 and/or new_8 but that's irrelevant. > > To intermix the applications of the transformations and > the patching of these dangling types seems like I'd > need to do an insanely ugly recursive walk of each functions > body. > > I'm curious when you mention def-use I'm not aware of > GCC using def-use chains except at the RTL level. > Is there a def-use mechanism in GIMPLE because > in SSA form it's trivial to find the definition of > a temp variable but non trivial to find the use of > it. Which I think is a valid reason for fixing up the > dangling types of temps in a scan. In GIMPLE SSA we maintain a list of uses for each SSA def, available via the so called immediate-uses. You can grep for uses of FOR_EACH_IMM_USE[_FAST] > > Note, I'll maintain a mapping like you suggest but not use > it at transformation application time. Furthermore, > I'll initialize the mapping with the default defs from > the DECLs so I won't have to mess with them on the fly. > Now at the time in the scan when I find uses and defs of > a dangling type I'd like to simply modify the associated operands > of the statement. What is the real advantage creating a new > statement with the correct types? I'll be using SSA_NAME_DEF_STMT > if the newly created ssa name is on the left hand side. Also, the > ssa_name it replaces will no longer be referenced by the end of the > scan pass. Since you are replacing a[i].b with array_for_b[i] I am wondering how you do the transform for non-pointer adjustments. > Note, I do have a escape mechanism in a qualification > pre-pass to the transformations. It's not intended as > catch-all for things I don't understand rather it's an > aid to find possible new cases. However, there are > legitimate things at this point in time during development > of this optimization that I need to spot things this way. Later, > when points to analysis is integrated falling through to > the default case behavior will likely cause an internal error. > > Thanks, > > Gary > > > From: Richard Biener > Sent: Tuesday, July 28, 2020 12:07 AM > To: Gary Oblock > Cc: gcc@gcc.gnu.org > Subject: Re: Gcc Digest, Vol 5, Issue 52 > > [EXTERNAL EMAIL NOTICE: This email originated from an external sender. Please > be mindful of safe email handling and proprietary information protection > practices.] > > > On Tue, Jul 28, 2020 at 4:36 AM Gary Oblock via Gcc wrote: > > > > Almost all of the makes sense to. > > > > I'm not sure what a conditionally initialized pointer is. > > { > void *p; > if (condition) > p = ...; > if (other condition) > ... use p; > > will end up with a PHI node after the conditional init with > one PHI argument being the default definition SSA name > for 'p'. > > > > You mention VAR_DECL but I assume this is for > > completeness and not something I'll run across > > associated with a default def (but then again I don't > > understand notion of a conditionally initialized > > pointer.) > > > > I'm at the moment only dealing with a single malloced > > array of structures of the given type (though multiple types could have > > this property.) I intend to extend this to cover multiple array and static > > allocations but I need to get the easiest case working first. This means no > > side pointers are needed and if and when I need them pointer will get > > transformed into a base and index pair. > > > > I intend to do the creation of new ssa names as a separate pass from the > > gimple transformations. So I will technically be creating for the duration > > of the pass possibly two defs associated with a single gimple statement. Do > > I need to delete the old ssa names > > via some mechanism? > > When you remove the old definition do > >gsi_remove (&gsi, true); // gsi points at stmt >release_defs (stmt); > > note that as far as
Re: Run a single ada test
On 7/28/20 2:57 PM, Andreas Schwab wrote: On Jul 28 2020, William Seurer wrote: There does not appear to be a check-gnat in any of the makefiles. See LANG_MAKEFRAGS. I see some stuff about that (and check-gnat, too) in some of the makefile input files but it doesn't seem to do anything when I run configure (for all languages). Is there some configure option or environment variable I need to use? Is it documented somewhere?
Re: Future debug options: -f* or -g*?
On Fri, Jul 10, 2020 at 12:09 PM Nathan Sidwell wrote: > > On 7/9/20 3:28 PM, Fangrui Song via Gcc wrote: > > Fix email addresses:) > > > > IMHO the -f ones are misnamed. > -fFOO -> affect generated code (non-target-specific) or language feature > -gFOO -> affect debug info > -mFOO -> machine-specific option > > the -fdump options are misnamed btw, I remember Jeff Law pointed that out > after > Mark Mitchell added the first one. I'm not sure why we didn't rename it right > then. I'll bet there are other -foptions that don;t match my comfortable > world > view :) Appreciate the perspective, for sure! It sounds like some folks who've worked on this a fair bit (at least myself, Eric Christopher, and Cary Coutant) have had a different perspective for quite a while - that -g flags generally turn on debug info emission (& customize it in some way, potentially) and -f flags modify the emission but don't enable it. Specifically this conversation arose around changing the semantics of -gsplit-dwarf, which currently enables debug info emission and customizes the nature of that emission. There's a desire to separate these semantics. I have a few issues with this that I'd like to avoid: 1) changing the semantics of an existing flag (I think it's best to introduce a new one, perhaps deprecate the old one), especially across two compilers, issues around version compatibility, etc seem less than ideal 2) especially given the existing semantics of the flag it seems like it'd add to the confusion to make -gsplit-dwarf no longer imply -g2, whereas adding -fsplit-dwarf would be less ambiguous/more clear that this is not going to turn on debug info emission Going forward for new flags, I still feel like (given the current proliferation of -g flags that do enable debug info emission and tweak it) the ambiguity of -g flags is problematic from a usability perspective, but I'd be less opposed to new flags using -g than I am to changing the semantics of an existing -g flag. If GCC is outright "hard no" on -fsplit-dwarf and (sounds like) has already changed -gsplit-dwarf semantics, Clang will essentially have to follow to avoid greater confusion, but I'd like to avoid that if possible. Thoughts? Are there other ways we could reduce the ambiguity between "enables debug info" and "tweaks debug info emission, if enabled"? - Dave > > nathan > > > On 2020-07-09, Fangrui Song wrote: > >> Both GCC and Clang have implemented many debugging options under -f and > >> -g. Whether options go to -f or -g appears to be pretty arbitrary > >> decisions. > >> > >> A non-complete list of GCC supported debug options is documented here at > >> https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html > >> > >> I think there options belong to 3 categories: > >> > >> (a) -f* & doesn't imply -g2: -fdebug-types-section > >> -feliminate-unused-debug-types, > >> -fdebug-default-version=5 (this exists in clang purely because -gdwarf-5 > >> implies -g2 & there is need to not imply -g2) > >> (b) -g* & implies -g2: -gsplit-dwarf (I want to move this one to (c) > >> http://lists.llvm.org/pipermail/cfe-dev/2020-July/066202.html ) > >>-gdwarf-5, -ggdb, -gstabs > >> (c) -g* but does not imply -g2: -ggnu-pubnames, -gcolumn-info, > >> -gstrict-dwarf, > >> -gz, ... > >>the list appears to be much longer than (b) > >> > >> ( (b) isn't very good to its non-orthogonality. The interaction with -g0 > >> -g1 > >> and -g3 can be non-obvious sometimes.) > >> > >> Cary Coutant kindly shared with me his understanding about debug > >> options (attached at the end). Many established options can't probably > >> be fixed now. Some are still fixable (-gsplit-dwarf). > >> > >> This post is mainly about future debug options. Shall we figure out a > >> convention for future debug options? > >> > >> Personally I'd prefer (c) but I won't object to (a). > >> I'd avoid (b). > >> > >>> In retrospect, I regret not naming the option -fsplit-dwarf, which > >>> clearly would not have implied -g, and would have fit in with a few > >>> other dwarf-related -f options. (I don't know whether Richard's > >>> objection to it is because there is already -gsplit-dwarf, or if he > >>> would have objected to it as an alternative-universe spelling.) > >>> > >>> At the time, I thought it was fairly common for all/most -g options > >>> (except -g0) to imply -g. Perhaps that wasn't true then or is no > >>> longer true now. If the rest of the community is OK with changing > >>> -gsplit-dwarf to not imply -g, and no one has said it would cause them > >>> any hardship, I'm OK with your proposed change. > >>> > >>> I did design it so that you could get the equivalent by simply writing > >>> "-gsplit-dwarf -g0" at the front of the compiler options (e.g., via an > >>> environment variable), so that a subsequent -g would not only turn on > >>> debug but would also enable split-dwarf. We used that fairly regularly > >>> at Google. > >>> > >>> Regarding how the
[GSoC] Automatic Detection of Parallel Compilation Viability, Report 2
Hi. Here I present the second report of the "Automatic Detection of Parallel Compilation Viability" in Markdown format. --- # Automatic Parallel Compilation Viability: Second Report ## Complete Tasks For the second evaluation, we expected to have a working version of the project that result in speedups when compile large files, and have a working integration with the GNU Jobserver. Both of these tasks are complete, and I will discuss some decisions made to achive this. ## Compilation Unit Partitioning In the first implementation, we had a bug where partitioning were done before LTRANS stage were executed, implying in information loss and undesired collateral effects such as bad inlining. This was fixed later on. After this, we decided to implement two modes of partitioning: 1. Partition without static promotion. This is the safer method to use, as we do not modify symbols in the Compilation Unit. This may lead to speedups in files that have multiple entries points with low connectivity between then (such as insn-emit.c), however this will not provide speedups when this hypothesis is not true (gimple-match.c is an example of this). 2. Partition with static promotion to global. This is a more aggressive method, as we can decide to promote some functions to global to increase parallelism opportunity. This also will change the final assembler name of the promoted function to avoid collision with functions of others Compilation Units. To use this mode, the user has to manually specify --param=promote-statics=1, as they must be aware of this. We also changed the conditions to decide whether a symbol will be in some partition or not, as implemented in `lto_merge_comdats_map` in lto-cgraph.c: 1. Find what symbols may have to bring COMDATs to its partition. We do that by defining a COMDAT frontier and marking all these symbols to be partitioned together. 2. Find symbols that may be part of other symbols, and mark them to be partitioned together. 3. If static promotion is disabled, mark symbols that references and calls static functions, and mark them to be partitioned together. Although condition 1. required some more complicated analysis, this reduced code complexity of the previous partitioner. ## Jobserver Integration We implemented a interface to communicate with the GNU Make's Jobserver that is able to detect when the GNU Make Jobserver is active, thanks to Nathan Sidwell. This works as follows: When -fparallel-jobs=jobserver is provided, GCC will try to detect if there is a running Jobserver in which we can communicate to. If true, we return the token that Make originally gave to us, then we wait for make for a new token that, when provided, will launch a forked child process with the partition information; or fall back to default compilation if Jobserver is not detected with a warning. Now if -fparallel-jobs=auto, this warning will not be provided and the default number of jobs will be set to 2, unless a single core CPU is detected. For more information about the implementation, check gcc/jobserver.cc file in the autopar_devel branch. ## Current Status Currently, we have the following scenario: 1. Bootstrap works with promote statics disabled, and when enabled object comparison fails on stage3 because promoted symbols name are randomized for now. This impacts reproducible builds and safer methods must be employed to fix this, such as maybe using the file SHA hash as a way to avoid name colision. 2. Jobserver integration works but modifications to the Makefile are necessary. So far, the current branch is not able to bootstrap with -fparallel-jobs=jobserver because such modifications are required to GCC's Makefiles. However, we managed to compile Git with this option enabled, therefore supporting the claim that it is working to a certain level. 3. Speedups ranged from 0.95x to 1.9x on a Quad-Core Intel Core-i7 8565U when testing with two files in GCC, as stated in the following table. The test was the result of a single execution with a previous warm up execution. The compiled GCC had checking enabled, and therefore release version might have better timings in both sequential and parallel, but the speedup may remain the same. ||| Without Static | With Static | | | File | Sequential |Promotion | Promotion | Speedup | ||||---| | gimple-match.c | 60s| 63s | 34s | 1.7x | | insn-emit.c| 37s| 19s | 20s | 1.9x | 4. Supported Frontends: C, C++, Fortran. Others frontends can also be easily supported if they do not require the GCC driver to spawn multiple processes to compile a single file to assembler. ## How to use this 1. Clone the autopar_devel branch: ``` git clone --single-branch --branch devel/autopar_devel \ git://gcc.gnu.org/git/gcc.git
Memory Handling
Hello Jakub, Thank you very much for giving me a detailed instruction. I spent yesterday studying the information over. I have few questions, and have also attached a work-in-progress patch to confirm that I am heading the right direction. On Tue, Jul 28, 2020 at 6:26 AM Jakub Jelinek wrote: > On Mon, Jul 27, 2020 at 01:59:01PM -0400, y2s1982 via Gcc-patches wrote: > > I do know you have said this several times, and I thought I understood > it, > > but it seems I am wrong each time. I just want to clarify my > understanding > > and what I had intended on doing on this and would like further > explanation > > on what you would like to see happen more specifically so that I may make > > less mistakes. > > > > My assumption in this patch was that, as the > ompd_callback_symbol_addr_fn_t > > callback function takes 2 context addresses and string query as input, > and > > ompd_address_t address as an output, I should give it: > > - the context addresses, which I assumed would contain a single data in > > compact form generated from the tool's side having size, offset, and > > address information, > > - and a string, which is basically a query that needs to be interpreted > > by the callback function to determine which part of the data it needs to > > use to generate to the returning pointer. > > The standard of course can't go into details on what exactly it is, because > it is heavily dependent on what object format is used, etc. > But for ELF, the intent is that the symbol addr callback does pretty much > what dlsym does, i.e. perform a (dynamic) symbol lookup like the dynamic > linker normally performs. It likely can't use the dynamic linker directly, > for running processes that would mean having to perform an inferior call to > the libdl library, and for core files there is no running process to do it > in, but it knows all the currently loaded libraries, their search order and > so can in that order go one library by one and search their dynamic symbol > tables (if you do nm -D on a library or readelf -Ws, you'll see what is in > there), relocate the addresses in there for shared libraries depending on > their load bias (difference between the addresses they are loaded at and > linked to) and return those. If filename is supplied, then it would > perform > the lookup primarily in the given shared library and only then fallback to > others. > > > I wasn't sure what role the filename input played in this. > > This seemed to fit what you meant by having a single compact data that > > contains all the information while resolving my ongoing mystery as to > what > > the callback was expecting to have as the string identifying the symbol. > To > > further clarify, I assumed the callback would do string manipulation and > > comparison to identify which information is being requested, refer to the > > single data contained in appropriate context, and return the address > > information. > > > > I am more than willing to scrap my bad idea for a better one. I am > > sincerely interested in learning better ways to implement and improve > > myself. I just need to know more specifics of the design, particularly: > > - where the compact data is stored (I assumed context, which means it > might > > not be defined in the library side, but should it be in the handle or > > global to library?), > > - how the information necessary for the compact data is gathered (if it > is > > done on the library side, should I just use the ompd_callback_sizeof_fn_t > > to obtain primitive sizes, and from there, just build the offset > > information for each variable members? How about variable address?) > > - how the ompd_callback_symbol_addr_fn_t callback function would likely > use > > it given its arguments (input of 2 contexts, 1 file name, 1 string to > > output 1 address), > > - what are the expected strings for the callback that would correspond to > > each variable (here, I assume, the types would be gomp_thread, > > gompd_thread_pool, gomp_team, etc.) or each member of said variables, > > (these, at least I expected, should be documented and agreed on between > > library and tool), > > among other things. > > So, there are multiple things you might need to know about the libgomp > shared library's internal ABI in order to implement the OMPD library that > can handle it. > One thing are addresses of internal variables. > > Say if OMPD wants to query the value of some ICV, those have different > scopes, some of them are per-process, others per-device, others per-thread, > others per-task. Say the cancel-var is per process and stored in > gomp_cancel_var which is a bool variable (in env.c). > If you look for that symbol: > readelf -Ws libgomp.so.1 | grep gomp_cancel_var >478: 00041704 1 OBJECT LOCAL DEFAULT 24 gomp_cancel_var > you'll see that there is such a symbol, but it is (intentionally) not > exported and not present in .dynsym, so the symbol lookup callback can't > find it. > So, if OMPD needs to
Re: Gcc Digest, Vol 5, Issue 52
Richard, Thanks, I had no idea about the immediate uses mechanism and using it will speed things up a bit and make them more reliable. However, I'll still have to scan the LHS of each assignment unless there's a mechanism to traverse all the SSAs for a function. Note, I assume there is also a mechanism to add and remove immediate use instances. If I can find it I'll post a question to the list. I do the the patching on a per function basis immediately after applying the transforms. It was going to be a scan of all the GIMPLE. What you've told me might make it a bit of a misnomer to call what I intend to do now, a scan. The default defs problem happened when the original scan tried to simply modify the type of a default def. There didn't seem to be a way of doing this and I've since learned this in fact associates declarations not types but with a declaration. Note, just modifying the type of normal ssa names seemed to work but I can't in fact know it actually would have. I'm not sure I can do justice to the other transformations but here is one larger example. Note, since I'm currently only dealing with dynamically allocated array I'll only see "a->f" and not "a[i].f" so you are getting the former. _2 = _1->f turns into get_field_arry_addr: new_3 = array_base.f_array_field get_index : new_4 = (sizetype)_1 get_offset : new_5 = new_4 * size_of_f_element get_field_addr: new_6 = new_3 + new_5 // uses pointer arith temp_set: new_7 = * new_6 final_set : _2 = new_7 I hope that's sufficient to satisfy your curiosity because the only other large transformation currently coded is that for the malloc which would take me quite a while to put together an example of. Note, these are shown in the HL design doc which I sent you. Though like battle plans, no design no matter how good survives coding intact. Thanks again, Gary From: Richard Biener Sent: Wednesday, July 29, 2020 5:42 AM To: Gary Oblock Cc: gcc@gcc.gnu.org Subject: Re: Gcc Digest, Vol 5, Issue 52 [EXTERNAL EMAIL NOTICE: This email originated from an external sender. Please be mindful of safe email handling and proprietary information protection practices.] On Tue, Jul 28, 2020 at 11:02 PM Gary Oblock wrote: > > Richard, > > I wasn't aware of release_defs so I'll add that for certain. > > When I do a single transformation as part of the transformation pass > each transformation uses the correct types internally but on the edges > emits glue code that will be transformed via a dangling type fixup pass. > > For example when adding something to a pointer: > > _2 = _1 + k > > Where _1 & _2 are the old point types I'll > emit > > new_3 = (type_convert)_1 > new_4 = (type_convert)k > new_5 = new_4 / struct_size // truncating divide > new_6 = new_3 + new_5 > _2 = (type_convert)_new_6 > > Note, the casting is done with CONVERT_EXPR > which is harmless when I create new ssa names > and set the appropriate operands in OK, so you're funneling the new "index" values through the original pointer variable _1? But then I don't see where the patching up of SSA names and the default def issue happens. > new_3 = (type_convert)_1 > _2 = (type_convert)new_6 > > to > > new_3 = new_7 > new_8 = new_6 > > Now I might actually find via a look up that > _1 and/or _2 were already mapped to > new_7 and/or new_8 but that's irrelevant. > > To intermix the applications of the transformations and > the patching of these dangling types seems like I'd > need to do an insanely ugly recursive walk of each functions > body. > > I'm curious when you mention def-use I'm not aware of > GCC using def-use chains except at the RTL level. > Is there a def-use mechanism in GIMPLE because > in SSA form it's trivial to find the definition of > a temp variable but non trivial to find the use of > it. Which I think is a valid reason for fixing up the > dangling types of temps in a scan. In GIMPLE SSA we maintain a list of uses for each SSA def, available via the so called immediate-uses. You can grep for uses of FOR_EACH_IMM_USE[_FAST] > > Note, I'll maintain a mapping like you suggest but not use > it at transformation application time. Furthermore, > I'll initialize the mapping with the default defs from > the DECLs so I won't have to mess with them on the fly. > Now at the time in the scan when I find uses and defs of > a dangling type I'd like to simply modify the associated operands > of the statement. What is the real advantage creating a new > statement with the correct types? I'll be using SSA_NAME_DEF_STMT > if the newly created ssa name is on the left hand side. Also, the > ssa_name it replaces will no longer be referenced by the end of the > scan pass. Since you are replacing a[i].b with array_for_b[i] I am wondering how you do the transform for non-pointer adjustments. > Note, I do have a escape mechanism in a qualification > pre-pass to the trans
Re: Gcc Digest, Vol 5, Issue 52
On Wed, Jul 29, 2020 at 9:39 PM Gary Oblock wrote: > > Richard, > > Thanks, I had no idea about the immediate uses mechanism and > using it will speed things up a bit and make them more reliable. > However, I'll still have to scan the LHS of each assignment unless > there's a mechanism to traverse all the SSAs for a function. May I suggest that you give the GCC internals manual a read, particularly the sections about GIMPLE, GENERIC and 'Analysis and Optimization of GIMPLE tuples'. Most of the info I provided is documented there. > Note, I assume there is also a mechanism to add and remove > immediate use instances. If I can find it I'll post a question to the list. > > I do the the patching on a per function basis immediately after > applying the transforms. It was going to be a scan of all the > GIMPLE. What you've told me might make it a bit of a misnomer > to call what I intend to do now, a scan. The default defs problem > happened when the original scan tried to simply modify the type > of a default def. There didn't seem to be a way of doing this and I've > since learned this in fact associates declarations not types but with > a declaration. Note, just modifying the type of normal ssa names > seemed to work but I can't in fact know it actually would have. > > I'm not sure I can do justice to the other transformations but > here is one larger example. Note, since I'm currently only > dealing with dynamically allocated array I'll only see "a->f" and > not "a[i].f" so you are getting the former. > > _2 = _1->f > > turns into > > get_field_arry_addr: new_3 = array_base.f_array_field > get_index : new_4 = (sizetype)_1 > get_offset : new_5 = new_4 * size_of_f_element > get_field_addr: new_6 = new_3 + new_5 // uses pointer arith > temp_set: new_7 = * new_6 > final_set : _2 = new_7 > > I hope that's sufficient to satisfy your curiosity because the only other > large transformation currently coded is that for the malloc which would > take me quite a while to put together an example of. Note, these are > shown in the HL design doc which I sent you. Though like battle plans, > no design no matter how good survives coding intact. > > Thanks again, > > Gary > > > > > > From: Richard Biener > Sent: Wednesday, July 29, 2020 5:42 AM > To: Gary Oblock > Cc: gcc@gcc.gnu.org > Subject: Re: Gcc Digest, Vol 5, Issue 52 > > [EXTERNAL EMAIL NOTICE: This email originated from an external sender. Please > be mindful of safe email handling and proprietary information protection > practices.] > > > On Tue, Jul 28, 2020 at 11:02 PM Gary Oblock wrote: > > > > Richard, > > > > I wasn't aware of release_defs so I'll add that for certain. > > > > When I do a single transformation as part of the transformation pass > > each transformation uses the correct types internally but on the edges > > emits glue code that will be transformed via a dangling type fixup pass. > > > > For example when adding something to a pointer: > > > > _2 = _1 + k > > > > Where _1 & _2 are the old point types I'll > > emit > > > > new_3 = (type_convert)_1 > > new_4 = (type_convert)k > > new_5 = new_4 / struct_size // truncating divide > > new_6 = new_3 + new_5 > > _2 = (type_convert)_new_6 > > > > Note, the casting is done with CONVERT_EXPR > > which is harmless when I create new ssa names > > and set the appropriate operands in > > OK, so you're funneling the new "index" values through > the original pointer variable _1? But then I don't see > where the patching up of SSA names and the default > def issue happens. > > > new_3 = (type_convert)_1 > > _2 = (type_convert)new_6 > > > > to > > > > new_3 = new_7 > > new_8 = new_6 > > > > Now I might actually find via a look up that > > _1 and/or _2 were already mapped to > > new_7 and/or new_8 but that's irrelevant. > > > > To intermix the applications of the transformations and > > the patching of these dangling types seems like I'd > > need to do an insanely ugly recursive walk of each functions > > body. > > > > I'm curious when you mention def-use I'm not aware of > > GCC using def-use chains except at the RTL level. > > Is there a def-use mechanism in GIMPLE because > > in SSA form it's trivial to find the definition of > > a temp variable but non trivial to find the use of > > it. Which I think is a valid reason for fixing up the > > dangling types of temps in a scan. > > In GIMPLE SSA we maintain a list of uses for each SSA > def, available via the so called immediate-uses. You > can grep for uses of FOR_EACH_IMM_USE[_FAST] > > > > > Note, I'll maintain a mapping like you suggest but not use > > it at transformation application time. Furthermore, > > I'll initialize the mapping with the default defs from > > the DECLs so I won't have to mess with them on the fly. > > Now at the time in the scan when I find uses and defs of > > a dangling type I'd like to simply modify the a