aboutsummaryrefslogtreecommitdiff
path: root/gcc/gcse.c
diff options
context:
space:
mode:
authorDaniel Berlin <dberlin@gcc.gnu.org>2007-06-11 18:02:15 +0000
committerDaniel Berlin <dberlin@gcc.gnu.org>2007-06-11 18:02:15 +0000
commit6fb5fa3cbc0d78cf9f4ff7cac5e1d8af1e65c5bb (patch)
treefdb9e9f8a0700a2713dc690fed1a2cf20dae8392 /gcc/gcse.c
parenta91d32a4a65d54cccf639a1541417e39cb7b7deb (diff)
downloadgcc-6fb5fa3cbc0d78cf9f4ff7cac5e1d8af1e65c5bb.zip
gcc-6fb5fa3cbc0d78cf9f4ff7cac5e1d8af1e65c5bb.tar.gz
gcc-6fb5fa3cbc0d78cf9f4ff7cac5e1d8af1e65c5bb.tar.bz2
Merge dataflow branch into mainline
From-SVN: r125624
Diffstat (limited to 'gcc/gcse.c')
-rw-r--r--gcc/gcse.c78
1 files changed, 42 insertions, 36 deletions
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 461e26c..9d800b2 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -171,6 +171,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "timevar.h"
#include "tree-pass.h"
#include "hashtab.h"
+#include "df.h"
+#include "dbgcnt.h"
/* Propagate flow information through back edges and thus enable PRE's
moving loop invariant calculations out of loops.
@@ -584,7 +586,7 @@ static void free_pre_mem (void);
static void compute_pre_data (void);
static int pre_expr_reaches_here_p (basic_block, struct expr *,
basic_block);
-static void insert_insn_end_bb (struct expr *, basic_block, int);
+static void insert_insn_end_basic_block (struct expr *, basic_block, int);
static void pre_insert_copy_insn (struct expr *, rtx);
static void pre_insert_copies (void);
static int pre_delete (void);
@@ -628,7 +630,7 @@ static bool store_killed_in_insn (rtx, rtx, rtx, int);
static bool store_killed_after (rtx, rtx, rtx, basic_block, int *, rtx *);
static bool store_killed_before (rtx, rtx, rtx, basic_block, int *);
static void build_store_vectors (void);
-static void insert_insn_start_bb (rtx, basic_block);
+static void insert_insn_start_basic_block (rtx, basic_block);
static int insert_store (struct ls_expr *, edge);
static void remove_reachable_equiv_notes (basic_block, struct ls_expr *);
static void replace_store_insn (rtx, rtx, basic_block, struct ls_expr *);
@@ -673,6 +675,9 @@ gcse_main (rtx f ATTRIBUTE_UNUSED)
successors and predecessors. */
max_gcse_regno = max_reg_num ();
+ df_note_add_problem ();
+ df_analyze ();
+
if (dump_file)
dump_flow_info (dump_file, dump_flags);
@@ -806,7 +811,6 @@ gcse_main (rtx f ATTRIBUTE_UNUSED)
/* We are finished with alias. */
end_alias_analysis ();
- allocate_reg_info (max_reg_num (), FALSE, FALSE);
if (!optimize_size && flag_gcse_sm)
{
@@ -1728,8 +1732,11 @@ hash_scan_set (rtx pat, rtx insn, struct hash_table *table)
{
/* An expression is not anticipatable if its operands are
modified before this insn or if this is not the only SET in
- this insn. */
- int antic_p = oprs_anticipatable_p (src, insn) && single_set (insn);
+ this insn. The latter condition does not have to mean that
+ SRC itself is not anticipatable, but we just will not be
+ able to handle code motion of insns with multiple sets. */
+ int antic_p = oprs_anticipatable_p (src, insn)
+ && !multiple_sets (insn);
/* An expression is not available if its operands are
subsequently modified, including this insn. It's also not
available if this is a branch, because we can't insert
@@ -2670,7 +2677,6 @@ try_replace_reg (rtx from, rtx to, rtx insn)
if (note != 0 && REG_NOTE_KIND (note) == REG_EQUAL)
set_unique_reg_note (insn, REG_EQUAL,
simplify_replace_rtx (XEXP (note, 0), from, to));
-
if (!success && set && reg_mentioned_p (from, SET_SRC (set)))
{
/* If above failed and this is a single set, try to simplify the source of
@@ -3095,7 +3101,7 @@ do_local_cprop (rtx x, rtx insn, bool alter_jumps, rtx *libcall_sp)
/* If we find a case where we can't fix the retval REG_EQUAL notes
match the new register, we either have to abandon this replacement
or fix delete_trivially_dead_insns to preserve the setting insn,
- or make it delete the REG_EUAQL note, and fix up all passes that
+ or make it delete the REG_EQUAL note, and fix up all passes that
require the REG_EQUAL note there. */
bool adjusted;
@@ -3164,6 +3170,7 @@ adjust_libcall_notes (rtx oldreg, rtx newval, rtx insn, rtx *libcall_sp)
}
}
XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), oldreg, newval);
+ df_notes_rescan (end);
insn = end;
}
return true;
@@ -3214,12 +3221,14 @@ local_cprop_pass (bool alter_jumps)
for (reg_used = &reg_use_table[0]; reg_use_count > 0;
reg_used++, reg_use_count--)
- if (do_local_cprop (reg_used->reg_rtx, insn, alter_jumps,
- libcall_sp))
- {
- changed = true;
- break;
- }
+ {
+ if (do_local_cprop (reg_used->reg_rtx, insn, alter_jumps,
+ libcall_sp))
+ {
+ changed = true;
+ break;
+ }
+ }
if (INSN_DELETED_P (insn))
break;
}
@@ -3991,7 +4000,7 @@ process_insert_insn (struct expr *expr)
no sense for code hoisting. */
static void
-insert_insn_end_bb (struct expr *expr, basic_block bb, int pre)
+insert_insn_end_basic_block (struct expr *expr, basic_block bb, int pre)
{
rtx insn = BB_END (bb);
rtx new_insn;
@@ -4048,7 +4057,7 @@ insert_insn_end_bb (struct expr *expr, basic_block bb, int pre)
}
#endif
/* FIXME: What if something in cc0/jump uses value set in new insn? */
- new_insn = emit_insn_before_noloc (pat, insn);
+ new_insn = emit_insn_before_noloc (pat, insn, bb);
}
/* Likewise if the last insn is a call, as will happen in the presence
@@ -4087,10 +4096,10 @@ insert_insn_end_bb (struct expr *expr, basic_block bb, int pre)
|| NOTE_INSN_BASIC_BLOCK_P (insn))
insn = NEXT_INSN (insn);
- new_insn = emit_insn_before_noloc (pat, insn);
+ new_insn = emit_insn_before_noloc (pat, insn, bb);
}
else
- new_insn = emit_insn_after_noloc (pat, insn);
+ new_insn = emit_insn_after_noloc (pat, insn, bb);
while (1)
{
@@ -4168,7 +4177,7 @@ pre_edge_insert (struct edge_list *edge_list, struct expr **index_map)
now. */
if (eg->flags & EDGE_ABNORMAL)
- insert_insn_end_bb (index_map[j], bb, 0);
+ insert_insn_end_basic_block (index_map[j], bb, 0);
else
{
insn = process_insert_insn (index_map[j]);
@@ -4438,7 +4447,8 @@ pre_delete (void)
/* We only delete insns that have a single_set. */
if (TEST_BIT (pre_delete_map[bb->index], indx)
- && (set = single_set (insn)) != 0)
+ && (set = single_set (insn)) != 0
+ && dbg_cnt (pre_insn))
{
/* Create a pseudo-reg to store the result of reaching
expressions into. Get the mode for the new pseudo from
@@ -4515,7 +4525,6 @@ pre_gcse (void)
- we know which insns are redundant when we go to create copies */
changed = pre_delete ();
-
did_insert = pre_edge_insert (edge_list, index_map);
/* In other places with reaching expressions, copy the expression to the
@@ -4966,7 +4975,7 @@ hoist_code (void)
occr->deleted_p = 1;
if (!insn_inserted_p)
{
- insert_insn_end_bb (index_map[i], bb, 0);
+ insert_insn_end_basic_block (index_map[i], bb, 0);
insn_inserted_p = 1;
}
}
@@ -5437,6 +5446,7 @@ update_ld_motion_stores (struct expr * expr)
new = emit_insn_before (copy, insn);
record_one_set (REGNO (reg), new);
SET_SRC (pat) = reg;
+ df_insn_rescan (insn);
/* un-recognize this pattern since it's probably different now. */
INSN_CODE (insn) = -1;
@@ -5553,8 +5563,10 @@ extract_mentioned_regs_helper (rtx x, rtx accum)
case PRE_DEC:
case PRE_INC:
+ case PRE_MODIFY:
case POST_DEC:
case POST_INC:
+ case POST_MODIFY:
/* We do not run this function with arguments having side effects. */
gcc_unreachable ();
@@ -6148,7 +6160,7 @@ build_store_vectors (void)
the BB_HEAD if needed. */
static void
-insert_insn_start_bb (rtx insn, basic_block bb)
+insert_insn_start_basic_block (rtx insn, basic_block bb)
{
/* Insert at start of successor block. */
rtx prev = PREV_INSN (BB_HEAD (bb));
@@ -6164,7 +6176,7 @@ insert_insn_start_bb (rtx insn, basic_block bb)
before = NEXT_INSN (before);
}
- insn = emit_insn_after_noloc (insn, prev);
+ insn = emit_insn_after_noloc (insn, prev, bb);
if (dump_file)
{
@@ -6221,7 +6233,7 @@ insert_store (struct ls_expr * expr, edge e)
int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest);
RESET_BIT (pre_insert_map[index], expr->index);
}
- insert_insn_start_bb (insn, bb);
+ insert_insn_start_basic_block (insn, bb);
return 0;
}
@@ -6590,7 +6602,6 @@ bypass_jumps (void)
/* We are finished with alias. */
end_alias_analysis ();
- allocate_reg_info (max_reg_num (), FALSE, FALSE);
return changed;
}
@@ -6645,14 +6656,12 @@ gate_handle_jump_bypass (void)
static unsigned int
rest_of_handle_jump_bypass (void)
{
- cleanup_cfg (CLEANUP_EXPENSIVE);
- reg_scan (get_insns (), max_reg_num ());
-
+ delete_unreachable_blocks ();
if (bypass_jumps ())
{
- rebuild_jump_labels (get_insns ());
- cleanup_cfg (CLEANUP_EXPENSIVE);
delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ rebuild_jump_labels (get_insns ());
+ cleanup_cfg (0);
}
return 0;
}
@@ -6688,11 +6697,9 @@ rest_of_handle_gcse (void)
{
int save_csb, save_cfj;
int tem2 = 0, tem;
-
tem = gcse_main (get_insns ());
- rebuild_jump_labels (get_insns ());
delete_trivially_dead_insns (get_insns (), max_reg_num ());
-
+ rebuild_jump_labels (get_insns ());
save_csb = flag_cse_skip_blocks;
save_cfj = flag_cse_follow_jumps;
flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
@@ -6702,7 +6709,6 @@ rest_of_handle_gcse (void)
if (flag_expensive_optimizations)
{
timevar_push (TV_CSE);
- reg_scan (get_insns (), max_reg_num ());
tem2 = cse_main (get_insns (), max_reg_num ());
purge_all_dead_edges ();
delete_trivially_dead_insns (get_insns (), max_reg_num ());
@@ -6716,8 +6722,7 @@ rest_of_handle_gcse (void)
{
timevar_push (TV_JUMP);
rebuild_jump_labels (get_insns ());
- delete_dead_jumptables ();
- cleanup_cfg (CLEANUP_EXPENSIVE);
+ cleanup_cfg (0);
timevar_pop (TV_JUMP);
}
@@ -6739,6 +6744,7 @@ struct tree_opt_pass pass_gcse =
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
+ TODO_df_finish |
TODO_dump_func |
TODO_verify_flow | TODO_ggc_collect, /* todo_flags_finish */
'G' /* letter */