summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChristoph Mallon <christoph.mallon@gmx.de>2012-10-18 11:09:27 +0200
committerChristoph Mallon <christoph.mallon@gmx.de>2012-10-19 09:32:36 +0200
commit06e304a5b4dd5f5fd0d0a1c5f89e1d996443a103 (patch)
tree8e27e5935e3a8f473d50ae2b88fb1f4a35df1d96
parent5b6ebacc63c6a3f3fed7dd80b76008e663bbfdf4 (diff)
Avoid an unnecessary basic block in case of do ... while (0);.
-rw-r--r--ast2firm.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/ast2firm.c b/ast2firm.c
index 7f0e78b..1447635 100644
--- a/ast2firm.c
+++ b/ast2firm.c
@@ -4542,30 +4542,36 @@ static ir_node *do_while_statement_to_firm(do_while_statement_t *statement)
/* create the header block */
ir_node *header_block = new_immBlock();
- /* the loop body */
- ir_node *body_block = new_immBlock();
- jump_to(body_block);
-
PUSH_BREAK(NULL);
PUSH_CONTINUE(header_block);
+ /* The loop body. */
+ ir_node *body_block = NULL;
+ expression_t *const cond = statement->condition;
+ /* Avoid an explicit body block in case of do ... while (0);. */
+ if (is_constant_expression(cond) != EXPR_CLASS_CONSTANT || fold_constant_to_bool(cond)) {
+ /* Not do ... while (0);. */
+ body_block = new_immBlock();
+ jump_to(body_block);
+ }
statement_to_firm(statement->body);
- ir_node *const false_block = get_break_label();
-
- POP_CONTINUE();
- POP_BREAK();
-
- jump_if_reachable(header_block);
/* create the condition */
+ jump_if_reachable(header_block);
mature_immBlock(header_block);
set_cur_block(header_block);
-
- create_condition_evaluation(statement->condition, body_block, false_block);
- mature_immBlock(body_block);
+ ir_node *const false_block = get_break_label();
+ if (body_block) {
+ create_condition_evaluation(statement->condition, body_block, false_block);
+ mature_immBlock(body_block);
+ } else {
+ jump_if_reachable(false_block);
+ }
mature_immBlock(false_block);
-
set_cur_block(false_block);
+
+ POP_CONTINUE();
+ POP_BREAK();
return NULL;
}