diff options
author | J"orn Rennecke <amylaar@cygnus.co.uk> | 1998-12-01 10:00:11 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 1998-12-01 10:00:11 +0000 |
commit | 2b49ee39817f8849f931611cdc13a8d18cd209c7 (patch) | |
tree | b9995987f19d6ca65c15b71f6f69120fde1b5af5 /gcc | |
parent | bbe348cd18f81dd9469c81ba6f498e01ca9c5a37 (diff) | |
download | gcc-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')
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/local-alloc.c | 20 | ||||
-rw-r--r-- | gcc/reload1.c | 40 | ||||
-rw-r--r-- | gcc/rtl.h | 1 |
4 files changed, 71 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 74a9a59..ee4b9ff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c index e8110ac..f112713 100644 --- a/gcc/local-alloc.c +++ b/gcc/local-alloc.c @@ -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 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) @@ -1440,6 +1440,7 @@ extern void init_optabs PROTO ((void)); extern void dump_local_alloc PROTO ((FILE *)); #endif extern void local_alloc PROTO ((void)); +extern int function_invariant_p PROTO ((rtx)); /* In reload1.c */ extern void reload_cse_regs PROTO ((rtx)); |