re PR debug/53671 (Many guality test failures)

PR debug/53671
PR debug/49888
* var-tracking.c (vt_get_canonicalize_base): New.
(vt_canonicalize_addr, vt_stack_offset_p): New.
(vt_canon_true_dep): New.
(drop_overlapping_mem_locs): Use vt_canon_true_dep.
(clobber_overlaping_mems): Use vt_canonicalize_addr.

From-SVN: r188871
This commit is contained in:
Alexandre Oliva 2012-06-22 01:34:05 +00:00 committed by Alexandre Oliva
parent 48b00503b1
commit 61806a93f3
2 changed files with 151 additions and 7 deletions

View File

@ -1,3 +1,13 @@
2012-06-21 Alexandre Oliva <aoliva@redhat.com>
PR debug/53671
PR debug/49888
* var-tracking.c (vt_get_canonicalize_base): New.
(vt_canonicalize_addr, vt_stack_offset_p): New.
(vt_canon_true_dep): New.
(drop_overlapping_mem_locs): Use vt_canon_true_dep.
(clobber_overlaping_mems): Use vt_canonicalize_addr.
2012-06-21 Alexandre Oliva <aoliva@redhat.com>
PR debug/53671

View File

@ -1955,6 +1955,144 @@ var_regno_delete (dataflow_set *set, int regno)
*reg = NULL;
}
/* Strip constant offsets and alignments off of LOC. Return the base
expression. */
static rtx
vt_get_canonicalize_base (rtx loc)
{
while ((GET_CODE (loc) == PLUS
|| GET_CODE (loc) == AND)
&& GET_CODE (XEXP (loc, 1)) == CONST_INT
&& (GET_CODE (loc) != AND
|| INTVAL (XEXP (loc, 1)) < 0))
loc = XEXP (loc, 0);
return loc;
}
/* Canonicalize LOC using equivalences from SET in addition to those
in the cselib static table. */
static rtx
vt_canonicalize_addr (dataflow_set *set, rtx oloc)
{
HOST_WIDE_INT ofst = 0;
enum machine_mode mode = GET_MODE (oloc);
rtx loc = canon_rtx (get_addr (oloc));
/* Try to substitute a base VALUE for equivalent expressions as much
as possible. The goal here is to expand stack-related addresses
to one of the stack base registers, so that we can compare
addresses for overlaps. */
while (GET_CODE (vt_get_canonicalize_base (loc)) == VALUE)
{
rtx x;
decl_or_value dv;
variable var;
location_chain l;
while (GET_CODE (loc) == PLUS)
{
ofst += INTVAL (XEXP (loc, 1));
loc = XEXP (loc, 0);
continue;
}
/* Alignment operations can't normally be combined, so just
canonicalize the base and we're done. We'll normally have
only one stack alignment anyway. */
if (GET_CODE (loc) == AND)
{
x = vt_canonicalize_addr (set, XEXP (loc, 0));
if (x != XEXP (loc, 0))
loc = gen_rtx_AND (mode, x, XEXP (loc, 1));
loc = canon_rtx (get_addr (loc));
break;
}
x = canon_rtx (get_addr (loc));
/* We've made progress! Start over. */
if (x != loc || GET_CODE (x) != VALUE)
{
loc = x;
continue;
}
dv = dv_from_rtx (x);
var = (variable) htab_find_with_hash (shared_hash_htab (set->vars),
dv, dv_htab_hash (dv));
if (!var)
break;
/* Look for an improved equivalent expression. */
for (l = var->var_part[0].loc_chain; l; l = l->next)
{
rtx base = vt_get_canonicalize_base (l->loc);
if (GET_CODE (base) == REG
|| (GET_CODE (base) == VALUE
&& canon_value_cmp (base, loc)))
{
loc = l->loc;
break;
}
}
/* No luck with the dataflow set, so we're done. */
if (!l)
break;
}
/* Add OFST back in. */
if (ofst)
{
/* Don't build new RTL if we can help it. */
if (GET_CODE (oloc) == PLUS
&& XEXP (oloc, 0) == loc
&& INTVAL (XEXP (oloc, 1)) == ofst)
return oloc;
loc = plus_constant (mode, loc, ofst);
}
return loc;
}
/* Return true iff ADDR has a stack register as the base address. */
static inline bool
vt_stack_offset_p (rtx addr)
{
rtx base = vt_get_canonicalize_base (addr);
if (GET_CODE (base) != REG)
return false;
return REGNO_PTR_FRAME_P (REGNO (base));
}
/* Return true iff there's a true dependence between MLOC and LOC.
MADDR must be a canonicalized version of MLOC's address. */
static inline bool
vt_canon_true_dep (dataflow_set *set, rtx mloc, rtx maddr, rtx loc)
{
if (GET_CODE (loc) != MEM)
return false;
if (!canon_true_dependence (mloc, GET_MODE (mloc), maddr, loc, NULL))
return false;
if (!MEM_EXPR (loc) && vt_stack_offset_p (maddr))
{
rtx addr = vt_canonicalize_addr (set, XEXP (loc, 0));
return canon_true_dependence (mloc, GET_MODE (mloc), maddr, loc, addr);
}
return true;
}
/* Hold parameters for the hashtab traversal function
drop_overlapping_mem_locs, see below. */
@ -1988,9 +2126,7 @@ drop_overlapping_mem_locs (void **slot, void *data)
if (shared_var_p (var, set->vars))
{
for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
if (GET_CODE (loc->loc) == MEM
&& canon_true_dependence (mloc, GET_MODE (mloc), addr,
loc->loc, NULL))
if (vt_canon_true_dep (set, mloc, addr, loc->loc))
break;
if (!loc)
@ -2009,9 +2145,7 @@ drop_overlapping_mem_locs (void **slot, void *data)
for (locp = &var->var_part[0].loc_chain, loc = *locp;
loc; loc = *locp)
{
if (GET_CODE (loc->loc) != MEM
|| !canon_true_dependence (mloc, GET_MODE (mloc), addr,
loc->loc, NULL))
if (!vt_canon_true_dep (set, mloc, addr, loc->loc))
{
locp = &loc->next;
continue;
@ -2052,7 +2186,7 @@ clobber_overlapping_mems (dataflow_set *set, rtx loc)
coms.set = set;
coms.loc = canon_rtx (loc);
coms.addr = canon_rtx (get_addr (XEXP (loc, 0)));
coms.addr = vt_canonicalize_addr (set, XEXP (loc, 0));
set->traversed_vars = set->vars;
htab_traverse (shared_hash_htab (set->vars),