summaryrefslogtreecommitdiffstats
path: root/gcc/regclass.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2001-07-16 17:54:34 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2001-07-16 17:54:34 +0000
commit546edcaaf9c30b39a7ac0240e86f2fcfd01e9d65 (patch)
tree91f60d01900241bcf2cec0a70c51d3cdca1a9403 /gcc/regclass.c
parent5d2e3b0feb8affd606954a3ebe98f6cbe4a24b90 (diff)
downloadppe42-gcc-546edcaaf9c30b39a7ac0240e86f2fcfd01e9d65.tar.gz
ppe42-gcc-546edcaaf9c30b39a7ac0240e86f2fcfd01e9d65.zip
* hard-reg-set.h (regs_invalidated_by_call): Declare.
* regclass.c (regs_invalidated_by_call): Move from cse.c. (init_reg_sets_1): Move initialization from cse_main. * cse.c (regs_invalidated_by_call): Move to regclass.c. (cse_main): Move its initialization also. * df.c (df_insn_refs_record): Use regs_invalidated_by_call. * flow.c (propagate_one_insn): Likewise. * gcse.c (compute_hash_table): Likewise. (compute_kill_rd, compute_store_table): Likewise. * sched-deps.c (sched_analyze_1): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44053 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/regclass.c')
-rw-r--r--gcc/regclass.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/gcc/regclass.c b/gcc/regclass.c
index 0af5328effe..e3eca7f35d1 100644
--- a/gcc/regclass.c
+++ b/gcc/regclass.c
@@ -116,7 +116,16 @@ int n_non_fixed_regs;
and are also considered fixed. */
char global_regs[FIRST_PSEUDO_REGISTER];
-
+
+/* Contains 1 for registers that are set or clobbered by calls. */
+/* ??? Ideally, this would be just call_used_regs plus global_regs, but
+ for someone's bright idea to have call_used_regs strictly include
+ fixed_regs. Which leaves us guessing as to the set of fixed_regs
+ that are actually preserved. We know for sure that those associated
+ with the local stack frame are safe, but scant others. */
+
+HARD_REG_SET regs_invalidated_by_call;
+
/* Table of register numbers in the order in which to try to use them. */
#ifdef REG_ALLOC_ORDER
int reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER;
@@ -410,6 +419,7 @@ init_reg_sets_1 ()
CLEAR_HARD_REG_SET (fixed_reg_set);
CLEAR_HARD_REG_SET (call_used_reg_set);
CLEAR_HARD_REG_SET (call_fixed_reg_set);
+ CLEAR_HARD_REG_SET (regs_invalidated_by_call);
memcpy (call_fixed_regs, fixed_regs, sizeof call_fixed_regs);
@@ -428,7 +438,34 @@ init_reg_sets_1 ()
SET_HARD_REG_BIT (call_fixed_reg_set, i);
if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (i)))
SET_HARD_REG_BIT (losing_caller_save_reg_set, i);
+
+ /* There are a couple of fixed registers that we know are safe to
+ exclude from being clobbered by calls:
+
+ The frame pointer is always preserved across calls. The arg pointer
+ is if it is fixed. The stack pointer usually is, unless
+ RETURN_POPS_ARGS, in which case an explicit CLOBBER will be present.
+ If we are generating PIC code, the PIC offset table register is
+ preserved across calls, though the target can override that. */
+
+ if (i == STACK_POINTER_REGNUM || i == FRAME_POINTER_REGNUM)
+ ;
+#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
+ else if (i == HARD_FRAME_POINTER_REGNUM)
+ ;
+#endif
+#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
+ else if (i == ARG_POINTER_REGNUM && fixed_regs[i])
+ ;
+#endif
+#ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
+ else if (i == PIC_OFFSET_TABLE_REGNUM && flag_pic)
+ ;
+#endif
+ else if (call_used_regs[i] || global_regs[i])
+ SET_HARD_REG_BIT (regs_invalidated_by_call, i);
}
+
memset (contains_reg_of_mode, 0, sizeof (contains_reg_of_mode));
memset (allocatable_regs_of_mode, 0, sizeof (allocatable_regs_of_mode));
for (m = 0; m < (unsigned int) MAX_MACHINE_MODE; m++)
OpenPOWER on IntegriCloud