aboutsummaryrefslogtreecommitdiff
path: root/gcc/reload1.c
diff options
context:
space:
mode:
authorJ"orn Rennecke <amylaar@cygnus.co.uk>1998-12-01 10:00:11 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>1998-12-01 10:00:11 +0000
commit2b49ee39817f8849f931611cdc13a8d18cd209c7 (patch)
treeb9995987f19d6ca65c15b71f6f69120fde1b5af5 /gcc/reload1.c
parentbbe348cd18f81dd9469c81ba6f498e01ca9c5a37 (diff)
downloadgcc-2b49ee39817f8849f931611cdc13a8d18cd209c7.zip
gcc-2b49ee39817f8849f931611cdc13a8d18cd209c7.tar.gz
gcc-2b49ee39817f8849f931611cdc13a8d18cd209c7.tar.bz2
local-alloc.c (function_invariant_p): New function.
* local-alloc.c (function_invariant_p): New function. (update_equiv_regs): Use function_invariant_p instead of CONSTANT_P to decide if an equivalence should be recorded. * reload1.c (num_eliminable_invariants): New static variable. (reload): Set it. Use function_invariant_p instead of CONSTANT_P to decide if an equivalence should be recorded. Unshare PLUS. (calculate_needs_all_insns): Skip insns that only set an equivalence. Take num_eliminable_invariants into account when deciding if register elimination should be done. (reload_as_needed): Take num_eliminable_invariants into account when deciding if register elimination should be done. (eliminate_regs): Handle non-constant reg_equiv_constant. * rtl.h (function_invariant_p): Declare. From-SVN: r24026
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r--gcc/reload1.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c
index e4dee18..08f5375 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -338,6 +338,9 @@ int num_not_at_initial_offset;
/* Count the number of registers that we may be able to eliminate. */
static int num_eliminable;
+/* And the number of registers that are equivalent to a constant that
+ can be eliminated to frame_pointer / arg_pointer + constant. */
+static int num_eliminable_invariants;
/* For each label, we record the offset of each elimination. If we reach
a label by more than one path and an offset differs, we cannot do the
@@ -659,6 +662,7 @@ reload (first, global, dumpfile)
Also look for a "constant" NOTE_INSN_SETJMP. This means that all
caller-saved registers must be marked live. */
+ num_eliminable_invariants = 0;
for (insn = first; insn; insn = NEXT_INSN (insn))
{
rtx set = single_set (insn);
@@ -674,7 +678,8 @@ reload (first, global, dumpfile)
rtx note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
if (note
#ifdef LEGITIMATE_PIC_OPERAND_P
- && (! CONSTANT_P (XEXP (note, 0)) || ! flag_pic
+ && (! function_invariant_p (XEXP (note, 0))
+ || ! flag_pic
|| LEGITIMATE_PIC_OPERAND_P (XEXP (note, 0)))
#endif
)
@@ -692,9 +697,22 @@ reload (first, global, dumpfile)
reg_equiv_memory_loc[i] = x;
}
- else if (CONSTANT_P (x))
+ else if (function_invariant_p (x))
{
- if (LEGITIMATE_CONSTANT_P (x))
+ if (GET_CODE (x) == PLUS)
+ {
+ /* This is PLUS of frame pointer and a constant,
+ and might be shared. Unshare it. */
+ reg_equiv_constant[i] = copy_rtx (x);
+ num_eliminable_invariants++;
+ }
+ else if (x == frame_pointer_rtx
+ || x == arg_pointer_rtx)
+ {
+ reg_equiv_constant[i] = x;
+ num_eliminable_invariants++;
+ }
+ else if (LEGITIMATE_CONSTANT_P (x))
reg_equiv_constant[i] = x;
else
reg_equiv_memory_loc[i]
@@ -1335,9 +1353,16 @@ calculate_needs_all_insns (global)
rtx old_notes = REG_NOTES (insn);
int did_elimination = 0;
int operands_changed = 0;
+ rtx set = single_set (insn);
+
+ /* Skip insns that only set an equivalence. */
+ if (set && GET_CODE (SET_DEST (set)) == REG
+ && reg_renumber[REGNO (SET_DEST (set))] < 0
+ && reg_equiv_constant[REGNO (SET_DEST (set))])
+ continue;
/* If needed, eliminate any eliminable registers. */
- if (num_eliminable)
+ if (num_eliminable || num_eliminable_invariants)
did_elimination = eliminate_regs_in_insn (insn, 0);
/* Analyze the instruction. */
@@ -2698,6 +2723,11 @@ eliminate_regs (x, mem_mode, insn)
}
}
+ else if (reg_renumber[regno] < 0 && reg_equiv_constant
+ && reg_equiv_constant[regno]
+ && ! CONSTANT_P (reg_equiv_constant[regno]))
+ return eliminate_regs (copy_rtx (reg_equiv_constant[regno]),
+ mem_mode, insn);
return x;
case PLUS:
@@ -4163,7 +4193,7 @@ reload_as_needed (live_known)
/* If we need to do register elimination processing, do so.
This might delete the insn, in which case we are done. */
- if (num_eliminable && chain->need_elim)
+ if ((num_eliminable || num_eliminable_invariants) && chain->need_elim)
{
eliminate_regs_in_insn (insn, 1);
if (GET_CODE (insn) == NOTE)