aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-03-24 16:58:57 -0800
committerRichard Henderson <rth@gcc.gnu.org>2004-03-24 16:58:57 -0800
commitbb1acb3e8f2dc8bb1bd408a6c56762073c90bf00 (patch)
tree8cdddee725800b5e9dccac42180f7f908c632294
parentbbcb76f2641a4bd47d0dd090d12857d88743175d (diff)
downloadgcc-bb1acb3e8f2dc8bb1bd408a6c56762073c90bf00.zip
gcc-bb1acb3e8f2dc8bb1bd408a6c56762073c90bf00.tar.gz
gcc-bb1acb3e8f2dc8bb1bd408a6c56762073c90bf00.tar.bz2
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
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/alias.c137
-rw-r--r--gcc/rtl.h2
-rw-r--r--gcc/sched-deps.c32
4 files changed, 136 insertions, 53 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ad09c14..f826918 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/alias.c b/gcc/alias.c
index 22e1e70..f2bf806 100644
--- a/gcc/alias.c
+++ b/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)
{
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 26466a9..d17325c 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -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 {
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index ad96281..7802bf2 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -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