aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-01-06 18:02:42 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-01-06 18:02:42 -0700
commitc75d40680ff8a143b9298968a3ca3053dea2e460 (patch)
tree1d54def2a7dd431805db19debe07eb983bedd5db /src/codegen.cpp
parent5f0bfcac24036e1fff0b2beda643a60dad465213 (diff)
downloadzig-c75d40680ff8a143b9298968a3ca3053dea2e460.tar.gz
zig-c75d40680ff8a143b9298968a3ca3053dea2e460.zip
while detects simple constant condition
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp61
1 files changed, 42 insertions, 19 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 3e555a5778..3f4262364e 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -1157,29 +1157,52 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) {
assert(node->data.while_expr.condition);
assert(node->data.while_expr.body);
- LLVMBasicBlockRef cond_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileCond");
- LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileBody");
- LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileEnd");
+ if (get_expr_type(node)->id == TypeTableEntryIdUnreachable) {
+ // generate a forever loop. guarantees no break statements
- add_debug_source_node(g, node);
- LLVMBuildBr(g->builder, cond_block);
-
- LLVMPositionBuilderAtEnd(g->builder, cond_block);
- LLVMValueRef cond_val = gen_expr(g, node->data.while_expr.condition);
- add_debug_source_node(g, node->data.while_expr.condition);
- LLVMBuildCondBr(g->builder, cond_val, body_block, end_block);
-
- LLVMPositionBuilderAtEnd(g->builder, body_block);
- g->break_block_stack.append(end_block);
- g->continue_block_stack.append(cond_block);
- gen_expr(g, node->data.while_expr.body);
- g->break_block_stack.pop();
- g->continue_block_stack.pop();
- if (get_expr_type(node->data.while_expr.body)->id != TypeTableEntryIdUnreachable) {
+ LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileBody");
+
+ add_debug_source_node(g, node);
+ LLVMBuildBr(g->builder, body_block);
+
+ LLVMPositionBuilderAtEnd(g->builder, body_block);
+ g->continue_block_stack.append(body_block);
+ gen_expr(g, node->data.while_expr.body);
+ g->continue_block_stack.pop();
+
+ if (get_expr_type(node->data.while_expr.body)->id != TypeTableEntryIdUnreachable) {
+ add_debug_source_node(g, node);
+ LLVMBuildBr(g->builder, body_block);
+ }
+ } else {
+ // generate a normal while loop
+
+ LLVMBasicBlockRef cond_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileCond");
+ LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileBody");
+ LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileEnd");
+
+ add_debug_source_node(g, node);
LLVMBuildBr(g->builder, cond_block);
+
+ LLVMPositionBuilderAtEnd(g->builder, cond_block);
+ LLVMValueRef cond_val = gen_expr(g, node->data.while_expr.condition);
+ add_debug_source_node(g, node->data.while_expr.condition);
+ LLVMBuildCondBr(g->builder, cond_val, body_block, end_block);
+
+ LLVMPositionBuilderAtEnd(g->builder, body_block);
+ g->break_block_stack.append(end_block);
+ g->continue_block_stack.append(cond_block);
+ gen_expr(g, node->data.while_expr.body);
+ g->break_block_stack.pop();
+ g->continue_block_stack.pop();
+ if (get_expr_type(node->data.while_expr.body)->id != TypeTableEntryIdUnreachable) {
+ add_debug_source_node(g, node);
+ LLVMBuildBr(g->builder, cond_block);
+ }
+
+ LLVMPositionBuilderAtEnd(g->builder, end_block);
}
- LLVMPositionBuilderAtEnd(g->builder, end_block);
return nullptr;
}