case OMP_SECTIONS:
cur_region = new_omp_region (bb, code, cur_region);
+ fallthru = true;
+ break;
+
+ case OMP_SECTIONS_SWITCH:
fallthru = false;
break;
switch (cur_region->type)
{
case OMP_FOR:
- /* ??? Technically there should be a some sort of loopback
- edge here, but it goes to a block that doesn't exist yet,
- and without it, updating the ssa form would be a real
- bear. Fortunately, we don't yet do ssa before expanding
- these nodes. */
+ /* Make the loopback edge. */
+ make_edge (bb, single_succ (cur_region->entry), 0);
+
+ /* Create an edge from OMP_FOR to exit, which corresponds to
+ the case that the body of the loop is not executed at
+ all. */
+ make_edge (cur_region->entry, bb->next_bb, 0);
+ fallthru = true;
break;
case OMP_SECTIONS:
/* Wire up the edges into and out of the nested sections. */
- /* ??? Similarly wrt loopback. */
{
+ basic_block switch_bb = single_succ (cur_region->entry);
+
struct omp_region *i;
for (i = cur_region->inner; i ; i = i->next)
{
gcc_assert (i->type == OMP_SECTION);
- make_edge (cur_region->entry, i->entry, 0);
+ make_edge (switch_bb, i->entry, 0);
make_edge (i->exit, bb, EDGE_FALLTHRU);
}
+
+ /* Make the loopback edge to the block with
+ OMP_SECTIONS_SWITCH. */
+ make_edge (bb, switch_bb, 0);
+
+ /* Make the edge from the switch to exit. */
+ make_edge (switch_bb, bb->next_bb, 0);
+ fallthru = false;
}
break;
default:
gcc_unreachable ();
}
- fallthru = true;
break;
default:
/* In case we maintain loop closed ssa form, do not propagate arguments
of loop exit phi nodes. */
if (current_loops
- && (current_loops->state & LOOP_CLOSED_SSA)
+ && loops_state_satisfies_p (LOOP_CLOSED_SSA)
&& is_gimple_reg (def)
&& TREE_CODE (use) == SSA_NAME
&& a->loop_father != b->loop_father)
return !bsi_end_p (i) ? bsi_stmt (i) : NULL_TREE;
}
+const_tree
+const_first_stmt (const_basic_block bb)
+{
+ const_block_stmt_iterator i = cbsi_start (bb);
+ return !cbsi_end_p (i) ? cbsi_stmt (i) : NULL_TREE;
+}
/* Return the last statement in basic block BB. */
return !bsi_end_p (b) ? bsi_stmt (b) : NULL_TREE;
}
+const_tree
+const_last_stmt (const_basic_block bb)
+{
+ const_block_stmt_iterator b = cbsi_last (bb);
+ return !cbsi_end_p (b) ? cbsi_stmt (b) : NULL_TREE;
+}
/* Return the last statement of an otherwise empty block. Return NULL
if the block is totally empty, or if it contains more than one
if there is an error, otherwise false. */
static bool
-verify_gimple_unary_expr (tree expr)
+verify_gimple_unary_expr (const_tree expr)
{
tree op = TREE_OPERAND (expr, 0);
tree type = TREE_TYPE (expr);
if there is an error, otherwise false. */
static bool
-verify_gimple_binary_expr (tree expr)
+verify_gimple_binary_expr (const_tree expr)
{
tree op0 = TREE_OPERAND (expr, 0);
tree op1 = TREE_OPERAND (expr, 1);
is an error, otherwise false. */
static bool
-verify_gimple_modify_stmt (tree stmt)
+verify_gimple_modify_stmt (const_tree stmt)
{
tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
e->flags |= EDGE_FALLTHRU;
break;
+ case OMP_RETURN:
+ case OMP_CONTINUE:
+ case OMP_SECTIONS_SWITCH:
+ case OMP_FOR:
+ /* The edges from OMP constructs can be simply redirected. */
+ break;
+
default:
/* Otherwise it must be a fallthru edge, and we don't need to
do anything besides redirecting it. */