aboutsummaryrefslogtreecommitdiff
path: root/gcc/sched.c
diff options
context:
space:
mode:
authorJim Wilson <wilson@gcc.gnu.org>1993-03-15 11:48:38 -0800
committerJim Wilson <wilson@gcc.gnu.org>1993-03-15 11:48:38 -0800
commitc3af9fc81e69cbbe49f33268669d60bfab2e00d6 (patch)
tree1c1a31a5bd738c831ebb50f75accf361b2820c63 /gcc/sched.c
parent581c26f9461f19f9e63fb05cd9a034c15d272293 (diff)
downloadgcc-c3af9fc81e69cbbe49f33268669d60bfab2e00d6.zip
gcc-c3af9fc81e69cbbe49f33268669d60bfab2e00d6.tar.gz
gcc-c3af9fc81e69cbbe49f33268669d60bfab2e00d6.tar.bz2
(reg_known_equiv_p): New variable.
(init_alias_analysis): Allocate and compute reg_known_equiv_p. (sched_analyze_1): Reenable code for REG_EQUIV notes, using reg_known_equiv_p so that it is only used on REG_EQUIV notes. (sched_analyze_2): Likewise. Only pass memory addresses to the sched_analyze_2 call. From-SVN: r3746
Diffstat (limited to 'gcc/sched.c')
-rw-r--r--gcc/sched.c69
1 files changed, 36 insertions, 33 deletions
diff --git a/gcc/sched.c b/gcc/sched.c
index cd844cb..dc944e4 100644
--- a/gcc/sched.c
+++ b/gcc/sched.c
@@ -294,6 +294,19 @@ void schedule_insns ();
for pseudo-register N. */
static rtx *reg_known_value;
+/* Vector recording for each reg_known_value whether it is due to a
+ REG_EQUIV note. Future passes (viz., reload) may replace the
+ pseudo with the equivalent expression and so we account for the
+ dependences that would be introduced if that happens. */
+/* ??? This is a problem only on the Convex. The REG_EQUIV notes created in
+ assign_parms mention the arg pointer, and there are explicit insns in the
+ RTL that modify the arg pointer. Thus we must ensure that such insns don't
+ get scheduled across each other because that would invalidate the 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. */
+static char *reg_known_equiv_p;
+
/* Indicates number of valid entries in reg_known_value. */
static int reg_known_value_size;
@@ -341,6 +354,12 @@ init_alias_analysis ()
bzero (reg_known_value+FIRST_PSEUDO_REGISTER,
(maxreg-FIRST_PSEUDO_REGISTER) * sizeof (rtx));
+ reg_known_equiv_p
+ = (char *) oballoc ((maxreg-FIRST_PSEUDO_REGISTER) * sizeof (char))
+ - FIRST_PSEUDO_REGISTER;
+ bzero (reg_known_equiv_p+FIRST_PSEUDO_REGISTER,
+ (maxreg-FIRST_PSEUDO_REGISTER) * sizeof (char));
+
/* Fill in the entries with known constant values. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if ((set = single_set (insn)) != 0
@@ -350,7 +369,11 @@ init_alias_analysis ()
&& reg_n_sets[REGNO (SET_DEST (set))] == 1)
|| (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
&& GET_CODE (XEXP (note, 0)) != EXPR_LIST)
- reg_known_value[REGNO (SET_DEST (set))] = XEXP (note, 0);
+ {
+ int regno = REGNO (SET_DEST (set));
+ reg_known_value[regno] = XEXP (note, 0);
+ reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV;
+ }
/* Fill in the remaining entries. */
while (--maxreg >= FIRST_PSEUDO_REGISTER)
@@ -1622,24 +1645,13 @@ sched_analyze_1 (x, insn)
add_dependence (insn, reg_last_sets[regno], REG_DEP_OUTPUT);
reg_last_sets[regno] = insn;
-#if 0
- /* ??? This code has two serious problems:
- 1) It can cause an infinite loop if regno is mentioned in
- its reg_known_value.
- 2) It can cause execution time exponential in the size of the
- input if there are long chains of reg_known_values pointing
- to other reg_known_values.
- This code was specifically added to handle fake argument pointers.
- It may need to be rewritten to just handle that specific case. */
-
/* Pseudos that are REG_EQUIV to something may be replaced
- by that during reloading, so we can potentially read
- quantities mentioned in those addresses. */
- if (! reload_completed)
- if (reg_known_value[regno] != regno_reg_rtx[regno])
- if (GET_CODE (reg_known_value[regno]) == MEM)
- sched_analyze_2 (XEXP (reg_known_value[regno], 0), insn);
-#endif
+ 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 (XEXP (reg_known_value[regno], 0), insn);
/* Don't let it cross a call after scheduling if it doesn't
already cross one. */
@@ -1793,22 +1805,13 @@ sched_analyze_2 (x, insn)
if (reg_last_sets[regno])
add_dependence (insn, reg_last_sets[regno], 0);
-#if 0
- /* ??? This code has two serious problems:
- 1) It can cause an infinite loop if regno is mentioned in
- its reg_known_value.
- 2) It can cause execution time exponential in the size of the
- input if there are long chains of reg_known_values pointing
- to other reg_known_values.
- This code was specifically added to handle fake argument pointers.
- It may need to be rewritten to just handle that specific case. */
-
/* Pseudos that are REG_EQUIV to something may be replaced
- by that, so we depend on anything mentioned there too. */
- if (! reload_completed)
- if (reg_known_value[regno] != regno_reg_rtx[regno])
- sched_analyze_2 (reg_known_value[regno], insn);
-#endif
+ 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 (XEXP (reg_known_value[regno], 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