summaryrefslogtreecommitdiff
path: root/gcc/local-alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/local-alloc.c')
-rw-r--r--gcc/local-alloc.c88
1 files changed, 68 insertions, 20 deletions
diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c
index dc56ca47917..4ef1f021f03 100644
--- a/gcc/local-alloc.c
+++ b/gcc/local-alloc.c
@@ -1211,13 +1211,9 @@ update_equiv_regs (void)
if (!bitmap_empty_p (cleared_regs))
FOR_EACH_BB (bb)
{
- bitmap_and_compl_into (DF_RA_LIVE_IN (bb), cleared_regs);
- if (DF_RA_LIVE_TOP (bb))
- bitmap_and_compl_into (DF_RA_LIVE_TOP (bb), cleared_regs);
- bitmap_and_compl_into (DF_RA_LIVE_OUT (bb), cleared_regs);
+ bitmap_and_compl_into (DF_LIVE_IN (bb), cleared_regs);
+ bitmap_and_compl_into (DF_LIVE_OUT (bb), cleared_regs);
bitmap_and_compl_into (DF_LR_IN (bb), cleared_regs);
- if (DF_LR_TOP (bb))
- bitmap_and_compl_into (DF_LR_TOP (bb), cleared_regs);
bitmap_and_compl_into (DF_LR_OUT (bb), cleared_regs);
}
@@ -1277,6 +1273,7 @@ block_alloc (int b)
int max_uid = get_max_uid ();
int *qty_order;
int no_conflict_combined_regno = -1;
+ struct df_ref ** def_rec;
/* Count the instructions in the basic block. */
@@ -1299,7 +1296,19 @@ block_alloc (int b)
/* Initialize table of hardware registers currently live. */
- REG_SET_TO_HARD_REG_SET (regs_live, DF_LR_TOP (BASIC_BLOCK (b)));
+ REG_SET_TO_HARD_REG_SET (regs_live, DF_LR_IN (BASIC_BLOCK (b)));
+
+ /* This is conservative, as this would include registers that are
+ artificial-def'ed-but-not-used. However, artificial-defs are
+ rare, and such uninitialized use is rarer still, and the chance
+ of this having any performance impact is even less, while the
+ benefit is not having to compute and keep the TOP set around. */
+ for (def_rec = df_get_artificial_defs (b); *def_rec; def_rec++)
+ {
+ int regno = DF_REF_REGNO (*def_rec);
+ if (regno < FIRST_PSEUDO_REGISTER)
+ SET_HARD_REG_BIT (regs_live, regno);
+ }
/* This loop scans the instructions of the basic block
and assigns quantities to registers.
@@ -2502,6 +2511,49 @@ dump_local_alloc (FILE *file)
fprintf (file, ";; Register %d in %d.\n", i, reg_renumber[i]);
}
+#ifdef STACK_REGS
+static void
+find_stack_regs (void)
+{
+ bitmap stack_regs = BITMAP_ALLOC (NULL);
+ int i;
+ HARD_REG_SET stack_hard_regs, used;
+ basic_block bb;
+
+ /* Any register that MAY be allocated to a register stack (like the
+ 387) is treated poorly. Each such register is marked as being
+ live everywhere. This keeps the register allocator and the
+ subsequent passes from doing anything useful with these values.
+
+ FIXME: This seems like an incredibly poor idea. */
+
+ CLEAR_HARD_REG_SET (stack_hard_regs);
+ for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
+ SET_HARD_REG_BIT (stack_hard_regs, i);
+
+ for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ {
+ COPY_HARD_REG_SET (used, reg_class_contents[reg_preferred_class (i)]);
+ IOR_HARD_REG_SET (used, reg_class_contents[reg_alternate_class (i)]);
+ AND_HARD_REG_SET (used, stack_hard_regs);
+ if (!hard_reg_set_empty_p (used))
+ bitmap_set_bit (stack_regs, i);
+ }
+
+ if (dump_file)
+ bitmap_print (dump_file, stack_regs, "stack regs:", "\n");
+
+ FOR_EACH_BB (bb)
+ {
+ bitmap_ior_into (DF_LIVE_IN (bb), stack_regs);
+ bitmap_and_into (DF_LIVE_IN (bb), DF_LR_IN (bb));
+ bitmap_ior_into (DF_LIVE_OUT (bb), stack_regs);
+ bitmap_and_into (DF_LIVE_OUT (bb), DF_LR_OUT (bb));
+ }
+ BITMAP_FREE (stack_regs);
+}
+#endif
+
/* Run old register allocator. Return TRUE if we must exit
rest_of_compilation upon return. */
static unsigned int
@@ -2512,26 +2564,22 @@ rest_of_handle_local_alloc (void)
df_note_add_problem ();
- if (optimize > 1)
- df_remove_problem (df_live);
- /* Create a new version of df that has the special version of UR if
- we are doing optimization. */
- if (optimize)
- df_urec_add_problem ();
+ if (optimize == 1)
+ {
+ df_live_add_problem ();
+ df_live_set_all_dirty ();
+ }
#ifdef ENABLE_CHECKING
df->changeable_flags |= DF_VERIFY_SCHEDULED;
#endif
df_analyze ();
+#ifdef STACK_REGS
+ if (optimize)
+ find_stack_regs ();
+#endif
regstat_init_n_sets_and_refs ();
regstat_compute_ri ();
- /* There is just too much going on in the register allocators to
- keep things up to date. At the end we have to rescan anyway
- because things change when the reload_completed flag is set.
- So we just turn off scanning and we will rescan by hand. */
- df_set_flags (DF_NO_INSN_RESCAN);
-
-
/* If we are not optimizing, then this is the only place before
register allocation where dataflow is done. And that is needed
to generate these warnings. */