mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-03 05:08:14 +00:00
Manually short circuit in lb_build_if_stmt for constant conditions
This commit is contained in:
+52
-10
@@ -5486,6 +5486,7 @@ void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results) {
|
|||||||
void lb_build_if_stmt(lbProcedure *p, Ast *node) {
|
void lb_build_if_stmt(lbProcedure *p, Ast *node) {
|
||||||
ast_node(is, IfStmt, node);
|
ast_node(is, IfStmt, node);
|
||||||
lb_open_scope(p, node->scope); // Scope #1
|
lb_open_scope(p, node->scope); // Scope #1
|
||||||
|
defer (lb_close_scope(p, lbDeferExit_Default, nullptr));
|
||||||
|
|
||||||
if (is->init != nullptr) {
|
if (is->init != nullptr) {
|
||||||
// TODO(bill): Should this have a separate block to begin with?
|
// TODO(bill): Should this have a separate block to begin with?
|
||||||
@@ -5503,30 +5504,67 @@ void lb_build_if_stmt(lbProcedure *p, Ast *node) {
|
|||||||
else_ = lb_create_block(p, "if.else");
|
else_ = lb_create_block(p, "if.else");
|
||||||
}
|
}
|
||||||
|
|
||||||
lb_build_cond(p, is->cond, then, else_);
|
lbValue cond = lb_build_cond(p, is->cond, then, else_);
|
||||||
lb_start_block(p, then);
|
|
||||||
|
|
||||||
if (is->label != nullptr) {
|
if (is->label != nullptr) {
|
||||||
lbTargetList *tl = lb_push_target_list(p, is->label, done, nullptr, nullptr);
|
lbTargetList *tl = lb_push_target_list(p, is->label, done, nullptr, nullptr);
|
||||||
tl->is_block = true;
|
tl->is_block = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
lb_build_stmt(p, is->body);
|
if (LLVMIsConstant(cond.value)) {
|
||||||
|
// NOTE(bill): Do a compile time short circuit for when the condition is constantly known.
|
||||||
|
// This done manually rather than relying on the SSA passes because sometimes the SSA passes
|
||||||
|
// miss some even if they are constantly known, especially with few optimization passes.
|
||||||
|
|
||||||
lb_emit_jump(p, done);
|
bool const_cond = LLVMConstIntGetZExtValue(cond.value) != 0;
|
||||||
|
|
||||||
if (is->else_stmt != nullptr) {
|
LLVMValueRef if_instr = LLVMGetLastInstruction(p->curr_block->block);
|
||||||
lb_start_block(p, else_);
|
GB_ASSERT(LLVMGetInstructionOpcode(if_instr) == LLVMBr);
|
||||||
|
GB_ASSERT(LLVMIsConditional(if_instr));
|
||||||
|
LLVMInstructionEraseFromParent(if_instr);
|
||||||
|
|
||||||
lb_open_scope(p, is->else_stmt->scope);
|
|
||||||
lb_build_stmt(p, is->else_stmt);
|
if (const_cond) {
|
||||||
lb_close_scope(p, lbDeferExit_Default, nullptr);
|
lb_emit_jump(p, then);
|
||||||
|
lb_start_block(p, then);
|
||||||
|
|
||||||
|
lb_build_stmt(p, is->body);
|
||||||
|
lb_emit_jump(p, done);
|
||||||
|
} else {
|
||||||
|
if (is->else_stmt != nullptr) {
|
||||||
|
lb_emit_jump(p, else_);
|
||||||
|
lb_start_block(p, else_);
|
||||||
|
|
||||||
|
lb_open_scope(p, is->else_stmt->scope);
|
||||||
|
lb_build_stmt(p, is->else_stmt);
|
||||||
|
lb_close_scope(p, lbDeferExit_Default, nullptr);
|
||||||
|
}
|
||||||
|
lb_emit_jump(p, done);
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lb_start_block(p, then);
|
||||||
|
|
||||||
|
lb_build_stmt(p, is->body);
|
||||||
|
|
||||||
lb_emit_jump(p, done);
|
lb_emit_jump(p, done);
|
||||||
|
|
||||||
|
if (is->else_stmt != nullptr) {
|
||||||
|
lb_start_block(p, else_);
|
||||||
|
|
||||||
|
lb_open_scope(p, is->else_stmt->scope);
|
||||||
|
lb_build_stmt(p, is->else_stmt);
|
||||||
|
lb_close_scope(p, lbDeferExit_Default, nullptr);
|
||||||
|
|
||||||
|
lb_emit_jump(p, done);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is->label != nullptr) {
|
||||||
|
lb_pop_target_list(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
lb_start_block(p, done);
|
lb_start_block(p, done);
|
||||||
lb_close_scope(p, lbDeferExit_Default, nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lb_build_for_stmt(lbProcedure *p, Ast *node) {
|
void lb_build_for_stmt(lbProcedure *p, Ast *node) {
|
||||||
@@ -5842,6 +5880,10 @@ void lb_build_stmt(lbProcedure *p, Ast *node) {
|
|||||||
lb_emit_jump(p, done);
|
lb_emit_jump(p, done);
|
||||||
lb_start_block(p, done);
|
lb_start_block(p, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bs->label != nullptr) {
|
||||||
|
lb_pop_target_list(p);
|
||||||
|
}
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(vd, ValueDecl, node);
|
case_ast_node(vd, ValueDecl, node);
|
||||||
|
|||||||
Reference in New Issue
Block a user