diff options
author | bonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-08 12:22:30 +0000 |
---|---|---|
committer | bonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-08 12:22:30 +0000 |
commit | e0bd4156d6613e878cafcb23f52d8c3e72d928eb (patch) | |
tree | 556125bd3f1ec87bfe5654cb4bf76058c22173f4 /gcc/fwprop.c | |
parent | 0f241d3febb1990e55daad2841f65020424d70d2 (diff) | |
download | gcc-e0bd4156d6613e878cafcb23f52d8c3e72d928eb.tar.gz |
2009-05-08 Paolo Bonzini <bonzini@gnu.org>
PR rtl-optimization/33928
PR 26854
* fwprop.c (use_def_ref, get_def_for_use, bitmap_only_bit_bitween,
process_uses, build_single_def_use_links): New.
(update_df): Update use_def_ref.
(forward_propagate_into): Use get_def_for_use instead of use-def
chains.
(fwprop_init): Call build_single_def_use_links and let it initialize
dataflow.
(fwprop_done): Free use_def_ref.
(fwprop_addr): Eliminate duplicate call to df_set_flags.
* df-problems.c (df_rd_simulate_artificial_defs_at_top,
df_rd_simulate_one_insn): New.
(df_rd_bb_local_compute_process_def): Update head comment.
(df_chain_create_bb): Use the new RD simulation functions.
* df.h (df_rd_simulate_artificial_defs_at_top,
df_rd_simulate_one_insn): New.
* opts.c (decode_options): Enable fwprop at -O1.
* doc/invoke.texi (-fforward-propagate): Document this.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147282 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fwprop.c')
-rw-r--r-- | gcc/fwprop.c | 125 |
1 files changed, 111 insertions, 14 deletions
diff --git a/gcc/fwprop.c b/gcc/fwprop.c index 11c948f2127..669d03cc066 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -105,6 +105,111 @@ along with GCC; see the file COPYING3. If not see static int num_changes; +DEF_VEC_P(df_ref); +DEF_VEC_ALLOC_P(df_ref,heap); +VEC(df_ref,heap) *use_def_ref; + + +/* Return the only def in USE's use-def chain, or NULL if there is + more than one def in the chain. */ + +static inline df_ref +get_def_for_use (df_ref use) +{ + return VEC_index (df_ref, use_def_ref, DF_REF_ID (use)); +} + + +/* Return the only bit between FIRST and LAST that is set in B, + or -1 if there are zero or more than one such bits. */ + +static inline int +bitmap_only_bit_between (const_bitmap b, unsigned first, unsigned last) +{ + bitmap_iterator bi; + unsigned bit, bit2; + + if (last < first) + return -1; + + bmp_iter_set_init (&bi, b, first, &bit); + if (bmp_iter_set (&bi, &bit) && bit <= last) + { + bit2 = bit; + bmp_iter_next (&bi, &bit2); + if (!bmp_iter_set (&bi, &bit2) || bit2 > last) + return bit; + } + return -1; +} + + +/* Fill the use_def_ref vector with values for the uses in USE_REC, + taking reaching definitions info from LOCAL_RD. TOP_FLAG says + which artificials uses should be used, when USE_REC is an + artificial use vector. */ + +static void +process_uses (bitmap local_rd, df_ref *use_rec, int top_flag) +{ + df_ref use; + while ((use = *use_rec++) != NULL) + if (top_flag == (DF_REF_FLAGS (use) & DF_REF_AT_TOP)) + { + unsigned int uregno = DF_REF_REGNO (use); + unsigned int first = DF_DEFS_BEGIN (uregno); + unsigned int last = first + DF_DEFS_COUNT (uregno) - 1; + int defno = bitmap_only_bit_between (local_rd, first, last); + df_ref def = (defno == -1) ? NULL : DF_DEFS_GET (defno); + + VEC_replace (df_ref, use_def_ref, DF_REF_ID (use), def); + } +} + + +/* Do dataflow analysis and use reaching definitions to build + a vector holding the reaching definitions of uses that have a + single RD. */ + +static void +build_single_def_use_links (void) +{ + basic_block bb; + bitmap local_rd = BITMAP_ALLOC (NULL); + + /* We use reaching definitions to compute our restricted use-def chains. */ + df_set_flags (DF_EQ_NOTES); + df_rd_add_problem (); + df_analyze (); + df_maybe_reorganize_use_refs (DF_REF_ORDER_BY_INSN_WITH_NOTES); + + use_def_ref = VEC_alloc (df_ref, heap, DF_USES_TABLE_SIZE ()); + VEC_safe_grow (df_ref, heap, use_def_ref, DF_USES_TABLE_SIZE ()); + + FOR_EACH_BB (bb) + { + int bb_index = bb->index; + struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index); + rtx insn; + + bitmap_copy (local_rd, bb_info->in); + process_uses (local_rd, df_get_artificial_uses (bb_index), DF_REF_AT_TOP); + + df_rd_simulate_artificial_defs_at_top (bb, local_rd); + FOR_BB_INSNS (bb, insn) + if (INSN_P (insn)) + { + unsigned int uid = INSN_UID (insn); + process_uses (local_rd, DF_INSN_UID_USES (uid), 0); + process_uses (local_rd, DF_INSN_UID_EQ_USES (uid), 0); + df_rd_simulate_one_insn (bb, insn, local_rd); + } + + process_uses (local_rd, df_get_artificial_uses (bb_index), 0); + } + + BITMAP_FREE (local_rd); +} /* Do not try to replace constant addresses or addresses of local and argument slots. These MEM expressions are made only once and inserted @@ -716,7 +821,8 @@ update_df (rtx insn, rtx *loc, df_ref *use_rec, enum df_ref_type type, width, offset, mode); /* Set up the use-def chain. */ - df_chain_copy (new_use, DF_REF_CHAIN (orig_use)); + gcc_assert (DF_REF_ID (new_use) == (int) VEC_length (df_ref, use_def_ref)); + VEC_safe_push (df_ref, heap, use_def_ref, get_def_for_use (orig_use)); changed = true; } if (changed) @@ -1035,7 +1141,6 @@ forward_propagate_and_simplify (df_ref use, rtx def_insn, rtx def_set) static void forward_propagate_into (df_ref use) { - struct df_link *defs; df_ref def; rtx def_insn, def_set, use_insn; rtx parent; @@ -1046,11 +1151,9 @@ forward_propagate_into (df_ref use) return; /* Only consider uses that have a single definition. */ - defs = DF_REF_CHAIN (use); - if (!defs || defs->next) + def = get_def_for_use (use); + if (!def) return; - - def = defs->ref; if (DF_REF_FLAGS (def) & DF_REF_READ_WRITE) return; if (DF_REF_IS_ARTIFICIAL (def)) @@ -1096,12 +1199,7 @@ fwprop_init (void) insns (sadly) if we are not working in cfglayout mode. */ loop_optimizer_init (0); - /* Now set up the dataflow problem (we only want use-def chains) and - put the dataflow solver to work. */ - df_set_flags (DF_EQ_NOTES); - df_chain_add_problem (DF_UD_CHAIN); - df_analyze (); - df_maybe_reorganize_use_refs (DF_REF_ORDER_BY_INSN_WITH_NOTES); + build_single_def_use_links (); df_set_flags (DF_DEFER_INSN_RESCAN); } @@ -1110,6 +1208,7 @@ fwprop_done (void) { loop_optimizer_finalize (); + VEC_free (df_ref, heap, use_def_ref); free_dominance_info (CDI_DOMINATORS); cleanup_cfg (0); delete_trivially_dead_insns (get_insns (), max_reg_num ()); @@ -1187,8 +1286,6 @@ fwprop_addr (void) /* Go through all the uses. update_df will create new ones at the end, and we'll go through them as well. */ - df_set_flags (DF_DEFER_INSN_RESCAN); - for (i = 0; i < DF_USES_TABLE_SIZE (); i++) { df_ref use = DF_USES_GET (i); |