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:
parent
bbcb76f264
commit
bb1acb3e8f
|
@ -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,
|
||||
|
|
137
gcc/alias.c
137
gcc/alias.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue