From fb4061627b2cd9acb3298d8a7f3ad90ab2615cf7 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 20 Mar 2007 08:31:13 +0000 Subject: [PATCH] re PR middle-end/30907 (Propagation of addresses within loops pessimizes code) 2007-03-19 Paolo Bonzini PR rtl-optimization/30907 * fwprop.c (forward_propagate_into): Never propagate inside a loop. (fwprop_init): Always call loop_optimizer_initialize. (fwprop_done): Always call loop_optimizer_finalize. (fwprop): We always have loop info now. (gate_fwprop_addr): Remove. (pass_fwprop_addr): Use gate_fwprop as gate. PR rtl-optimization/30841 * df-problems.c (df_ru_local_compute, df_rd_local_compute, df_chain_alloc): Call df_reorganize_refs unconditionally. * df-scan.c (df_rescan_blocks, df_reorganize_refs): Change refs_organized to refs_organized_size. (df_ref_create_structure): Use refs_organized_size instead of bitmap_size if refs had been organized, and keep refs_organized_size up-to-date. * df.h (struct df_ref_info): Change refs_organized to refs_organized_size. (DF_DEFS_SIZE, DF_USES_SIZE): Use refs_organized_size instead of bitmap_size. From-SVN: r123084 --- gcc/ChangeLog | 23 +++++++++++++++++++++++ gcc/df-problems.c | 14 ++++---------- gcc/df-scan.c | 42 ++++++++++++++++++++++++------------------ gcc/df.h | 8 ++++---- gcc/fwprop.c | 26 ++++++-------------------- 5 files changed, 61 insertions(+), 52 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4589400a77a..43a8abfd596 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2007-03-19 Paolo Bonzini + + PR rtl-optimization/30907 + * fwprop.c (forward_propagate_into): Never propagate inside a loop. + (fwprop_init): Always call loop_optimizer_initialize. + (fwprop_done): Always call loop_optimizer_finalize. + (fwprop): We always have loop info now. + (gate_fwprop_addr): Remove. + (pass_fwprop_addr): Use gate_fwprop as gate. + + PR rtl-optimization/30841 + * df-problems.c (df_ru_local_compute, df_rd_local_compute, + df_chain_alloc): Call df_reorganize_refs unconditionally. + * df-scan.c (df_rescan_blocks, df_reorganize_refs): Change + refs_organized to refs_organized_size. + (df_ref_create_structure): Use refs_organized_size instead of + bitmap_size if refs had been organized, and keep refs_organized_size + up-to-date. + * df.h (struct df_ref_info): Change refs_organized to + refs_organized_size. + (DF_DEFS_SIZE, DF_USES_SIZE): Use refs_organized_size instead of + bitmap_size. + 2007-03-19 Mark Mitchell * except.c (output_function_exception_table): Do not reference the diff --git a/gcc/df-problems.c b/gcc/df-problems.c index ec80bf74f77..42710b203cf 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -586,9 +586,7 @@ df_ru_local_compute (struct dataflow *dflow, bitmap dense_invalidated = problem_data->dense_invalidated_by_call; df_set_seen (); - - if (!df->use_info.refs_organized) - df_reorganize_refs (&df->use_info); + df_reorganize_refs (&df->use_info); EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi) { @@ -1109,9 +1107,7 @@ df_rd_local_compute (struct dataflow *dflow, bitmap dense_invalidated = problem_data->dense_invalidated_by_call; df_set_seen (); - - if (!df->def_info.refs_organized) - df_reorganize_refs (&df->def_info); + df_reorganize_refs (&df->def_info); EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi) { @@ -2771,8 +2767,7 @@ df_chain_alloc (struct dataflow *dflow, if (dflow->flags & DF_DU_CHAIN) { - if (!df->def_info.refs_organized) - df_reorganize_refs (&df->def_info); + df_reorganize_refs (&df->def_info); /* Clear out the pointers from the refs. */ for (i = 0; i < DF_DEFS_SIZE (df); i++) @@ -2784,8 +2779,7 @@ df_chain_alloc (struct dataflow *dflow, if (dflow->flags & DF_UD_CHAIN) { - if (!df->use_info.refs_organized) - df_reorganize_refs (&df->use_info); + df_reorganize_refs (&df->use_info); for (i = 0; i < DF_USES_SIZE (df); i++) { struct df_ref *ref = df->use_info.refs[i]; diff --git a/gcc/df-scan.c b/gcc/df-scan.c index fea786c0196..d88da8a9930 100644 --- a/gcc/df-scan.c +++ b/gcc/df-scan.c @@ -435,8 +435,8 @@ df_rescan_blocks (struct df *df, bitmap blocks) struct dataflow *dflow = df->problems_by_index[DF_SCAN]; basic_block bb; - df->def_info.refs_organized = false; - df->use_info.refs_organized = false; + df->def_info.refs_organized_size = 0; + df->use_info.refs_organized_size = 0; if (blocks) { @@ -882,7 +882,7 @@ df_reorganize_refs (struct df_ref_info *ref_info) unsigned int offset = 0; unsigned int size = 0; - if (ref_info->refs_organized) + if (ref_info->refs_organized_size) return; if (ref_info->refs_size < ref_info->bitmap_size) @@ -915,7 +915,7 @@ df_reorganize_refs (struct df_ref_info *ref_info) reset it now that we have squished out all of the empty slots. */ ref_info->bitmap_size = size; - ref_info->refs_organized = true; + ref_info->refs_organized_size = size; ref_info->add_refs_inline = true; } @@ -957,22 +957,25 @@ df_ref_create_structure (struct dataflow *dflow, rtx reg, rtx *loc, case DF_REF_REG_DEF: { struct df_reg_info *reg_info = DF_REG_DEF_GET (df, regno); - reg_info->n_refs++; + unsigned int size = df->def_info.refs_organized_size + ? df->def_info.refs_organized_size + : df->def_info.bitmap_size; /* Add the ref to the reg_def chain. */ + reg_info->n_refs++; df_reg_chain_create (reg_info, this_ref); - DF_REF_ID (this_ref) = df->def_info.bitmap_size; + DF_REF_ID (this_ref) = size; if (df->def_info.add_refs_inline) { - if (DF_DEFS_SIZE (df) >= df->def_info.refs_size) + if (size >= df->def_info.refs_size) { - int new_size = df->def_info.bitmap_size - + df->def_info.bitmap_size / 4; + int new_size = size + size / 4; df_grow_ref_info (&df->def_info, new_size); } /* Add the ref to the big array of defs. */ - DF_DEFS_SET (df, df->def_info.bitmap_size, this_ref); - df->def_info.refs_organized = false; + DF_DEFS_SET (df, size, this_ref); + if (df->def_info.refs_organized_size) + df->def_info.refs_organized_size++; } df->def_info.bitmap_size++; @@ -997,22 +1000,25 @@ df_ref_create_structure (struct dataflow *dflow, rtx reg, rtx *loc, case DF_REF_REG_USE: { struct df_reg_info *reg_info = DF_REG_USE_GET (df, regno); - reg_info->n_refs++; + unsigned int size = df->use_info.refs_organized_size + ? df->use_info.refs_organized_size + : df->use_info.bitmap_size; /* Add the ref to the reg_use chain. */ + reg_info->n_refs++; df_reg_chain_create (reg_info, this_ref); - DF_REF_ID (this_ref) = df->use_info.bitmap_size; + DF_REF_ID (this_ref) = size; if (df->use_info.add_refs_inline) { - if (DF_USES_SIZE (df) >= df->use_info.refs_size) + if (size >= df->use_info.refs_size) { - int new_size = df->use_info.bitmap_size - + df->use_info.bitmap_size / 4; + int new_size = size + size / 4; df_grow_ref_info (&df->use_info, new_size); } /* Add the ref to the big array of defs. */ - DF_USES_SET (df, df->use_info.bitmap_size, this_ref); - df->use_info.refs_organized = false; + DF_USES_SET (df, size, this_ref); + if (df->def_info.refs_organized_size) + df->def_info.refs_organized_size++; } df->use_info.bitmap_size++; diff --git a/gcc/df.h b/gcc/df.h index 6c538b28d4e..d8789b9a7f6 100644 --- a/gcc/df.h +++ b/gcc/df.h @@ -323,9 +323,9 @@ struct df_ref_info unsigned int refs_size; /* Size of currently allocated refs table. */ unsigned int bitmap_size; /* Number of refs seen. */ - /* True if refs table is organized so that every reference for a + /* >0 if refs table is organized so that every reference for a pseudo is contiguous. */ - bool refs_organized; + unsigned int refs_organized_size; /* True if the next refs should be added immediately or false to defer to later to reorganize the table. */ bool add_refs_inline; @@ -433,10 +433,10 @@ struct df || DF_REF_REG_MEM_LOAD_P (REF)) /* Macros to get the refs out of def_info or use_info refs table. */ -#define DF_DEFS_SIZE(DF) ((DF)->def_info.bitmap_size) +#define DF_DEFS_SIZE(DF) ((DF)->def_info.refs_organized_size) #define DF_DEFS_GET(DF,ID) ((DF)->def_info.refs[(ID)]) #define DF_DEFS_SET(DF,ID,VAL) ((DF)->def_info.refs[(ID)]=(VAL)) -#define DF_USES_SIZE(DF) ((DF)->use_info.bitmap_size) +#define DF_USES_SIZE(DF) ((DF)->use_info.refs_organized_size) #define DF_USES_GET(DF,ID) ((DF)->use_info.refs[(ID)]) #define DF_USES_SET(DF,ID,VAL) ((DF)->use_info.refs[(ID)]=(VAL)) diff --git a/gcc/fwprop.c b/gcc/fwprop.c index 6ce91836d45..106424efc96 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -862,10 +862,8 @@ forward_propagate_into (struct df_ref *use) if (DF_REF_FLAGS (def) & DF_REF_ARTIFICIAL) return; - /* Do not propagate loop invariant definitions inside the loop if - we are going to unroll. */ - if (current_loops - && DF_REF_BB (def)->loop_father != DF_REF_BB (use)->loop_father) + /* Do not propagate loop invariant definitions inside the loop. */ + if (DF_REF_BB (def)->loop_father != DF_REF_BB (use)->loop_father) return; /* Check if the use is still present in the insn! */ @@ -900,8 +898,7 @@ fwprop_init (void) loops and be careful about them. But we have to call flow_loops_find before df_analyze, because flow_loops_find may introduce new jump insns (sadly) if we are not working in cfglayout mode. */ - if (flag_rerun_cse_after_loop && (flag_unroll_loops || flag_peel_loops)) - loop_optimizer_init (0); + loop_optimizer_init (0); /* Now set up the dataflow problem (we only want use-def chains) and put the dataflow solver to work. */ @@ -915,10 +912,7 @@ static void fwprop_done (void) { df_finish (df); - - if (flag_rerun_cse_after_loop && (flag_unroll_loops || flag_peel_loops)) - loop_optimizer_finalize (); - + loop_optimizer_finalize (); free_dominance_info (CDI_DOMINATORS); cleanup_cfg (0); delete_trivially_dead_insns (get_insns (), max_reg_num ()); @@ -957,8 +951,7 @@ fwprop (void) { struct df_ref *use = DF_USES_GET (df, i); if (use) - if (!current_loops - || DF_REF_TYPE (use) == DF_REF_REG_USE + if (DF_REF_TYPE (use) == DF_REF_REG_USE || DF_REF_BB (use)->loop_father == NULL) forward_propagate_into (use); } @@ -985,13 +978,6 @@ struct tree_opt_pass pass_rtl_fwprop = 0 /* letter */ }; -static bool -gate_fwprop_addr (void) -{ - return optimize > 0 && flag_forward_propagate && flag_rerun_cse_after_loop - && (flag_unroll_loops || flag_peel_loops); -} - static unsigned int fwprop_addr (void) { @@ -1018,7 +1004,7 @@ fwprop_addr (void) struct tree_opt_pass pass_rtl_fwprop_addr = { "fwprop2", /* name */ - gate_fwprop_addr, /* gate */ + gate_fwprop, /* gate */ fwprop_addr, /* execute */ NULL, /* sub */ NULL, /* next */