Commit 2b49ee39 by J"orn Rennecke Committed by Joern Rennecke

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
parent bbe348cd
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) Mon Nov 30 02:00:08 PST 1998 Jeff Law (law@cygnus.com)
* version.c: Bump for snapshot. * version.c: Bump for snapshot.
......
...@@ -630,6 +630,22 @@ memref_used_between_p (memref, start, end) ...@@ -630,6 +630,22 @@ memref_used_between_p (memref, start, end)
return 0; 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 /* Find registers that are equivalent to a single value throughout the
compilation (either because they can be referenced in memory or are set once compilation (either because they can be referenced in memory or are set once
from a single constant). Lower their priority for a register. from a single constant). Lower their priority for a register.
...@@ -798,7 +814,7 @@ update_equiv_regs () ...@@ -798,7 +814,7 @@ update_equiv_regs ()
if (REG_N_SETS (regno) != 1 if (REG_N_SETS (regno) != 1
&& (! note && (! note
|| ! CONSTANT_P (XEXP (note, 0)) || ! function_invariant_p (XEXP (note, 0))
|| (reg_equiv_replacement[regno] || (reg_equiv_replacement[regno]
&& ! rtx_equal_p (XEXP (note, 0), && ! rtx_equal_p (XEXP (note, 0),
reg_equiv_replacement[regno])))) reg_equiv_replacement[regno]))))
...@@ -812,7 +828,7 @@ update_equiv_regs () ...@@ -812,7 +828,7 @@ update_equiv_regs ()
/* If this register is known to be equal to a constant, record that /* If this register is known to be equal to a constant, record that
it is always equivalent to the constant. */ 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); PUT_MODE (note, (enum machine_mode) REG_EQUIV);
/* If this insn introduces a "constant" register, decrease the priority /* If this insn introduces a "constant" register, decrease the priority
......
...@@ -338,6 +338,9 @@ int num_not_at_initial_offset; ...@@ -338,6 +338,9 @@ int num_not_at_initial_offset;
/* Count the number of registers that we may be able to eliminate. */ /* Count the number of registers that we may be able to eliminate. */
static int num_eliminable; 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 /* 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 a label by more than one path and an offset differs, we cannot do the
...@@ -659,6 +662,7 @@ reload (first, global, dumpfile) ...@@ -659,6 +662,7 @@ reload (first, global, dumpfile)
Also look for a "constant" NOTE_INSN_SETJMP. This means that all Also look for a "constant" NOTE_INSN_SETJMP. This means that all
caller-saved registers must be marked live. */ caller-saved registers must be marked live. */
num_eliminable_invariants = 0;
for (insn = first; insn; insn = NEXT_INSN (insn)) for (insn = first; insn; insn = NEXT_INSN (insn))
{ {
rtx set = single_set (insn); rtx set = single_set (insn);
...@@ -674,7 +678,8 @@ reload (first, global, dumpfile) ...@@ -674,7 +678,8 @@ reload (first, global, dumpfile)
rtx note = find_reg_note (insn, REG_EQUIV, NULL_RTX); rtx note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
if (note if (note
#ifdef LEGITIMATE_PIC_OPERAND_P #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))) || LEGITIMATE_PIC_OPERAND_P (XEXP (note, 0)))
#endif #endif
) )
...@@ -692,9 +697,22 @@ reload (first, global, dumpfile) ...@@ -692,9 +697,22 @@ reload (first, global, dumpfile)
reg_equiv_memory_loc[i] = x; reg_equiv_memory_loc[i] = x;
} }
else if (CONSTANT_P (x)) else if (function_invariant_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)
{ {
if (LEGITIMATE_CONSTANT_P (x)) reg_equiv_constant[i] = x;
num_eliminable_invariants++;
}
else if (LEGITIMATE_CONSTANT_P (x))
reg_equiv_constant[i] = x; reg_equiv_constant[i] = x;
else else
reg_equiv_memory_loc[i] reg_equiv_memory_loc[i]
...@@ -1335,9 +1353,16 @@ calculate_needs_all_insns (global) ...@@ -1335,9 +1353,16 @@ calculate_needs_all_insns (global)
rtx old_notes = REG_NOTES (insn); rtx old_notes = REG_NOTES (insn);
int did_elimination = 0; int did_elimination = 0;
int operands_changed = 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 needed, eliminate any eliminable registers. */
if (num_eliminable) if (num_eliminable || num_eliminable_invariants)
did_elimination = eliminate_regs_in_insn (insn, 0); did_elimination = eliminate_regs_in_insn (insn, 0);
/* Analyze the instruction. */ /* Analyze the instruction. */
...@@ -2698,6 +2723,11 @@ eliminate_regs (x, mem_mode, insn) ...@@ -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; return x;
case PLUS: case PLUS:
...@@ -4163,7 +4193,7 @@ reload_as_needed (live_known) ...@@ -4163,7 +4193,7 @@ reload_as_needed (live_known)
/* If we need to do register elimination processing, do so. /* If we need to do register elimination processing, do so.
This might delete the insn, in which case we are done. */ 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); eliminate_regs_in_insn (insn, 1);
if (GET_CODE (insn) == NOTE) if (GET_CODE (insn) == NOTE)
......
...@@ -1440,6 +1440,7 @@ extern void init_optabs PROTO ((void)); ...@@ -1440,6 +1440,7 @@ extern void init_optabs PROTO ((void));
extern void dump_local_alloc PROTO ((FILE *)); extern void dump_local_alloc PROTO ((FILE *));
#endif #endif
extern void local_alloc PROTO ((void)); extern void local_alloc PROTO ((void));
extern int function_invariant_p PROTO ((rtx));
/* In reload1.c */ /* In reload1.c */
extern void reload_cse_regs PROTO ((rtx)); extern void reload_cse_regs PROTO ((rtx));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment