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
This commit is contained in:
parent
bbe348cd18
commit
2b49ee3981
|
@ -1,3 +1,20 @@
|
|||
Tue Dec 1 17:58:26 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
|
||||
|
||||
* 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.
|
||||
|
||||
Mon Nov 30 02:00:08 PST 1998 Jeff Law (law@cygnus.com)
|
||||
|
||||
* version.c: Bump for snapshot.
|
||||
|
|
|
@ -630,6 +630,22 @@ memref_used_between_p (memref, start, end)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Return nonzero if the rtx X is invariant over the current function. */
|
||||
int
|
||||
function_invariant_p (x)
|
||||
rtx x;
|
||||
{
|
||||
if (CONSTANT_P (x))
|
||||
return 1;
|
||||
if (x == frame_pointer_rtx || x == arg_pointer_rtx)
|
||||
return 1;
|
||||
if (GET_CODE (x) == PLUS
|
||||
&& (XEXP (x, 0) == frame_pointer_rtx || XEXP (x, 0) == arg_pointer_rtx)
|
||||
&& CONSTANT_P (XEXP (x, 1)))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find registers that are equivalent to a single value throughout the
|
||||
compilation (either because they can be referenced in memory or are set once
|
||||
from a single constant). Lower their priority for a register.
|
||||
|
@ -798,7 +814,7 @@ update_equiv_regs ()
|
|||
|
||||
if (REG_N_SETS (regno) != 1
|
||||
&& (! note
|
||||
|| ! CONSTANT_P (XEXP (note, 0))
|
||||
|| ! function_invariant_p (XEXP (note, 0))
|
||||
|| (reg_equiv_replacement[regno]
|
||||
&& ! rtx_equal_p (XEXP (note, 0),
|
||||
reg_equiv_replacement[regno]))))
|
||||
|
@ -812,7 +828,7 @@ update_equiv_regs ()
|
|||
|
||||
/* If this register is known to be equal to a constant, record that
|
||||
it is always equivalent to the constant. */
|
||||
if (note && CONSTANT_P (XEXP (note, 0)))
|
||||
if (note && function_invariant_p (XEXP (note, 0)))
|
||||
PUT_MODE (note, (enum machine_mode) REG_EQUIV);
|
||||
|
||||
/* If this insn introduces a "constant" register, decrease the priority
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue