This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
patch committed to dataflow branch
- From: Kenneth Zadeck <zadeck at naturalbridge dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, "Berlin, Daniel" <dberlin at dberlin dot org>, "Zadeck, Kenneth" <zadeck at naturalbridge dot com>
- Date: Thu, 13 Apr 2006 14:50:29 -0400
- Subject: patch committed to dataflow branch
This patch converts rtl-seqabstr to use df rather than flow.
The last three frags are minor cleanups that should have been in earlier patches and will be put there before submission to mainline.
This code has been bootstrapped and regression tested on
x86_64-unknown-linux-gnu
powerpc64-unknown-linux-gnu
i686-pc-linux-gnu
Kenny
2006-04-13 Kenneth Zadeck <zadeck@naturalbridge.com>
* rtl-factoring (collect_pattern_seqs, clear_regs_live_in_seq,
recompute_gain_for_pattern_seq, clear_regs_live_in_seq,
recompute_gain, split_blocks_after_seqs, split_pattern_seq,
erase_matching_seqs, abstract_best_seq, rtl_seqabstr): Threaded
local instance of df to replace all references to flow.
(gate_rtl_seqabstr): Removed unnecessary calls.
* passes.c (init_optimization_passes): Moved clear_df before
rtl_seqabstr. Removed some expensive calls to dce.
* tree-pass.h (pass_fast_rtl_dce): New.
* regrename.c (gate_handle_regrename): Update call to pass.
* sched-rgn.c (rest_of_handle_sched2): Remove outdated calls.
Index: rtl-factoring.c
===================================================================
--- rtl-factoring.c (revision 112855)
+++ rtl-factoring.c (working copy)
@@ -438,7 +438,7 @@ match_seqs (p_hash_elem e0, p_hash_elem
into PATTERN_SEQS. */
static void
-collect_pattern_seqs (void)
+collect_pattern_seqs (struct df *df ATTRIBUTE_UNUSED)
{
htab_iterator hti0, hti1, hti2;
p_hash_bucket hash_bucket;
@@ -455,36 +455,39 @@ collect_pattern_seqs (void)
FOR_EACH_BB (bb)
{
regset_head live;
- struct propagate_block_info *pbi;
rtx insn;
+ rtx prev;
/* Initialize liveness propagation. */
INIT_REG_SET (&live);
- COPY_REG_SET (&live, DF_LIVE_OUT (rtl_df, bb));
- pbi = init_propagate_block_info (bb, &live, NULL, NULL, 0);
+ df_lr_simulate_artificial_refs_at_end (df, bb, &live);
/* Propagate liveness info and mark insns where a stack reg is live. */
insn = BB_END (bb);
- while (1)
+ for (insn = BB_END (bb); ; insn = prev)
{
- int reg;
- for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
- {
- if (REGNO_REG_SET_P (&live, reg))
- {
- bitmap_set_bit (&stack_reg_live, INSN_UID (insn));
- break;
- }
- }
-
- if (insn == BB_HEAD (bb))
- break;
- insn = propagate_one_insn (pbi, insn);
+ prev = PREV_INSN (insn);
+ if (INSN_P (insn))
+ {
+ int reg;
+ for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
+ {
+ if (REGNO_REG_SET_P (&live, reg))
+ {
+ bitmap_set_bit (&stack_reg_live, INSN_UID (insn));
+ break;
+ }
+ }
+
+ }
+ if (insn == BB_HEAD (bb))
+ break;
+ df_lr_simulate_one_insn (df, bb, insn, &live);
+ insn = prev;
}
/* Free unused data. */
CLEAR_REG_SET (&live);
- free_propagate_block_info (pbi);
}
#endif
@@ -531,24 +534,22 @@ renumbered_reg_set_to_hard_reg_set (HARD
give by its last INSN and its LENGTH. */
static void
-clear_regs_live_in_seq (HARD_REG_SET * regs, rtx insn, int length)
+clear_regs_live_in_seq (struct df *df, HARD_REG_SET * regs, rtx insn, int length)
{
basic_block bb;
regset_head live;
HARD_REG_SET hlive;
- struct propagate_block_info *pbi;
rtx x;
int i;
/* Initialize liveness propagation. */
bb = BLOCK_FOR_INSN (insn);
INIT_REG_SET (&live);
- COPY_REG_SET (&live, DF_LIVE_OUT (rtl_df, bb));
- pbi = init_propagate_block_info (bb, &live, NULL, NULL, 0);
+ df_lr_simulate_artificial_refs_at_end (df, bb, &live);
/* Propagate until INSN if found. */
for (x = BB_END (bb); x != insn;)
- x = propagate_one_insn (pbi, x);
+ df_lr_simulate_one_insn (df, bb, insn, &live);
/* Clear registers live after INSN. */
renumbered_reg_set_to_hard_reg_set (&hlive, &live);
@@ -557,7 +558,8 @@ clear_regs_live_in_seq (HARD_REG_SET * r
/* Clear registers live in and before the sequence. */
for (i = 0; i < length;)
{
- rtx prev = propagate_one_insn (pbi, x);
+ rtx prev = PREV_INSN (x);
+ df_lr_simulate_one_insn (df, bb, insn, &live);
if (INSN_P (x))
{
@@ -570,7 +572,6 @@ clear_regs_live_in_seq (HARD_REG_SET * r
}
/* Free unused data. */
- free_propagate_block_info (pbi);
CLEAR_REG_SET (&live);
}
@@ -579,7 +580,7 @@ clear_regs_live_in_seq (HARD_REG_SET * r
abstract from the matching sequences. */
static void
-recompute_gain_for_pattern_seq (pattern_seq pseq)
+recompute_gain_for_pattern_seq (struct df *df, pattern_seq pseq)
{
matching_seq mseq;
rtx x;
@@ -618,7 +619,7 @@ recompute_gain_for_pattern_seq (pattern_
of PSEQ. */
if (mseq->cost > seq_call_cost)
{
- clear_regs_live_in_seq (&linkregs, mseq->insn,
+ clear_regs_live_in_seq (df, &linkregs, mseq->insn,
mseq->abstracted_length);
if (mseq->abstracted_length > pseq->abstracted_length)
pseq->abstracted_length = mseq->abstracted_length;
@@ -664,7 +665,7 @@ recompute_gain_for_pattern_seq (pattern_
/* Should not use registers live in the pattern sequence as link register.
*/
- clear_regs_live_in_seq (&linkregs, pseq->insn, pseq->abstracted_length);
+ clear_regs_live_in_seq (df, &linkregs, pseq->insn, pseq->abstracted_length);
/* Determine whether pattern sequence contains a call_insn. */
hascall = 0;
@@ -733,7 +734,7 @@ free_pattern_seq (pattern_seq pseq)
place of PATTERN_SEQS. */
static void
-recompute_gain (void)
+recompute_gain (struct df *df)
{
pattern_seq *pseq;
int maxgain;
@@ -742,7 +743,7 @@ recompute_gain (void)
for (pseq = &pattern_seqs; *pseq;)
{
if ((*pseq)->gain <= 0)
- recompute_gain_for_pattern_seq (*pseq);
+ recompute_gain_for_pattern_seq (df, *pseq);
if ((*pseq)->gain > 0)
{
@@ -964,7 +965,7 @@ block_label_after (rtx insn)
sequences. */
static void
-split_blocks_after_seqs (void)
+split_blocks_after_seqs (struct df *df)
{
seq_block sb;
matching_seq mseq;
@@ -975,8 +976,8 @@ split_blocks_after_seqs (void)
for (mseq = sb->matching_seqs; mseq; mseq = mseq->next_matching_seq)
{
block_label_after (mseq->insn);
- IOR_REG_SET (DF_LIVE_OUT (rtl_df, BLOCK_FOR_INSN (pattern_seqs->insn)),
- DF_LIVE_OUT (rtl_df, BLOCK_FOR_INSN (mseq->insn)));
+ IOR_REG_SET (DF_LIVE_OUT (df, BLOCK_FOR_INSN (pattern_seqs->insn)),
+ DF_LIVE_OUT (df, BLOCK_FOR_INSN (mseq->insn)));
}
}
}
@@ -985,7 +986,7 @@ split_blocks_after_seqs (void)
and -return insns before and after the sequence. */
static void
-split_pattern_seq (void)
+split_pattern_seq (struct df *df)
{
rtx insn;
basic_block bb;
@@ -1030,7 +1031,7 @@ split_pattern_seq (void)
gen_symbol_ref_rtx_for_label
(retlabel)), BB_END (bb));
/* Update liveness info. */
- SET_REGNO_REG_SET (DF_LIVE_OUT (rtl_df, bb),
+ SET_REGNO_REG_SET (DF_LIVE_OUT (df, bb),
REGNO (pattern_seqs->link_reg));
}
@@ -1038,7 +1039,7 @@ split_pattern_seq (void)
replaces them with pseudo-calls to the pattern sequence. */
static void
-erase_matching_seqs (void)
+erase_matching_seqs (struct df *df)
{
seq_block sb;
matching_seq mseq;
@@ -1082,12 +1083,12 @@ erase_matching_seqs (void)
BB_END (bb) = callinsn;
/* Maintain control flow and liveness information. */
- SET_REGNO_REG_SET (DF_LIVE_OUT (rtl_df, bb),
+ SET_REGNO_REG_SET (DF_LIVE_OUT (df, bb),
REGNO (pattern_seqs->link_reg));
emit_barrier_after (BB_END (bb));
make_single_succ_edge (bb, BLOCK_FOR_INSN (sb->label), 0);
- IOR_REG_SET (DF_LIVE_OUT (rtl_df, bb),
- DF_LIVE_IN (rtl_df, BLOCK_FOR_INSN (sb->label)));
+ IOR_REG_SET (DF_LIVE_OUT (df, bb),
+ DF_LIVE_IN (df, BLOCK_FOR_INSN (sb->label)));
make_edge (BLOCK_FOR_INSN (seq_blocks->label),
BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL);
@@ -1119,15 +1120,15 @@ free_seq_blocks (void)
from PATTERN_SEQS. */
static void
-abstract_best_seq (void)
+abstract_best_seq (struct df *df)
{
pattern_seq bestpseq;
/* Do the abstraction. */
determine_seq_blocks ();
- split_blocks_after_seqs ();
- split_pattern_seq ();
- erase_matching_seqs ();
+ split_blocks_after_seqs (df);
+ split_pattern_seq (df);
+ erase_matching_seqs (df);
free_seq_blocks ();
/* Record the usage of the link register. */
@@ -1359,6 +1360,10 @@ static void
rtl_seqabstr (void)
{
int iter;
+ struct df * df = df_init (DF_HARD_REGS);
+ df_lr_add_problem (df, DF_LR_RUN_DCE);
+ df_ur_add_problem (df, 0);
+ df_analyze (df);
/* Create a hash list for COLLECT_PATTERN_SEQS. */
hash_buckets = htab_create (HASH_INIT, htab_hash_bucket , htab_eq_bucket ,
@@ -1369,7 +1374,7 @@ rtl_seqabstr (void)
compute_init_costs ();
/* Build an initial set of pattern sequences from the current function. */
- collect_pattern_seqs ();
+ collect_pattern_seqs (df);
dump_pattern_seqs ();
/* Iterate until there are no sequences to abstract. */
@@ -1377,7 +1382,7 @@ rtl_seqabstr (void)
{
/* Recompute gain for sequences if necessary and select sequence with
biggest gain. */
- recompute_gain ();
+ recompute_gain (df);
if (!pattern_seqs)
break;
dump_best_pattern_seq (iter);
@@ -1385,25 +1390,12 @@ rtl_seqabstr (void)
recomputation where needed. */
update_pattern_seqs ();
/* Turn best sequences into pseudo-functions and -calls. */
- abstract_best_seq ();
+ abstract_best_seq (df);
}
/* Cleanup hash tables. */
htab_delete (hash_buckets);
-
- if (iter > 1)
- {
- /* Update notes. */
- count_or_remove_death_notes (NULL, 1);
-
- life_analysis (PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
- | PROP_KILL_DEAD_CODE);
-
- /* Extra cleanup. */
- cleanup_cfg (CLEANUP_EXPENSIVE |
- CLEANUP_UPDATE_LIFE |
- (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
- }
+ df_finish (df);
}
/* The gate function for TREE_OPT_PASS. */
@@ -1419,12 +1411,6 @@ gate_rtl_seqabstr (void)
static unsigned int
rest_of_rtl_seqabstr (void)
{
- life_analysis (PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE | PROP_KILL_DEAD_CODE);
-
- cleanup_cfg (CLEANUP_EXPENSIVE |
- CLEANUP_UPDATE_LIFE |
- (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
-
/* Abstract out common insn sequences. */
rtl_seqabstr ();
return 0;
Index: passes.c
===================================================================
--- passes.c (revision 112917)
+++ passes.c (working copy)
@@ -676,6 +676,6 @@ init_optimization_passes (void)
NEXT_PASS (pass_split_after_reload);
NEXT_PASS (pass_branch_target_load_optimize1);
NEXT_PASS (pass_flow2);
- NEXT_PASS (pass_rtl_seqabstr);
NEXT_PASS (pass_clear_df);
+ NEXT_PASS (pass_rtl_seqabstr);
NEXT_PASS (pass_stack_adjustments);
@@ -682,9 +682,8 @@
NEXT_PASS (pass_peephole2);
NEXT_PASS (pass_if_after_reload);
- NEXT_PASS (pass_rtl_dce);
NEXT_PASS (pass_regrename);
NEXT_PASS (pass_cprop_hardreg);
- NEXT_PASS (pass_rtl_dce);
+ NEXT_PASS (pass_fast_rtl_dce);
NEXT_PASS (pass_reorder_blocks);
NEXT_PASS (pass_branch_target_load_optimize2);
NEXT_PASS (pass_leaf_regs);
Index: tree-pass.h
===================================================================
--- tree-pass.h (revision 112878)
+++ tree-pass.h (working copy)
@@ -334,6 +334,7 @@ extern struct tree_opt_pass pass_rtl_fwp
extern struct tree_opt_pass pass_rtl_fwprop_addr;
extern struct tree_opt_pass pass_jump2;
extern struct tree_opt_pass pass_cse;
+extern struct tree_opt_pass pass_fast_rtl_dce;
extern struct tree_opt_pass pass_rtl_dce;
extern struct tree_opt_pass pass_rtl_dse;
extern struct tree_opt_pass pass_gcse;
Index: regrename.c
===================================================================
--- regrename.c (revision 112878)
+++ regrename.c (working copy)
@@ -1961,10 +1961,7 @@ gate_handle_regrename (void)
static unsigned int
rest_of_handle_regrename (void)
{
- if (flag_rename_registers)
- regrename_optimize ();
- if (flag_cprop_registers)
- copyprop_hardreg_forward ();
+ regrename_optimize ();
return 0;
}
Index: sched-rgn.c
===================================================================
--- sched-rgn.c (revision 112855)
+++ sched-rgn.c (working copy)
@@ -3250,13 +3250,7 @@ rest_of_handle_sched2 (void)
split_all_insns ();
if (flag_sched2_use_superblocks || flag_sched2_use_traces)
- {
- schedule_ebbs ();
- /* No liveness updating code yet, but it should be easy to do.
- reg-stack recomputes the liveness when needed for now. */
- count_or_remove_death_notes (NULL, 1);
- cleanup_cfg (CLEANUP_EXPENSIVE);
- }
+ schedule_ebbs ();
else
schedule_insns ();
#endif