diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-03-29 01:53:46 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-03-29 01:53:46 +0200 |
commit | 2b80199f41d444c88474b32792a7e828f2a96b68 (patch) | |
tree | 7d5601e9e49e4f8fa5cf78fc46ce899d76d94f4f /gcc | |
parent | b9da60aea69647fd7957dc328a8431412157d3a7 (diff) | |
download | gcc-2b80199f41d444c88474b32792a7e828f2a96b68.zip gcc-2b80199f41d444c88474b32792a7e828f2a96b68.tar.gz gcc-2b80199f41d444c88474b32792a7e828f2a96b68.tar.bz2 |
re PR debug/48203 (ICE in dwarf2out.c while building eglibc.)
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.
From-SVN: r171640
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 6 | ||||
-rw-r--r-- | gcc/cselib.c | 33 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr48203.c | 51 | ||||
-rw-r--r-- | gcc/var-tracking.c | 37 |
7 files changed, 145 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eae6519..f3ee4b5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2011-03-29 Jakub Jelinek <jakub@redhat.com> + + 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. + 2011-03-28 Richard Sandiford <richard.sandiford@linaro.org> * builtins.c (expand_builtin_memset_args): Use gen_int_mode diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index da40aae..e075c53 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -3172,8 +3172,10 @@ expand_debug_expr (tree exp) rtx incoming = DECL_INCOMING_RTL (SSA_NAME_VAR (exp)); if (incoming && GET_MODE (incoming) != BLKmode - && (REG_P (incoming) - || (MEM_P (incoming) && REG_P (XEXP (incoming, 0))))) + && ((REG_P (incoming) && HARD_REGISTER_P (incoming)) + || (MEM_P (incoming) + && REG_P (XEXP (incoming, 0)) + && HARD_REGISTER_P (XEXP (incoming, 0))))) { op0 = gen_rtx_ENTRY_VALUE (GET_MODE (incoming)); ENTRY_VALUE_EXP (op0) = incoming; diff --git a/gcc/cselib.c b/gcc/cselib.c index f9e13ff..dff0967 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: diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 77d533e..182a894 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -13891,7 +13891,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, dw_loc_descr_ref ref = mem_loc_descriptor (ENTRY_VALUE_EXP (rtl), GET_MODE (rtl), VAR_INIT_STATUS_INITIALIZED); - if (ref == NULL) + if (ref == NULL || ref->dw_loc_opc == DW_OP_fbreg) return NULL; mem_loc_result->dw_loc_oprnd1.v.val_loc = ref; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dec92ef..513805d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-03-29 Jakub Jelinek <jakub@redhat.com> + + PR debug/48203 + * gcc.dg/pr48203.c: New test. + 2011-03-28 Jeff Law <law@redhat.com> * gcc.dg/tree-ssa/ssa-dom-thread-3.c: New test. diff --git a/gcc/testsuite/gcc.dg/pr48203.c b/gcc/testsuite/gcc.dg/pr48203.c new file mode 100644 index 0000000..b4b2b08 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr48203.c @@ -0,0 +1,51 @@ +/* PR debug/48203 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g" } */ + +volatile int v; + +void +foo (long a, long b, long c, long d, long e, long f, long g, long h, + long i, long j, long k, long l, long m, long n, long o, long p) +{ + long a2 = a; + long b2 = b; + long c2 = c; + long d2 = d; + long e2 = e; + long f2 = f; + long g2 = g; + long h2 = h; + long i2 = i; + long j2 = j; + long k2 = k; + long l2 = l; + long m2 = m; + long n2 = n; + long o2 = o; + long p2 = p; + v++; +} + +void +bar (int a, int b, int c, int d, int e, int f, int g, int h, + int i, int j, int k, int l, int m, int n, int o, int p) +{ + int a2 = a; + int b2 = b; + int c2 = c; + int d2 = d; + int e2 = e; + int f2 = f; + int g2 = g; + int h2 = h; + int i2 = i; + int j2 = j; + int k2 = k; + int l2 = l; + int m2 = m; + int n2 = n; + int o2 = o; + int p2 = p; + v++; +} diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index ef02937..9729956 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -8472,7 +8472,7 @@ vt_add_function_parameter (tree parm) VAR_INIT_STATUS_INITIALIZED, NULL, INSERT); if (dv_is_value_p (dv)) { - cselib_val *val = CSELIB_VAL_PTR (dv_as_value (dv)); + cselib_val *val = CSELIB_VAL_PTR (dv_as_value (dv)), *val2; struct elt_loc_list *el; el = (struct elt_loc_list *) ggc_alloc_cleared_atomic (sizeof (*el)); @@ -8481,6 +8481,23 @@ vt_add_function_parameter (tree parm) ENTRY_VALUE_EXP (el->loc) = incoming; el->setting_insn = get_insns (); val->locs = el; + val2 = cselib_lookup_from_insn (el->loc, GET_MODE (incoming), + true, VOIDmode, get_insns ()); + if (val2 + && val2 != val + && val2->locs + && rtx_equal_p (val2->locs->loc, el->loc)) + { + struct elt_loc_list *el2; + + preserve_value (val2); + el2 = (struct elt_loc_list *) + ggc_alloc_cleared_atomic (sizeof (*el2)); + el2->next = val2->locs; + el2->loc = dv_as_value (dv); + el2->setting_insn = get_insns (); + val2->locs = el2; + } if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (parm)))) { @@ -8499,6 +8516,24 @@ vt_add_function_parameter (tree parm) ENTRY_VALUE_EXP (el->loc) = mem; el->setting_insn = get_insns (); val->locs = el; + val2 = cselib_lookup_from_insn (el->loc, GET_MODE (mem), + true, VOIDmode, + get_insns ()); + if (val2 + && val2 != val + && val2->locs + && rtx_equal_p (val2->locs->loc, el->loc)) + { + struct elt_loc_list *el2; + + preserve_value (val2); + el2 = (struct elt_loc_list *) + ggc_alloc_cleared_atomic (sizeof (*el2)); + el2->next = val2->locs; + el2->loc = val->val_rtx; + el2->setting_insn = get_insns (); + val2->locs = el2; + } } } } |