static bool if_convertible_phi_p (struct loop *, basic_block, tree);
static bool if_convertible_modify_expr_p (struct loop *, basic_block, tree);
static bool if_convertible_stmt_p (struct loop *, basic_block, tree);
-static bool if_convertible_bb_p (struct loop *, basic_block, bool);
+static bool if_convertible_bb_p (struct loop *, basic_block, basic_block);
static bool if_convertible_loop_p (struct loop *, bool);
static void add_to_predicate_list (basic_block, tree);
static tree add_to_dst_predicate_list (struct loop * loop, basic_block, tree, tree,
BB is inside loop LOOP. */
static bool
-if_convertible_bb_p (struct loop *loop, basic_block bb, bool exit_bb_seen)
+if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb)
{
edge e;
edge_iterator ei;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "----------[%d]-------------\n", bb->index);
- if (exit_bb_seen)
+ if (exit_bb)
{
if (bb != loop->latch)
{
fprintf (dump_file, "non empty basic block after exit bb\n");
return false;
}
+ else if (bb == loop->latch
+ && bb != exit_bb
+ && !dominated_by_p (CDI_DOMINATORS, bb, exit_bb))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "latch is not dominated by exit_block\n");
+ return false;
+ }
}
/* Be less adventurous and handle only normal edges. */
unsigned int i;
edge e;
edge_iterator ei;
- bool exit_bb_seen = false;
+ basic_block exit_bb = NULL;
/* Handle only inner most loop. */
if (!loop || loop->inner)
{
bb = ifc_bbs[i];
- if (!if_convertible_bb_p (loop, bb, exit_bb_seen))
+ if (!if_convertible_bb_p (loop, bb, exit_bb))
return false;
/* Check statements. */
return false;
if (bb_with_exit_edge_p (loop, bb))
- exit_bb_seen = true;
+ exit_bb = bb;
}
/* OK. Did not find any potential issues so go ahead in if-convert