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:
Jakub Jelinek 2011-03-29 01:53:46 +02:00 committed by Jakub Jelinek
parent b9da60aea6
commit 2b80199f41
7 changed files with 145 additions and 8 deletions

View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -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;
}

View File

@ -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.

View 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++;
}

View File

@ -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;
}
}
}
}