diff options
author | Jeff Law <law@redhat.com> | 2011-03-28 12:33:42 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2011-03-28 12:33:42 -0600 |
commit | 520af9ec9a673351b046e06e91d8f66fa70341d2 (patch) | |
tree | 6f6e281ff34d399c1d3ec13acccdbbca92243795 /gcc/tree-ssa-threadupdate.c | |
parent | 80ec23acbd7c94b82afc2e53506d5bfa2a049fe8 (diff) | |
download | gcc-520af9ec9a673351b046e06e91d8f66fa70341d2.zip gcc-520af9ec9a673351b046e06e91d8f66fa70341d2.tar.gz gcc-520af9ec9a673351b046e06e91d8f66fa70341d2.tar.bz2 |
tree-ssa-threadupdate.c (redirect_edges): Call create_edge_and_update_destination_phis as needed.
* tree-ssa-threadupdate.c (redirect_edges): Call
create_edge_and_update_destination_phis as needed.
(create_edge_and_update_destination_phis): Accept new BB argument.
All callers updated.
(thread_block): Do not update the profile when threading around
intermediate blocks.
(thread_single_edge): Likewise.
(determine_bb_domination_status): If BB is not a successor of the
loop header, return NONDOMINATING.
(register_jump_thread): Note when we register a jump thread around
an intermediate block.
* tree-ssa-threadedge.c (thread_around_empty_block): New function.
(thread_across_edge): Use it.
* gcc.dg/tree-ssa/ssa-dom-thread-3.c: New test.
From-SVN: r171622
Diffstat (limited to 'gcc/tree-ssa-threadupdate.c')
-rw-r--r-- | gcc/tree-ssa-threadupdate.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index 951f47e..efbc5ec 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -304,14 +304,15 @@ lookup_redirection_data (edge e, edge incoming_edge, enum insert_option insert) destination. */ static void -create_edge_and_update_destination_phis (struct redirection_data *rd) +create_edge_and_update_destination_phis (struct redirection_data *rd, + basic_block bb) { - edge e = make_edge (rd->dup_block, rd->outgoing_edge->dest, EDGE_FALLTHRU); + edge e = make_edge (bb, rd->outgoing_edge->dest, EDGE_FALLTHRU); gimple_stmt_iterator gsi; rescan_loop_exit (e, true, false); e->probability = REG_BR_PROB_BASE; - e->count = rd->dup_block->count; + e->count = bb->count; e->aux = rd->outgoing_edge->aux; /* If there are any PHI nodes at the destination of the outgoing edge @@ -359,7 +360,7 @@ create_duplicates (void **slot, void *data) /* Go ahead and wire up outgoing edges and update PHIs for the duplicate block. */ - create_edge_and_update_destination_phis (rd); + create_edge_and_update_destination_phis (rd, rd->dup_block); } /* Keep walking the hash table. */ @@ -380,7 +381,7 @@ fixup_template_block (void **slot, void *data) and halt the hash table traversal. */ if (rd->dup_block && rd->dup_block == local_info->template_block) { - create_edge_and_update_destination_phis (rd); + create_edge_and_update_destination_phis (rd, rd->dup_block); return 0; } @@ -443,6 +444,11 @@ redirect_edges (void **slot, void *data) remove_ctrl_stmt_and_useless_edges (local_info->bb, rd->outgoing_edge->dest); + /* If we are threading beyond the immediate successors of + the duplicate, then BB will have no edges, create one. */ + if (EDGE_COUNT (local_info->bb->succs) == 0) + create_edge_and_update_destination_phis (rd, local_info->bb); + /* Fixup the flags on the single remaining edge. */ single_succ_edge (local_info->bb)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE | EDGE_ABNORMAL); @@ -565,8 +571,9 @@ thread_block (basic_block bb, bool noloop_only) continue; } - update_bb_profile_for_threading (e->dest, EDGE_FREQUENCY (e), - e->count, (edge) e->aux); + if (e->dest == e2->src) + update_bb_profile_for_threading (e->dest, EDGE_FREQUENCY (e), + e->count, (edge) e->aux); /* Insert the outgoing edge into the hash table if it is not already in the hash table. */ @@ -650,12 +657,13 @@ thread_single_edge (edge e) } /* Otherwise, we need to create a copy. */ - update_bb_profile_for_threading (bb, EDGE_FREQUENCY (e), e->count, eto); + if (e->dest == eto->src) + update_bb_profile_for_threading (bb, EDGE_FREQUENCY (e), e->count, eto); rd.outgoing_edge = eto; create_block_for_threading (bb, &rd); - create_edge_and_update_destination_phis (&rd); + create_edge_and_update_destination_phis (&rd, rd.dup_block); if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, " Threaded jump %d --> %d to %d\n", @@ -704,7 +712,9 @@ determine_bb_domination_status (struct loop *loop, basic_block bb) edge e; #ifdef ENABLE_CHECKING - /* This function assumes BB is a successor of LOOP->header. */ + /* This function assumes BB is a successor of LOOP->header. + If that is not the case return DOMST_NONDOMINATING which + is always safe. */ { bool ok = false; @@ -717,7 +727,8 @@ determine_bb_domination_status (struct loop *loop, basic_block bb) } } - gcc_assert (ok); + if (!ok) + return DOMST_NONDOMINATING; } #endif @@ -1099,6 +1110,11 @@ register_jump_thread (edge e, edge e2) if (threaded_edges == NULL) threaded_edges = VEC_alloc (edge, heap, 10); + if (dump_file && (dump_flags & TDF_DETAILS) + && e->dest != e2->src) + fprintf (dump_file, + " Registering jump thread around one or more intermediate blocks\n"); + VEC_safe_push (edge, heap, threaded_edges, e); VEC_safe_push (edge, heap, threaded_edges, e2); } |