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
This commit is contained in:
parent
b9da60aea6
commit
2b80199f41
7 changed files with 145 additions and 8 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
33
gcc/cselib.c
33
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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
51
gcc/testsuite/gcc.dg/pr48203.c
Normal file
51
gcc/testsuite/gcc.dg/pr48203.c
Normal file
|
@ -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++;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue