diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-28 23:53:46 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-28 23:53:46 +0000 |
commit | 06eb3ccd8a660aa8d0f6b113841813bbe867f84a (patch) | |
tree | 7d5601e9e49e4f8fa5cf78fc46ce899d76d94f4f /gcc/cselib.c | |
parent | 5150021e40056804a9215058c054b90cd7b92626 (diff) | |
download | gcc-06eb3ccd8a660aa8d0f6b113841813bbe867f84a.tar.gz |
PR debug/48203
* cfgexpand.c (expand_debug_expr) <case SSA_NAME>: Only
create ENTRY_VALUE if incoming or address of incoming's MEM
is a hard REG.
* dwarf2out.c (mem_loc_descriptor): Don't emit
DW_OP_GNU_entry_value of DW_OP_fbreg.
* var-tracking.c (vt_add_function_parameter): Ensure cselib_lookup
on ENTRY_VALUE is able to find the canonical parameter VALUE.
* 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.
(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.
(preserve_only_constants): Don't clear VALUES forwaring
ENTRY_VALUE to some other VALUE.
* gcc.dg/pr48203.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171640 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cselib.c')
-rw-r--r-- | gcc/cselib.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/gcc/cselib.c b/gcc/cselib.c index f9e13ffffef..dff096752f5 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -305,7 +305,8 @@ cselib_clear_table (void) cselib_reset_table (1); } -/* Remove from hash table all VALUEs except constants. */ +/* Remove from hash table all VALUEs except constants + and function invariants. */ static int preserve_only_constants (void **x, void *info ATTRIBUTE_UNUSED) @@ -329,6 +330,14 @@ preserve_only_constants (void **x, void *info ATTRIBUTE_UNUSED) return 1; } } + /* Keep around VALUEs that forward function invariant ENTRY_VALUEs + to corresponding parameter VALUEs. */ + if (v->locs != NULL + && v->locs->next != NULL + && v->locs->next->next == NULL + && GET_CODE (v->locs->next->loc) == ENTRY_VALUE + && GET_CODE (v->locs->loc) == VALUE) + return 1; htab_clear_slot (cselib_hash_table, x); return 1; @@ -804,8 +813,9 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, enum machine_mode memmode) == DEBUG_IMPLICIT_PTR_DECL (y); case ENTRY_VALUE: - return rtx_equal_for_cselib_1 (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y), - memmode); + /* ENTRY_VALUEs are function invariant, it is thus undesirable to + use rtx_equal_for_cselib_1 to compare the operands. */ + return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y)); case LABEL_REF: return XEXP (x, 0) == XEXP (y, 0); @@ -954,7 +964,22 @@ cselib_hash_rtx (rtx x, int create, enum machine_mode memmode) return hash ? hash : (unsigned int) DEBUG_IMPLICIT_PTR; case ENTRY_VALUE: - hash += cselib_hash_rtx (ENTRY_VALUE_EXP (x), create, memmode); + /* ENTRY_VALUEs are function invariant, thus try to avoid + recursing on argument if ENTRY_VALUE is one of the + forms emitted by expand_debug_expr, otherwise + ENTRY_VALUE hash would depend on the current value + in some register or memory. */ + if (REG_P (ENTRY_VALUE_EXP (x))) + hash += (unsigned int) REG + + (unsigned int) GET_MODE (ENTRY_VALUE_EXP (x)) + + (unsigned int) REGNO (ENTRY_VALUE_EXP (x)); + else if (MEM_P (ENTRY_VALUE_EXP (x)) + && REG_P (XEXP (ENTRY_VALUE_EXP (x), 0))) + hash += (unsigned int) MEM + + (unsigned int) GET_MODE (XEXP (ENTRY_VALUE_EXP (x), 0)) + + (unsigned int) REGNO (XEXP (ENTRY_VALUE_EXP (x), 0)); + else + hash += cselib_hash_rtx (ENTRY_VALUE_EXP (x), create, memmode); return hash ? hash : (unsigned int) ENTRY_VALUE; case CONST_INT: |