Commit 2b80199f by Jakub Jelinek Committed by Jakub Jelinek

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
parent b9da60ae
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;
......
......@@ -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;
}
......
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.
......
/* 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;
}
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment