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> 2004-03-24 Kazu Hirata <kazu@cs.umass.edu>
* dwarf2asm.c, loop.h, pretty-print.c, pretty-print.h, * 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 Because this array contains only pseudo registers it has no effect
after reload. */ after reload. */
static rtx *alias_invariant; static GTY((length("alias_invariant_size"))) rtx *alias_invariant;
unsigned int alias_invariant_size; unsigned GTY(()) int alias_invariant_size;
/* Vector indexed by N giving the initial (unchanging) value known for /* Vector indexed by N giving the initial (unchanging) value known for
pseudo-register N. This array is initialized in pseudo-register N. This array is initialized in init_alias_analysis,
init_alias_analysis, and does not change until end_alias_analysis and does not change until end_alias_analysis is called. */
is called. */ static GTY((length("reg_known_value_size"))) rtx *reg_known_value;
rtx *reg_known_value;
/* Indicates number of valid entries in 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 /* Vector recording for each reg_known_value whether it is due to a
REG_EQUIV note. Future passes (viz., reload) may replace the 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 REG_EQUIV notes. One could argue that the REG_EQUIV notes are
wrong, but solving the problem in the scheduler will likely give wrong, but solving the problem in the scheduler will likely give
better code, so we do it here. */ 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 /* True when scanning insns from the start of the rtl to the
NOTE_INSN_FUNCTION_BEG note. */ NOTE_INSN_FUNCTION_BEG note. */
@ -1075,10 +1074,70 @@ clear_reg_alias_info (rtx reg)
{ {
unsigned int regno = REGNO (reg); unsigned int regno = REGNO (reg);
if (regno < reg_known_value_size && regno >= FIRST_PSEUDO_REGISTER) if (regno >= FIRST_PSEUDO_REGISTER)
reg_known_value[regno] = reg; {
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 /* 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, 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 and the register has a known value (say a SYMBOL_REF), then a MEM
@ -1088,11 +1147,16 @@ rtx
canon_rtx (rtx x) canon_rtx (rtx x)
{ {
/* Recursively look for equivalences. */ /* Recursively look for equivalences. */
if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
&& REGNO (x) < reg_known_value_size) {
return reg_known_value[REGNO (x)] == x rtx t = get_reg_known_value (REGNO (x));
? x : canon_rtx (reg_known_value[REGNO (x)]); if (t == x)
else if (GET_CODE (x) == PLUS) return x;
if (t)
return canon_rtx (t);
}
if (GET_CODE (x) == PLUS)
{ {
rtx x0 = canon_rtx (XEXP (x, 0)); rtx x0 = canon_rtx (XEXP (x, 0));
rtx x1 = canon_rtx (XEXP (x, 1)); rtx x1 = canon_rtx (XEXP (x, 1));
@ -2736,14 +2800,9 @@ init_alias_analysis (void)
timevar_push (TV_ALIAS_ANALYSIS); timevar_push (TV_ALIAS_ANALYSIS);
reg_known_value_size = maxreg; reg_known_value_size = maxreg - FIRST_PSEUDO_REGISTER;
reg_known_value = ggc_calloc (reg_known_value_size, sizeof (rtx));
reg_known_value reg_known_equiv_p = xcalloc (reg_known_value_size, sizeof (bool));
= (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;
/* Overallocate reg_base_value to allow some growth during loop /* Overallocate reg_base_value to allow some growth during loop
optimization. Loop unrolling can create a large number of optimization. Loop unrolling can create a large number of
@ -2861,6 +2920,7 @@ init_alias_analysis (void)
{ {
unsigned int regno = REGNO (SET_DEST (set)); unsigned int regno = REGNO (SET_DEST (set));
rtx src = SET_SRC (set); rtx src = SET_SRC (set);
rtx t;
if (REG_NOTES (insn) != 0 if (REG_NOTES (insn) != 0
&& (((note = find_reg_note (insn, REG_EQUAL, 0)) != 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) || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
&& GET_CODE (XEXP (note, 0)) != EXPR_LIST && GET_CODE (XEXP (note, 0)) != EXPR_LIST
&& ! rtx_varies_p (XEXP (note, 0), 1) && ! 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); set_reg_known_value (regno, XEXP (note, 0));
reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV; set_reg_known_equiv_p (regno,
REG_NOTE_KIND (note) == REG_EQUIV);
} }
else if (REG_N_SETS (regno) == 1 else if (REG_N_SETS (regno) == 1
&& GET_CODE (src) == PLUS && GET_CODE (src) == PLUS
&& GET_CODE (XEXP (src, 0)) == REG && GET_CODE (XEXP (src, 0)) == REG
&& REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER && (t = get_reg_known_value (REGNO (XEXP (src, 0))))
&& (reg_known_value[REGNO (XEXP (src, 0))])
&& GET_CODE (XEXP (src, 1)) == CONST_INT) && GET_CODE (XEXP (src, 1)) == CONST_INT)
{ {
rtx op0 = XEXP (src, 0); t = plus_constant (t, INTVAL (XEXP (src, 1)));
op0 = reg_known_value[REGNO (op0)]; set_reg_known_value (regno, t);
reg_known_value[regno] set_reg_known_equiv_p (regno, 0);
= plus_constant (op0, INTVAL (XEXP (src, 1)));
reg_known_equiv_p[regno] = 0;
} }
else if (REG_N_SETS (regno) == 1 else if (REG_N_SETS (regno) == 1
&& ! rtx_varies_p (src, 1)) && ! rtx_varies_p (src, 1))
{ {
reg_known_value[regno] = src; set_reg_known_value (regno, src);
reg_known_equiv_p[regno] = 0; set_reg_known_equiv_p (regno, 0);
} }
} }
} }
@ -2917,9 +2976,9 @@ init_alias_analysis (void)
while (changed && ++pass < MAX_ALIAS_LOOP_PASSES); while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);
/* Fill in the remaining entries. */ /* 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) 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 /* Simplify the reg_base_value array so that no register refers to
another register, except to special registers indirectly through another register, except to special registers indirectly through
@ -2965,10 +3024,10 @@ void
end_alias_analysis (void) end_alias_analysis (void)
{ {
old_reg_base_value = reg_base_value; 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 = 0;
reg_known_value_size = 0; reg_known_value_size = 0;
free (reg_known_equiv_p + FIRST_PSEUDO_REGISTER); free (reg_known_equiv_p);
reg_known_equiv_p = 0; reg_known_equiv_p = 0;
if (alias_invariant) 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 bool memory_modified_in_insn_p (rtx, rtx);
extern rtx find_base_term (rtx); extern rtx find_base_term (rtx);
extern rtx gen_hard_reg_clobber (enum machine_mode, unsigned int); 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 */ /* In sibcall.c */
typedef enum { typedef enum {

View File

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