summaryrefslogtreecommitdiff
path: root/gcc/local-alloc.c
diff options
context:
space:
mode:
authorzadeck <zadeck@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-02 13:10:07 +0000
committerzadeck <zadeck@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-02 13:10:07 +0000
commitdea7b504afdd99c98883a1e47226e805beb752b3 (patch)
treeb10f5b41b330de2e7955bcee2d0e55e357b7321d /gcc/local-alloc.c
parent0c80423da5fc889b03078be0b322542054ed219f (diff)
downloadgcc-dea7b504afdd99c98883a1e47226e805beb752b3.tar.gz
2007-09-02 Kenneth Zadeck <zadeck@naturalbridge.com>
* ra-conflict.c: New file. * ra.h: New file. * reload.c (push_reload, find_dummy_reload): Change DF_RA_LIVE usage to DF_LIVE usage. * rtlanal.c (subreg_nregs_with_regno): New function. * df-scan.c (df_def_record_1, df_uses_record): Add code to set DF_REF_EXTRACT, DF_REF_STRICT_LOWER_PART, and DF_REF_SUBREG flags. (df_has_eh_preds): Removed. (df_bb_refs_collect, df_bb_refs_collect, df_bb_refs_collect, df_exit_block_uses_collect): Changed call from df_has_eh_preds to bb_has_eh_pred. * global.c (allocno, max_allocno, conflicts, allocno_row_words, reg_allocno, EXECUTE_IF_SET_IN_ALLOCNO_SET): Moved to ra.h (SET_ALLOCNO_LIVE, CLEAR_ALLOCNO_LIVE): Moved to ra-conflicts.c. (regs_set, record_one_conflict, record_conflicts, mark_reg_store, mark_reg_clobber, mark_reg_conflicts, mark_reg_death): Deleted. (global_alloc): Turn off rescanning insns after call to global_conflicts and added call to set_preferences. (global_conflicts): Moved to ra-alloc.c. (set_preferences_1, set_preferences): New function. (mirror_conflicts): Changed types for various variables. (mark_elimination): Change DF_RA_LIVE usage to DF_LIVE usage. (build_insn_chain): Rewritten from scratch and made local. (print_insn_chain, print_insn_chains): New functions. (dump_conflicts): Do not print conflicts for fixed_regs. (rest_of_handle_global_alloc): Turn off insn rescanning. * hard-reg-set.h: Fixed comment. * local-alloc.c (update_equiv_regs): Change DF_RA_LIVE usage to DF_LIVE usage and delete refs to TOP sets. (block_alloc): Mark regs as live if they are in the artificial defs at top of block. (find_stack_regs): New function. (rest_of_handle_local_alloc): Changed urec problem to live problem and do not turn off df rescanning. * df.h (DF_UREC, DF_UREC_BB_INFO, DF_LIVE_TOP, DF_RA_LIVE_IN, DF_RA_LIVE_TOP, DF_RA_LIVE_OUT, df_urec_bb_info, df_urec, df_urec_add_problem, df_urec_get_bb_info, df_has_eh_preds): Removed. (DF_CHAIN, DF_NOTE, DF_CHAIN): Renumbered. (DF_REF_EXTRACT, DF_REF_STRICT_LOWER_PART, DF_REF_SUBREG): New fields in df_ref_flags. The rest have been renumbered. * init-regs.c (initialize_uninitialized_regs): Enhanced debugging at -O1. * rtl.h (subreg_nregs_with_regno): New function. * df-problems.c: (df_get_live_out, df_get_live_in, df_get_live_top): Removed reference to DF_RA_LIVE. (df_lr_reset, df_lr_transfer_function, df_live_free_bb_info, df_live_alloc, df_live_reset, df_live_local_finalize, df_live_free): Make top set only if different from in set. (df_lr_top_dump, df_live_top_dump): Only print top set if different from in set. (df_lr_bb_local_compute): Removed unnecessary check. (df_urec_problem_data, df_urec_set_bb_info, df_urec_free_bb_info, df_urec_alloc, df_urec_mark_reg_change, earlyclobber_regclass, df_urec_check_earlyclobber, df_urec_mark_reg_use_for_earlyclobber, df_urec_mark_reg_use_for_earlyclobber_1, df_urec_bb_local_compute, df_urec_local_compute, df_urec_init, df_urec_local_finalize, df_urec_confluence_n, df_urec_transfer_function, df_urec_free, df_urec_top_dump, df_urec_bottom_dump, problem_UREC, df_urec_add_problem): Removed. (df_simulate_fixup_sets): Changed call from df_has_eh_preds to bb_has_eh_pred. * Makefile.in (ra-conflict.o, ra.h): New dependencies. * basic_block.h (bb_has_abnormal_pred): New function. * reload1.c (compute_use_by_pseudos): Change DF_RA_LIVE usage to DF_LIVE usage. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128957 138bc75d-0d04-0410-961f-82ee72b054a4
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. */