/* If current bb has only one successor, then consider it as an
unconditional goto. */
- if (bb->succ && !bb->succ->succ_next)
+ if (EDGE_COUNT (bb->succs) == 1)
{
- basic_block bb_n = bb->succ->dest;
+ basic_block bb_n = EDGE_SUCC (bb, 0)->dest;
if (cond != NULL_TREE)
add_to_predicate_list (bb_n, cond);
cond = NULL_TREE;
else_clause = TREE_OPERAND (stmt, 2);
/* Create temp. for condition. */
- if (!is_gimple_reg (c))
+ if (!is_gimple_condexpr (c))
{
tree new_stmt;
new_stmt = ifc_temp_var (TREE_TYPE (c), unshare_expr (c));
/* Add new condition into destination's predicate list. */
if (then_clause)
/* if 'c' is true then then_clause is reached. */
- new_cond = add_to_dst_predicate_list (loop, then_clause, cond, c, bsi);
+ new_cond = add_to_dst_predicate_list (loop, then_clause, cond,
+ unshare_expr (c), bsi);
if (else_clause)
{
+ tree c2;
+ if (!is_gimple_reg(c) && is_gimple_condexpr (c))
+ {
+ tree new_stmt;
+ new_stmt = ifc_temp_var (TREE_TYPE (c), unshare_expr (c));
+ bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
+ c = TREE_OPERAND (new_stmt, 0);
+ }
+
/* if 'c' is false then else_clause is reached. */
- tree c2 = build1 (TRUTH_NOT_EXPR,
- boolean_type_node,
- unshare_expr (c));
+ c2 = invert_truthvalue (unshare_expr (c));
add_to_dst_predicate_list (loop, else_clause, cond, c2, bsi);
}
bsi_remove (bsi);
cond = NULL_TREE;
}
- else if (new_cond != NULL_TREE)
- {
- TREE_OPERAND (stmt, 0) = new_cond;
- modify_stmt (stmt);
- }
return;
}
if_convertable_bb_p (struct loop *loop, basic_block bb, bool exit_bb_seen)
{
edge e;
+ edge_iterator ei;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "----------[%d]-------------\n", bb->index);
}
/* Be less adventurous and handle only normal edges. */
- for (e = bb->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, bb->succs)
if (e->flags &
(EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP))
{
block_stmt_iterator itr;
unsigned int i;
edge e;
+ edge_iterator ei;
bool exit_bb_seen = false;
/* Handle only inner most loop. */
/* If one of the loop header's edge is exit edge then do not apply
if-conversion. */
- for (e = loop->header->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, loop->header->succs)
if ( e->flags & EDGE_LOOP_EXIT)
return false;
basic_block p2 = NULL;
basic_block true_bb = NULL;
tree tmp_cond;
+ edge_iterator ei;
- for (e = bb->pred; e; e = e->pred_next)
+ FOR_EACH_EDGE (e, ei, bb->preds)
{
if (p1 == NULL)
- p1 = e->src;
+ p1 = e->src;
else
{
gcc_assert (!p2);
if (bb == exit_bb)
{
edge new_e;
+ edge_iterator ei;
/* Connect this node with loop header. */
new_e = make_edge (ifc_bbs[0], bb, EDGE_FALLTHRU);
if (exit_bb != loop->latch)
{
/* Redirect non-exit edge to loop->latch. */
- for (e = bb->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, bb->succs)
if (!(e->flags & EDGE_LOOP_EXIT))
{
redirect_edge_and_branch (e, loop->latch);
}
/* It is time to remove this basic block. First remove edges. */
- while (bb->succ != NULL)
- ssa_remove_edge (bb->succ);
- while (bb->pred != NULL)
- ssa_remove_edge (bb->pred);
+ while (EDGE_COUNT (bb->succs) > 0)
+ ssa_remove_edge (EDGE_SUCC (bb, 0));
+ while (EDGE_COUNT (bb->preds) > 0)
+ ssa_remove_edge (EDGE_PRED (bb, 0));
/* Remove labels and make stmts member of loop->header. */
for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
remove_bb_from_loops (bb);
expunge_block (bb);
}
+
+ /* Now if possible, merge loop header and block with exit edge.
+ This reduces number of basic blocks to 2. Auto vectorizer addresses
+ loops with two nodes only. FIXME: Use cleanup_tree_cfg(). */
+ if (exit_bb != loop->latch && empty_block_p (loop->latch))
+ {
+ if (can_merge_blocks_p (loop->header, exit_bb))
+ {
+ remove_bb_from_loops (exit_bb);
+ merge_blocks (loop->header, exit_bb);
+ }
+ }
}
/* Make new temp variable of type TYPE. Add MODIFY_EXPR to assign EXP
pred_blocks_visited_p (basic_block bb, bitmap *visited)
{
edge e;
- for (e = bb->pred; e; e = e->pred_next)
+ edge_iterator ei;
+ FOR_EACH_EDGE (e, ei, bb->preds)
if (!bitmap_bit_p (*visited, e->src->index))
return false;
bb_with_exit_edge_p (basic_block bb)
{
edge e;
+ edge_iterator ei;
bool exit_edge_found = false;
- for (e = bb->succ; e && !exit_edge_found ; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, bb->succs)
if (e->flags & EDGE_LOOP_EXIT)
- exit_edge_found = true;
+ {
+ exit_edge_found = true;
+ break;
+ }
return exit_edge_found;
}