On Mon, Mar 28, 2011 at 09:58:38AM -0700, Richard Henderson wrote: > > * var-tracking.c (vt_add_function_parameter): Ensure cselib_lookup > > on ENTRY_VALUE is able to find the canonical parameter VALUE. > > I don't really understand what's going on here. Whatever it is, it > could definitely use some more commentary; there's almost nothing in > the surrounding context. I also suggest pulling some of this out into > a new function. You've got 2 exact copies here in the patch, and 2 > more that are nearly the same already in the code.
As cfgexpand.c creates ENTRY_VALUEs (where the first hunk of this patch applies), when vt_initialization uses cselib to lookup those ENTRY_VALUEs, without the patch it will find a newly created cselib_val whose only location is the ENTRY_VALUE. Which means it will always use DW_OP_GNU_entry_value in the end. Sometimes that is the only usable choice, but e.g. the first function in gcc.dg/pr48203.c shows we can do better, because all the entry values are also held in the corresponding registers (the function doesn't clobber them), so we can instead of DW_OP_GNU_entry_value just refer to the registers itself, either in the whole function, or at least as long as the aren't clobbered by something else. The extra cselib_lookup calls give us those values that hash as those ENTRY_VALUE will hash and by telling that the value is live in the parameter's VALUE vt_expand_loc_callback will find it. Say vt_add_function_parameter is called for first parameter in %rdi, cselib_lookup_from_insn gives us VALUE 2:2 for it. We add (entry_value:DI (reg:DI %rdi)) to list of locations for that VALUE. The second cselib_lookup_from_insn gives us VALUE 3:217, which will have locations (value:DI 2:2) (the one we've injected there) and (entry_value:DI (reg:DI %rdi)). Then when (entry_value:DI (reg:DI %rdi)) appears in some DEBUG_INSNs, it will give (value:DI 3:217) and vt_expand_loc_callback will use the first location for it (i.e. (value:DI 2:2) ) and either it will see the value is still live in %rdi, some other register or memory, or, if nowhere else, in (entry_value:DI (reg:DI %rdi)). The 3 cselib.c changes from this patch ensure that the hash value for (entry_value:DI (reg:DI %rdi)) will always be the same and (value:DI 3:217) will never be flushed from the hash table, even when e.g. on next bb's boundary we flush all registers from the hash table, or e.g. when movl $123, %edi is seen in the insns. I could of course create another hash table and map ENTRY_VALUEs through that hash table back to the parameter VALUEs, but cselib already has a hash table which we can use and furthermore the ENTRY_VALUEs could be embedded in other RTLs. I will look into creating helper inlines to reduce code duplication. > > * cselib.c (rtx_equal_for_cselib_1) <case ENTRY_VALUE>: Use > > rtx_equal_p instead of rtx_equal_for_cselib_1 to compare > > ENTRY_VALUE_EXPs. > > Ok. > > > (cselib_hash_rtx) <case ENTRY_VALUE>: If ENTRY_VALUE_EXP > > is a REG_P or MEM_P with REG_P address, compute hash directly > > instead of calling cselib_hash_rtx on ENTRY_VALUE_EXP. > > Why? Because REG and MEM hash based on their current value in cselib: case MEM: case REG: e = cselib_lookup (x, GET_MODE (x), create, memmode); if (! e) return 0; return e->hash; In ENTRY_VALUEs which are function invariant I want it to hash always the same. > > (preserve_only_constants): Don't clear VALUES forwaring > > ENTRY_VALUE to some other VALUE. > > Ok with a comment. I guess the reasoning being that even though this > value isn't "constant", it's function invariant? Yeah. Perhaps preserve_only_constants could be renamed to preserve_only_function_invariants or similar (and likewise for cselib_preserve_constants and CSELIB_PRESERVE_CONSTANTS). Jakub