alias.c (alias_invariant, [...]): Mark GTY.

* alias.c (alias_invariant, alias_invariant_size): Mark GTY.
        (reg_known_value, reg_known_value_size): Likewise; make static.
        (reg_known_equiv_p): Make static.
        (clear_reg_alias_info): Update for new indexing.
        (get_reg_known_value, set_reg_known_value): New.
        (get_reg_known_equiv_p, set_reg_known_equiv_p): New.
        (canon_rtx): Use them.
        (init_alias_analysis): Likewise.  Allocate reg_known_value with gc.
        Don't play queer offsetting games with reg_known_value and
        reg_known_equiv_p.
        (end_alias_analysis): Free reg_known_value with gc.
        * rtl.h (get_reg_known_value, get_reg_known_equiv_p): Declare.
        * sched-deps.c (reg_known_equiv_p, reg_known_value): Remove.
        (deps_may_trap_p, sched_analyze_1, sched_analyze_2): Use the new
        functions instead.

From-SVN: r79945
This commit is contained in:
Richard Henderson 2004-03-24 16:58:57 -08:00 committed by Richard Henderson
parent bbcb76f264
commit bb1acb3e8f
4 changed files with 136 additions and 53 deletions

View File

@ -1,3 +1,21 @@
2004-03-24 Richard Henderson <rth@redhat.com>
* alias.c (alias_invariant, alias_invariant_size): Mark GTY.
(reg_known_value, reg_known_value_size): Likewise; make static.
(reg_known_equiv_p): Make static.
(clear_reg_alias_info): Update for new indexing.
(get_reg_known_value, set_reg_known_value): New.
(get_reg_known_equiv_p, set_reg_known_equiv_p): New.
(canon_rtx): Use them.
(init_alias_analysis): Likewise. Allocate reg_known_value with gc.
Don't play queer offsetting games with reg_known_value and
reg_known_equiv_p.
(end_alias_analysis): Free reg_known_value with gc.
* rtl.h (get_reg_known_value, get_reg_known_equiv_p): Declare.
* sched-deps.c (reg_known_equiv_p, reg_known_value): Remove.
(deps_may_trap_p, sched_analyze_1, sched_analyze_2): Use the new
functions instead.
2004-03-24 Kazu Hirata <kazu@cs.umass.edu>
* dwarf2asm.c, loop.h, pretty-print.c, pretty-print.h,

View File

@ -181,17 +181,16 @@ static GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER];
Because this array contains only pseudo registers it has no effect
after reload. */
static rtx *alias_invariant;
unsigned int alias_invariant_size;
static GTY((length("alias_invariant_size"))) rtx *alias_invariant;
unsigned GTY(()) int alias_invariant_size;
/* Vector indexed by N giving the initial (unchanging) value known for
pseudo-register N. This array is initialized in
init_alias_analysis, and does not change until end_alias_analysis
is called. */
rtx *reg_known_value;
pseudo-register N. This array is initialized in init_alias_analysis,
and does not change until end_alias_analysis is called. */
static GTY((length("reg_known_value_size"))) rtx *reg_known_value;
/* Indicates number of valid entries in reg_known_value. */
static unsigned int reg_known_value_size;
static GTY(()) unsigned int reg_known_value_size;
/* Vector recording for each reg_known_value whether it is due to a
REG_EQUIV note. Future passes (viz., reload) may replace the
@ -205,7 +204,7 @@ static unsigned int reg_known_value_size;
REG_EQUIV notes. One could argue that the REG_EQUIV notes are
wrong, but solving the problem in the scheduler will likely give
better code, so we do it here. */
char *reg_known_equiv_p;
static bool *reg_known_equiv_p;
/* True when scanning insns from the start of the rtl to the
NOTE_INSN_FUNCTION_BEG note. */
@ -1075,10 +1074,70 @@ clear_reg_alias_info (rtx reg)
{
unsigned int regno = REGNO (reg);
if (regno < reg_known_value_size && regno >= FIRST_PSEUDO_REGISTER)
reg_known_value[regno] = reg;
if (regno >= FIRST_PSEUDO_REGISTER)
{
regno -= FIRST_PSEUDO_REGISTER;
if (regno < reg_known_value_size)
{
reg_known_value[regno] = reg;
reg_known_equiv_p[regno] = false;
}
}
}
/* If a value is known for REGNO, return it. */
rtx
get_reg_known_value (unsigned int regno)
{
if (regno >= FIRST_PSEUDO_REGISTER)
{
regno -= FIRST_PSEUDO_REGISTER;
if (regno < reg_known_value_size)
return reg_known_value[regno];
}
return NULL;
}
/* Set it. */
static void
set_reg_known_value (unsigned int regno, rtx val)
{
if (regno >= FIRST_PSEUDO_REGISTER)
{
regno -= FIRST_PSEUDO_REGISTER;
if (regno < reg_known_value_size)
reg_known_value[regno] = val;
}
}
/* Similarly for reg_known_equiv_p. */
bool
get_reg_known_equiv_p (unsigned int regno)
{
if (regno >= FIRST_PSEUDO_REGISTER)
{
regno -= FIRST_PSEUDO_REGISTER;
if (regno < reg_known_value_size)
return reg_known_equiv_p[regno];
}
return false;
}
static void
set_reg_known_equiv_p (unsigned int regno, bool val)
{
if (regno >= FIRST_PSEUDO_REGISTER)
{
regno -= FIRST_PSEUDO_REGISTER;
if (regno < reg_known_value_size)
reg_known_equiv_p[regno] = val;
}
}
/* Returns a canonical version of X, from the point of view alias
analysis. (For example, if X is a MEM whose address is a register,
and the register has a known value (say a SYMBOL_REF), then a MEM
@ -1088,11 +1147,16 @@ rtx
canon_rtx (rtx x)
{
/* Recursively look for equivalences. */
if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
&& REGNO (x) < reg_known_value_size)
return reg_known_value[REGNO (x)] == x
? x : canon_rtx (reg_known_value[REGNO (x)]);
else if (GET_CODE (x) == PLUS)
if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
{
rtx t = get_reg_known_value (REGNO (x));
if (t == x)
return x;
if (t)
return canon_rtx (t);
}
if (GET_CODE (x) == PLUS)
{
rtx x0 = canon_rtx (XEXP (x, 0));
rtx x1 = canon_rtx (XEXP (x, 1));
@ -2736,14 +2800,9 @@ init_alias_analysis (void)
timevar_push (TV_ALIAS_ANALYSIS);
reg_known_value_size = maxreg;
reg_known_value
= (rtx *) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (rtx))
- FIRST_PSEUDO_REGISTER;
reg_known_equiv_p
= (char*) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (char))
- FIRST_PSEUDO_REGISTER;
reg_known_value_size = maxreg - FIRST_PSEUDO_REGISTER;
reg_known_value = ggc_calloc (reg_known_value_size, sizeof (rtx));
reg_known_equiv_p = xcalloc (reg_known_value_size, sizeof (bool));
/* Overallocate reg_base_value to allow some growth during loop
optimization. Loop unrolling can create a large number of
@ -2861,6 +2920,7 @@ init_alias_analysis (void)
{
unsigned int regno = REGNO (SET_DEST (set));
rtx src = SET_SRC (set);
rtx t;
if (REG_NOTES (insn) != 0
&& (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
@ -2868,29 +2928,28 @@ init_alias_analysis (void)
|| (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
&& GET_CODE (XEXP (note, 0)) != EXPR_LIST
&& ! rtx_varies_p (XEXP (note, 0), 1)
&& ! reg_overlap_mentioned_p (SET_DEST (set), XEXP (note, 0)))
&& ! reg_overlap_mentioned_p (SET_DEST (set),
XEXP (note, 0)))
{
reg_known_value[regno] = XEXP (note, 0);
reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV;
set_reg_known_value (regno, XEXP (note, 0));
set_reg_known_equiv_p (regno,
REG_NOTE_KIND (note) == REG_EQUIV);
}
else if (REG_N_SETS (regno) == 1
&& GET_CODE (src) == PLUS
&& GET_CODE (XEXP (src, 0)) == REG
&& REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER
&& (reg_known_value[REGNO (XEXP (src, 0))])
&& (t = get_reg_known_value (REGNO (XEXP (src, 0))))
&& GET_CODE (XEXP (src, 1)) == CONST_INT)
{
rtx op0 = XEXP (src, 0);
op0 = reg_known_value[REGNO (op0)];
reg_known_value[regno]
= plus_constant (op0, INTVAL (XEXP (src, 1)));
reg_known_equiv_p[regno] = 0;
t = plus_constant (t, INTVAL (XEXP (src, 1)));
set_reg_known_value (regno, t);
set_reg_known_equiv_p (regno, 0);
}
else if (REG_N_SETS (regno) == 1
&& ! rtx_varies_p (src, 1))
{
reg_known_value[regno] = src;
reg_known_equiv_p[regno] = 0;
set_reg_known_value (regno, src);
set_reg_known_equiv_p (regno, 0);
}
}
}
@ -2917,9 +2976,9 @@ init_alias_analysis (void)
while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);
/* Fill in the remaining entries. */
for (i = FIRST_PSEUDO_REGISTER; i < (int)maxreg; i++)
for (i = 0; i < (int)reg_known_value_size; i++)
if (reg_known_value[i] == 0)
reg_known_value[i] = regno_reg_rtx[i];
reg_known_value[i] = regno_reg_rtx[i + FIRST_PSEUDO_REGISTER];
/* Simplify the reg_base_value array so that no register refers to
another register, except to special registers indirectly through
@ -2965,10 +3024,10 @@ void
end_alias_analysis (void)
{
old_reg_base_value = reg_base_value;
free (reg_known_value + FIRST_PSEUDO_REGISTER);
ggc_free (reg_known_value);
reg_known_value = 0;
reg_known_value_size = 0;
free (reg_known_equiv_p + FIRST_PSEUDO_REGISTER);
free (reg_known_equiv_p);
reg_known_equiv_p = 0;
if (alias_invariant)
{

View File

@ -2423,6 +2423,8 @@ extern rtx addr_side_effect_eval (rtx, int, int);
extern bool memory_modified_in_insn_p (rtx, rtx);
extern rtx find_base_term (rtx);
extern rtx gen_hard_reg_clobber (enum machine_mode, unsigned int);
extern rtx get_reg_known_value (unsigned int);
extern bool get_reg_known_equiv_p (unsigned int);
/* In sibcall.c */
typedef enum {

View File

@ -44,8 +44,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "cselib.h"
#include "df.h"
extern char *reg_known_equiv_p;
extern rtx *reg_known_value;
static regset_head reg_pending_sets_head;
static regset_head reg_pending_clobbers_head;
@ -113,10 +111,12 @@ deps_may_trap_p (rtx mem)
{
rtx addr = XEXP (mem, 0);
if (REG_P (addr)
&& REGNO (addr) >= FIRST_PSEUDO_REGISTER
&& reg_known_value[REGNO (addr)])
addr = reg_known_value[REGNO (addr)];
if (REG_P (addr) && REGNO (addr) >= FIRST_PSEUDO_REGISTER)
{
rtx t = get_reg_known_value (REGNO (addr));
if (t)
addr = t;
}
return rtx_addr_can_trap_p (addr);
}
@ -523,10 +523,12 @@ sched_analyze_1 (struct deps *deps, rtx x, rtx insn)
/* Pseudos that are REG_EQUIV to something may be replaced
by that during reloading. We need only add dependencies for
the address in the REG_EQUIV note. */
if (!reload_completed
&& reg_known_equiv_p[regno]
&& GET_CODE (reg_known_value[regno]) == MEM)
sched_analyze_2 (deps, XEXP (reg_known_value[regno], 0), insn);
if (!reload_completed && get_reg_known_equiv_p (regno))
{
rtx t = get_reg_known_value (regno);
if (GET_CODE (t) == MEM)
sched_analyze_2 (deps, XEXP (t, 0), insn);
}
/* Don't let it cross a call after scheduling if it doesn't
already cross one. */
@ -659,10 +661,12 @@ sched_analyze_2 (struct deps *deps, rtx x, rtx insn)
/* Pseudos that are REG_EQUIV to something may be replaced
by that during reloading. We need only add dependencies for
the address in the REG_EQUIV note. */
if (!reload_completed
&& reg_known_equiv_p[regno]
&& GET_CODE (reg_known_value[regno]) == MEM)
sched_analyze_2 (deps, XEXP (reg_known_value[regno], 0), insn);
if (!reload_completed && get_reg_known_equiv_p (regno))
{
rtx t = get_reg_known_value (regno);
if (GET_CODE (t) == MEM)
sched_analyze_2 (deps, XEXP (t, 0), insn);
}
/* If the register does not already cross any calls, then add this
insn to the sched_before_next_call list so that it will still