Commit 27d93d2c by Jason Merrill Committed by Jason Merrill

cp-gimplify.c (genericize_cp_loop): Use LOOP_EXPR.

	* cp-gimplify.c (genericize_cp_loop): Use LOOP_EXPR.
	(genericize_for_stmt): Handle null statement-list.

From-SVN: r217669
parent b065b669
2014-11-17 Jason Merrill <jason@redhat.com> 2014-11-17 Jason Merrill <jason@redhat.com>
* cp-gimplify.c (genericize_cp_loop): Use LOOP_EXPR.
(genericize_for_stmt): Handle null statement-list.
* constexpr.c (use_new_call): Always use new call handling. * constexpr.c (use_new_call): Always use new call handling.
C++14 constexpr support (minus loops and multiple returns) C++14 constexpr support (minus loops and multiple returns)
......
...@@ -208,7 +208,7 @@ genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body, ...@@ -208,7 +208,7 @@ genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
void *data) void *data)
{ {
tree blab, clab; tree blab, clab;
tree entry = NULL, exit = NULL, t; tree exit = NULL;
tree stmt_list = NULL; tree stmt_list = NULL;
blab = begin_bc_block (bc_break, start_locus); blab = begin_bc_block (bc_break, start_locus);
...@@ -222,64 +222,46 @@ genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body, ...@@ -222,64 +222,46 @@ genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
cp_walk_tree (&incr, cp_genericize_r, data, NULL); cp_walk_tree (&incr, cp_genericize_r, data, NULL);
*walk_subtrees = 0; *walk_subtrees = 0;
/* If condition is zero don't generate a loop construct. */ if (cond && TREE_CODE (cond) != INTEGER_CST)
if (cond && integer_zerop (cond))
{
if (cond_is_first)
{ {
t = build1_loc (start_locus, GOTO_EXPR, void_type_node, /* If COND is constant, don't bother building an exit. If it's false,
we won't build a loop. If it's true, any exits are in the body. */
location_t cloc = EXPR_LOC_OR_LOC (cond, start_locus);
exit = build1_loc (cloc, GOTO_EXPR, void_type_node,
get_bc_label (bc_break)); get_bc_label (bc_break));
append_to_statement_list (t, &stmt_list); exit = fold_build3_loc (cloc, COND_EXPR, void_type_node, cond,
} build_empty_stmt (cloc), exit);
} }
else
{
/* Expand to gotos, just like c_finish_loop. TODO: Use LOOP_EXPR. */
tree top = build1 (LABEL_EXPR, void_type_node,
create_artificial_label (start_locus));
/* If we have an exit condition, then we build an IF with gotos either if (exit && cond_is_first)
out of the loop, or to the top of it. If there's no exit condition, append_to_statement_list (exit, &stmt_list);
then we just build a jump back to the top. */ append_to_statement_list (body, &stmt_list);
exit = build1 (GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL (top)); finish_bc_block (&stmt_list, bc_continue, clab);
append_to_statement_list (incr, &stmt_list);
if (exit && !cond_is_first)
append_to_statement_list (exit, &stmt_list);
if (!stmt_list)
stmt_list = build_empty_stmt (start_locus);
if (cond && !integer_nonzerop (cond)) tree loop;
if (cond && integer_zerop (cond))
{ {
/* Canonicalize the loop condition to the end. This means
generating a branch to the loop condition. Reuse the
continue label, if possible. */
if (cond_is_first) if (cond_is_first)
{ loop = fold_build3_loc (start_locus, COND_EXPR,
if (incr) void_type_node, cond, stmt_list,
{ build_empty_stmt (start_locus));
entry = build1 (LABEL_EXPR, void_type_node,
create_artificial_label (start_locus));
t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
LABEL_EXPR_LABEL (entry));
}
else else
t = build1_loc (start_locus, GOTO_EXPR, void_type_node, loop = stmt_list;
get_bc_label (bc_continue));
append_to_statement_list (t, &stmt_list);
}
t = build1 (GOTO_EXPR, void_type_node, get_bc_label (bc_break));
exit = fold_build3_loc (start_locus,
COND_EXPR, void_type_node, cond, exit, t);
}
append_to_statement_list (top, &stmt_list);
} }
else
loop = build1_loc (start_locus, LOOP_EXPR, void_type_node, stmt_list);
append_to_statement_list (body, &stmt_list); stmt_list = NULL;
finish_bc_block (&stmt_list, bc_continue, clab); append_to_statement_list (loop, &stmt_list);
append_to_statement_list (incr, &stmt_list);
append_to_statement_list (entry, &stmt_list);
append_to_statement_list (exit, &stmt_list);
finish_bc_block (&stmt_list, bc_break, blab); finish_bc_block (&stmt_list, bc_break, blab);
if (!stmt_list)
if (stmt_list == NULL_TREE) stmt_list = build_empty_stmt (start_locus);
stmt_list = build1 (NOP_EXPR, void_type_node, integer_zero_node);
*stmt_p = stmt_list; *stmt_p = stmt_list;
} }
...@@ -303,6 +285,8 @@ genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data) ...@@ -303,6 +285,8 @@ genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data)
genericize_cp_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt), genericize_cp_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees, data); FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees, data);
append_to_statement_list (loop, &expr); append_to_statement_list (loop, &expr);
if (expr == NULL_TREE)
expr = loop;
*stmt_p = expr; *stmt_p = expr;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment