diff options
| author | gingerBill <bill@gingerbill.org> | 2021-05-24 22:09:21 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-05-24 22:09:21 +0100 |
| commit | 3f156bcb4b4d428c9d8547d63de145f01080d043 (patch) | |
| tree | 4b4cb2574d3f065c8a8d0b2d73240b086c1a45be /src/llvm_backend.cpp | |
| parent | d35a9e65b68e9d38f470c3cf0e54909e08d7bde8 (diff) | |
Refactor backend code for assignments; Refactor some statements into separate procedures
Diffstat (limited to 'src/llvm_backend.cpp')
| -rw-r--r-- | src/llvm_backend.cpp | 734 |
1 files changed, 335 insertions, 399 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index bc519f70d..9121bc083 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -4425,7 +4425,7 @@ void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *scope) { lb_start_block(p, done); } -void lb_build_inline_range_stmt(lbProcedure *p, AstUnrollRangeStmt *rs, Scope *scope) { +void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt *rs, Scope *scope) { lbModule *m = p->module; lb_open_scope(p, scope); // Open scope here @@ -4943,6 +4943,321 @@ void lb_reset_copy_elision_hint(lbProcedure *p, lbCopyElisionHint prev_hint) { p->copy_elision_hint = prev_hint; } +void lb_build_static_variables(lbProcedure *p, AstValueDecl *vd) { + for_array(i, vd->names) { + lbValue value = {}; + if (vd->values.count > 0) { + GB_ASSERT(vd->names.count == vd->values.count); + Ast *ast_value = vd->values[i]; + GB_ASSERT(ast_value->tav.mode == Addressing_Constant || + ast_value->tav.mode == Addressing_Invalid); + + bool allow_local = false; + value = lb_const_value(p->module, ast_value->tav.type, ast_value->tav.value, allow_local); + } + + Ast *ident = vd->names[i]; + GB_ASSERT(!is_blank_ident(ident)); + Entity *e = entity_of_node(ident); + GB_ASSERT(e->flags & EntityFlag_Static); + String name = e->token.string; + + String mangled_name = {}; + { + gbString str = gb_string_make_length(permanent_allocator(), p->name.text, p->name.len); + str = gb_string_appendc(str, "-"); + str = gb_string_append_fmt(str, ".%.*s-%llu", LIT(name), cast(long long)e->id); + mangled_name.text = cast(u8 *)str; + mangled_name.len = gb_string_length(str); + } + + char *c_name = alloc_cstring(permanent_allocator(), mangled_name); + + LLVMValueRef global = LLVMAddGlobal(p->module->mod, lb_type(p->module, e->type), c_name); + LLVMSetInitializer(global, LLVMConstNull(lb_type(p->module, e->type))); + if (value.value != nullptr) { + LLVMSetInitializer(global, value.value); + } else { + } + if (e->Variable.thread_local_model != "") { + LLVMSetThreadLocal(global, true); + + String m = e->Variable.thread_local_model; + LLVMThreadLocalMode mode = LLVMGeneralDynamicTLSModel; + if (m == "default") { + mode = LLVMGeneralDynamicTLSModel; + } else if (m == "localdynamic") { + mode = LLVMLocalDynamicTLSModel; + } else if (m == "initialexec") { + mode = LLVMInitialExecTLSModel; + } else if (m == "localexec") { + mode = LLVMLocalExecTLSModel; + } else { + GB_PANIC("Unhandled thread local mode %.*s", LIT(m)); + } + LLVMSetThreadLocalMode(global, mode); + } else { + LLVMSetLinkage(global, LLVMInternalLinkage); + } + + + lbValue global_val = {global, alloc_type_pointer(e->type)}; + lb_add_entity(p->module, e, global_val); + lb_add_member(p->module, mangled_name, global_val); + } +} + + +void lb_build_assignment(lbProcedure *p, Array<lbAddr> &lvals, Slice<Ast *> const &values) { + if (values.count == 0) { + return; + } + + auto inits = array_make<lbValue>(permanent_allocator(), 0, lvals.count); + + for_array(i, values) { + Ast *rhs = values[i]; + if (is_type_tuple(type_of_expr(rhs))) { + lbValue init = lb_build_expr(p, rhs); + Type *t = init.type; + GB_ASSERT(t->kind == Type_Tuple); + for_array(i, t->Tuple.variables) { + Entity *e = t->Tuple.variables[i]; + lbValue v = lb_emit_struct_ev(p, init, cast(i32)i); + array_add(&inits, v); + } + } else { + auto prev_hint = lb_set_copy_elision_hint(p, lvals[inits.count], rhs); + lbValue init = lb_build_expr(p, rhs); + if (p->copy_elision_hint.used) { + lvals[inits.count] = {}; // zero lval + } + lb_reset_copy_elision_hint(p, prev_hint); + array_add(&inits, init); + } + } + + GB_ASSERT(lvals.count == inits.count); + for_array(i, inits) { + lbAddr lval = lvals[i]; + lbValue init = inits[i]; + lb_addr_store(p, lval, init); + } +} + +void lb_build_return_stmt(lbProcedure *p, AstReturnStmt *rs) { + lbValue res = {}; + + TypeTuple *tuple = &p->type->Proc.results->Tuple; + isize return_count = p->type->Proc.result_count; + isize res_count = rs->results.count; + + if (return_count == 0) { + // No return values + + lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr); + + LLVMBuildRetVoid(p->builder); + return; + } else if (return_count == 1) { + Entity *e = tuple->variables[0]; + if (res_count == 0) { + lbValue *found = map_get(&p->module->values, hash_entity(e)); + GB_ASSERT(found); + res = lb_emit_load(p, *found); + } else { + res = lb_build_expr(p, rs->results[0]); + res = lb_emit_conv(p, res, e->type); + } + if (p->type->Proc.has_named_results) { + // NOTE(bill): store the named values before returning + if (e->token.string != "") { + lbValue *found = map_get(&p->module->values, hash_entity(e)); + GB_ASSERT(found != nullptr); + lb_emit_store(p, *found, lb_emit_conv(p, res, e->type)); + } + } + + } else { + auto results = array_make<lbValue>(permanent_allocator(), 0, return_count); + + if (res_count != 0) { + for (isize res_index = 0; res_index < res_count; res_index++) { + lbValue res = lb_build_expr(p, rs->results[res_index]); + Type *t = res.type; + if (t->kind == Type_Tuple) { + for_array(i, t->Tuple.variables) { + Entity *e = t->Tuple.variables[i]; + lbValue v = lb_emit_struct_ev(p, res, cast(i32)i); + array_add(&results, v); + } + } else { + array_add(&results, res); + } + } + } else { + for (isize res_index = 0; res_index < return_count; res_index++) { + Entity *e = tuple->variables[res_index]; + lbValue *found = map_get(&p->module->values, hash_entity(e)); + GB_ASSERT(found); + lbValue res = lb_emit_load(p, *found); + array_add(&results, res); + } + } + + GB_ASSERT(results.count == return_count); + + if (p->type->Proc.has_named_results) { + // NOTE(bill): store the named values before returning + for_array(i, p->type->Proc.results->Tuple.variables) { + Entity *e = p->type->Proc.results->Tuple.variables[i]; + if (e->kind != Entity_Variable) { + continue; + } + + if (e->token.string == "") { + continue; + } + lbValue *found = map_get(&p->module->values, hash_entity(e)); + GB_ASSERT(found != nullptr); + lb_emit_store(p, *found, lb_emit_conv(p, results[i], e->type)); + } + } + + Type *ret_type = p->type->Proc.results; + // NOTE(bill): Doesn't need to be zero because it will be initialized in the loops + res = lb_add_local_generated(p, ret_type, false).addr; + for_array(i, results) { + Entity *e = tuple->variables[i]; + lbValue field = lb_emit_struct_ep(p, res, cast(i32)i); + lbValue val = lb_emit_conv(p, results[i], e->type); + lb_emit_store(p, field, val); + } + + res = lb_emit_load(p, res); + } + + + lb_ensure_abi_function_type(p->module, p); + if (p->abi_function_type->ret.kind == lbArg_Indirect) { + if (res.value != nullptr) { + LLVMBuildStore(p->builder, res.value, p->return_ptr.addr.value); + } else { + LLVMBuildStore(p->builder, LLVMConstNull(p->abi_function_type->ret.type), p->return_ptr.addr.value); + } + + lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr); + + LLVMBuildRetVoid(p->builder); + } else { + LLVMValueRef ret_val = res.value; + ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.type); + if (p->abi_function_type->ret.cast_type != nullptr) { + ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.cast_type); + } + + lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr); + LLVMBuildRet(p->builder, ret_val); + } +} + +void lb_build_if_stmt(lbProcedure *p, Ast *node) { + ast_node(is, IfStmt, node); + lb_open_scope(p, node->scope); // Scope #1 + + if (is->init != nullptr) { + // TODO(bill): Should this have a separate block to begin with? + #if 1 + lbBlock *init = lb_create_block(p, "if.init"); + lb_emit_jump(p, init); + lb_start_block(p, init); + #endif + lb_build_stmt(p, is->init); + } + lbBlock *then = lb_create_block(p, "if.then"); + lbBlock *done = lb_create_block(p, "if.done"); + lbBlock *else_ = done; + if (is->else_stmt != nullptr) { + else_ = lb_create_block(p, "if.else"); + } + + lb_build_cond(p, is->cond, then, else_); + lb_start_block(p, then); + + if (is->label != nullptr) { + lbTargetList *tl = lb_push_target_list(p, is->label, done, nullptr, nullptr); + tl->is_block = true; + } + + lb_build_stmt(p, is->body); + + 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); + } + + lb_start_block(p, done); + lb_close_scope(p, lbDeferExit_Default, nullptr); +} + +void lb_build_for_stmt(lbProcedure *p, Ast *node) { + ast_node(fs, ForStmt, node); + + lb_open_scope(p, node->scope); // Open Scope here + + if (fs->init != nullptr) { + #if 1 + lbBlock *init = lb_create_block(p, "for.init"); + lb_emit_jump(p, init); + lb_start_block(p, init); + #endif + lb_build_stmt(p, fs->init); + } + lbBlock *body = lb_create_block(p, "for.body"); + lbBlock *done = lb_create_block(p, "for.done"); // NOTE(bill): Append later + lbBlock *loop = body; + if (fs->cond != nullptr) { + loop = lb_create_block(p, "for.loop"); + } + lbBlock *post = loop; + if (fs->post != nullptr) { + post = lb_create_block(p, "for.post"); + } + + + lb_emit_jump(p, loop); + lb_start_block(p, loop); + + if (loop != body) { + lb_build_cond(p, fs->cond, body, done); + lb_start_block(p, body); + } + + lb_push_target_list(p, fs->label, done, post, nullptr); + + lb_build_stmt(p, fs->body); + lb_close_scope(p, lbDeferExit_Default, nullptr); + + lb_pop_target_list(p); + + lb_emit_jump(p, post); + + if (fs->post != nullptr) { + lb_start_block(p, post); + lb_build_stmt(p, fs->post); + lb_emit_jump(p, loop); + } + + lb_start_block(p, done); +} + void lb_build_stmt(lbProcedure *p, Ast *node) { Ast *prev_stmt = p->curr_stmt; @@ -5028,156 +5343,24 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { } if (is_static) { - for_array(i, vd->names) { - lbValue value = {}; - if (vd->values.count > 0) { - GB_ASSERT(vd->names.count == vd->values.count); - Ast *ast_value = vd->values[i]; - GB_ASSERT(ast_value->tav.mode == Addressing_Constant || - ast_value->tav.mode == Addressing_Invalid); - - bool allow_local = false; - value = lb_const_value(p->module, ast_value->tav.type, ast_value->tav.value, allow_local); - } - - Ast *ident = vd->names[i]; - GB_ASSERT(!is_blank_ident(ident)); - Entity *e = entity_of_node(ident); - GB_ASSERT(e->flags & EntityFlag_Static); - String name = e->token.string; - - String mangled_name = {}; - { - gbString str = gb_string_make_length(permanent_allocator(), p->name.text, p->name.len); - str = gb_string_appendc(str, "-"); - str = gb_string_append_fmt(str, ".%.*s-%llu", LIT(name), cast(long long)e->id); - mangled_name.text = cast(u8 *)str; - mangled_name.len = gb_string_length(str); - } - - char *c_name = alloc_cstring(permanent_allocator(), mangled_name); - - LLVMValueRef global = LLVMAddGlobal(p->module->mod, lb_type(p->module, e->type), c_name); - LLVMSetInitializer(global, LLVMConstNull(lb_type(p->module, e->type))); - if (value.value != nullptr) { - LLVMSetInitializer(global, value.value); - } else { - } - if (e->Variable.thread_local_model != "") { - LLVMSetThreadLocal(global, true); - - String m = e->Variable.thread_local_model; - LLVMThreadLocalMode mode = LLVMGeneralDynamicTLSModel; - if (m == "default") { - mode = LLVMGeneralDynamicTLSModel; - } else if (m == "localdynamic") { - mode = LLVMLocalDynamicTLSModel; - } else if (m == "initialexec") { - mode = LLVMInitialExecTLSModel; - } else if (m == "localexec") { - mode = LLVMLocalExecTLSModel; - } else { - GB_PANIC("Unhandled thread local mode %.*s", LIT(m)); - } - LLVMSetThreadLocalMode(global, mode); - } else { - LLVMSetLinkage(global, LLVMInternalLinkage); - } - - - lbValue global_val = {global, alloc_type_pointer(e->type)}; - lb_add_entity(p->module, e, global_val); - lb_add_member(p->module, mangled_name, global_val); - } + lb_build_static_variables(p, vd); return; } - if (vd->values.count == 0) { // declared and zero-initialized - for_array(i, vd->names) { - Ast *name = vd->names[i]; - if (!is_blank_ident(name)) { - Entity *e = entity_of_node(name); - lb_add_local(p, e->type, e, true); - } - } - } else if (vd->names.count == vd->values.count) { - auto lvals = array_make<lbAddr>(permanent_allocator(), 0, vd->names.count); - auto inits = array_make<lbValue>(permanent_allocator(), 0, vd->names.count); - - for_array(i, vd->names) { - Ast *name = vd->names[i]; - lbAddr lval = {}; - if (!is_blank_ident(name)) { - Entity *e = entity_of_node(name); - bool zero_init = true; - if (vd->names.count == vd->values.count) { - // Possibly uses copy elision - // Make the caller mem zero - zero_init = true; - } - lval = lb_add_local(p, e->type, e, zero_init); - } - array_add(&lvals, lval); - } - - for_array(i, vd->values) { - Ast *rhs = unparen_expr(vd->values[i]); - - auto prev_hint = lb_set_copy_elision_hint(p, lvals[i], rhs); - - lbValue init = lb_build_expr(p, rhs); - Type *t = init.type; - GB_ASSERT(t->kind != Type_Tuple); - array_add(&inits, init); - - if (p->copy_elision_hint.used) { - lvals[i] = {}; // zero lval - } - lb_reset_copy_elision_hint(p, prev_hint); - } - - for_array(i, inits) { - lbAddr lval = lvals[i]; - lbValue init = inits[i]; - lb_addr_store(p, lval, init); - } - } else { // Tuple(s) - auto lvals = array_make<lbAddr>(permanent_allocator(), 0, vd->names.count); - auto inits = array_make<lbValue>(permanent_allocator(), 0, vd->names.count); + auto lvals = array_make<lbAddr>(permanent_allocator(), 0, vd->names.count); - for_array(i, vd->names) { - Ast *name = vd->names[i]; - lbAddr lval = {}; - if (!is_blank_ident(name)) { - Entity *e = entity_of_node(name); - bool zero_init = false; - lval = lb_add_local(p, e->type, e, zero_init); - } - array_add(&lvals, lval); - } - - for_array(i, vd->values) { - Ast *rhs = unparen_expr(vd->values[i]); - lbValue init = lb_build_expr(p, rhs); - Type *t = init.type; - if (t->kind == Type_Tuple) { - for_array(i, t->Tuple.variables) { - Entity *e = t->Tuple.variables[i]; - lbValue v = lb_emit_struct_ev(p, init, cast(i32)i); - array_add(&inits, v); - } - } else { - array_add(&inits, init); - } - } - - for_array(i, inits) { - lbAddr lval = lvals[i]; - lbValue init = inits[i]; - lb_addr_store(p, lval, init); + for_array(i, vd->names) { + Ast *name = vd->names[i]; + lbAddr lval = {}; + if (!is_blank_ident(name)) { + Entity *e = entity_of_node(name); + bool zero_init = true; // Zero always and optimize out later + lval = lb_add_local(p, e->type, e, zero_init); } + array_add(&lvals, lval); } + lb_build_assignment(p, lvals, vd->values); case_end; case_ast_node(as, AssignStmt, node); @@ -5192,54 +5375,10 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { } array_add(&lvals, lval); } - - if (as->lhs.count == as->rhs.count) { - auto inits = array_make<lbValue>(permanent_allocator(), 0, lvals.count); - - for_array(i, as->rhs) { - Ast *rhs = unparen_expr(as->rhs[i]); - - auto prev_hint = lb_set_copy_elision_hint(p, lvals[i], rhs); - - lbValue init = lb_build_expr(p, rhs); - array_add(&inits, init); - - if (p->copy_elision_hint.used) { - lvals[i] = {}; // zero lval - } - lb_reset_copy_elision_hint(p, prev_hint); - } - - for_array(i, inits) { - lbAddr lval = lvals[i]; - lbValue init = inits[i]; - lb_addr_store(p, lval, init); - } - } else { - auto inits = array_make<lbValue>(permanent_allocator(), 0, lvals.count); - - for_array(i, as->rhs) { - lbValue init = lb_build_expr(p, as->rhs[i]); - Type *t = init.type; - // TODO(bill): refactor for code reuse as this is repeated a bit - if (t->kind == Type_Tuple) { - for_array(i, t->Tuple.variables) { - Entity *e = t->Tuple.variables[i]; - lbValue v = lb_emit_struct_ev(p, init, cast(i32)i); - array_add(&inits, v); - } - } else { - array_add(&inits, init); - } - } - - for_array(i, inits) { - lbAddr lval = lvals[i]; - lbValue init = inits[i]; - lb_addr_store(p, lval, init); - } - } + lb_build_assignment(p, lvals, as->rhs); } else { + GB_ASSERT(as->lhs.count == 1); + GB_ASSERT(as->rhs.count == 1); // NOTE(bill): Only 1 += 1 is allowed, no tuples // +=, -=, etc i32 op = cast(i32)as->op.kind; @@ -5270,222 +5409,19 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { case_end; case_ast_node(ds, DeferStmt, node); - isize scope_index = p->scope_index; - lb_add_defer_node(p, scope_index, ds->stmt); + lb_add_defer_node(p, p->scope_index, ds->stmt); case_end; case_ast_node(rs, ReturnStmt, node); - lbValue res = {}; - - TypeTuple *tuple = &p->type->Proc.results->Tuple; - isize return_count = p->type->Proc.result_count; - isize res_count = rs->results.count; - - if (return_count == 0) { - // No return values - - lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr); - - LLVMBuildRetVoid(p->builder); - return; - } else if (return_count == 1) { - Entity *e = tuple->variables[0]; - if (res_count == 0) { - lbValue *found = map_get(&p->module->values, hash_entity(e)); - GB_ASSERT(found); - res = lb_emit_load(p, *found); - } else { - res = lb_build_expr(p, rs->results[0]); - res = lb_emit_conv(p, res, e->type); - } - if (p->type->Proc.has_named_results) { - // NOTE(bill): store the named values before returning - if (e->token.string != "") { - lbValue *found = map_get(&p->module->values, hash_entity(e)); - GB_ASSERT(found != nullptr); - lb_emit_store(p, *found, lb_emit_conv(p, res, e->type)); - } - } - - } else { - auto results = array_make<lbValue>(permanent_allocator(), 0, return_count); - - if (res_count != 0) { - for (isize res_index = 0; res_index < res_count; res_index++) { - lbValue res = lb_build_expr(p, rs->results[res_index]); - Type *t = res.type; - if (t->kind == Type_Tuple) { - for_array(i, t->Tuple.variables) { - Entity *e = t->Tuple.variables[i]; - lbValue v = lb_emit_struct_ev(p, res, cast(i32)i); - array_add(&results, v); - } - } else { - array_add(&results, res); - } - } - } else { - for (isize res_index = 0; res_index < return_count; res_index++) { - Entity *e = tuple->variables[res_index]; - lbValue *found = map_get(&p->module->values, hash_entity(e)); - GB_ASSERT(found); - lbValue res = lb_emit_load(p, *found); - array_add(&results, res); - } - } - - GB_ASSERT(results.count == return_count); - - if (p->type->Proc.has_named_results) { - // NOTE(bill): store the named values before returning - for_array(i, p->type->Proc.results->Tuple.variables) { - Entity *e = p->type->Proc.results->Tuple.variables[i]; - if (e->kind != Entity_Variable) { - continue; - } - - if (e->token.string == "") { - continue; - } - lbValue *found = map_get(&p->module->values, hash_entity(e)); - GB_ASSERT(found != nullptr); - lb_emit_store(p, *found, lb_emit_conv(p, results[i], e->type)); - } - } - - Type *ret_type = p->type->Proc.results; - // NOTE(bill): Doesn't need to be zero because it will be initialized in the loops - res = lb_add_local_generated(p, ret_type, false).addr; - for_array(i, results) { - Entity *e = tuple->variables[i]; - lbValue field = lb_emit_struct_ep(p, res, cast(i32)i); - lbValue val = lb_emit_conv(p, results[i], e->type); - lb_emit_store(p, field, val); - } - - res = lb_emit_load(p, res); - } - - - lb_ensure_abi_function_type(p->module, p); - if (p->abi_function_type->ret.kind == lbArg_Indirect) { - if (res.value != nullptr) { - LLVMBuildStore(p->builder, res.value, p->return_ptr.addr.value); - } else { - LLVMBuildStore(p->builder, LLVMConstNull(p->abi_function_type->ret.type), p->return_ptr.addr.value); - } - - lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr); - - LLVMBuildRetVoid(p->builder); - } else { - LLVMValueRef ret_val = res.value; - ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.type); - if (p->abi_function_type->ret.cast_type != nullptr) { - ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.cast_type); - } - - lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr); - LLVMBuildRet(p->builder, ret_val); - } - - - + lb_build_return_stmt(p, rs); case_end; case_ast_node(is, IfStmt, node); - lb_open_scope(p, node->scope); // Scope #1 - - if (is->init != nullptr) { - // TODO(bill): Should this have a separate block to begin with? - #if 1 - lbBlock *init = lb_create_block(p, "if.init"); - lb_emit_jump(p, init); - lb_start_block(p, init); - #endif - lb_build_stmt(p, is->init); - } - lbBlock *then = lb_create_block(p, "if.then"); - lbBlock *done = lb_create_block(p, "if.done"); - lbBlock *else_ = done; - if (is->else_stmt != nullptr) { - else_ = lb_create_block(p, "if.else"); - } - - lb_build_cond(p, is->cond, then, else_); - lb_start_block(p, then); - - if (is->label != nullptr) { - lbTargetList *tl = lb_push_target_list(p, is->label, done, nullptr, nullptr); - tl->is_block = true; - } - - lb_build_stmt(p, is->body); - - 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); - } - - - lb_start_block(p, done); - lb_close_scope(p, lbDeferExit_Default, nullptr); + lb_build_if_stmt(p, node); case_end; case_ast_node(fs, ForStmt, node); - lb_open_scope(p, node->scope); // Open Scope here - - if (fs->init != nullptr) { - #if 1 - lbBlock *init = lb_create_block(p, "for.init"); - lb_emit_jump(p, init); - lb_start_block(p, init); - #endif - lb_build_stmt(p, fs->init); - } - lbBlock *body = lb_create_block(p, "for.body"); - lbBlock *done = lb_create_block(p, "for.done"); // NOTE(bill): Append later - lbBlock *loop = body; - if (fs->cond != nullptr) { - loop = lb_create_block(p, "for.loop"); - } - lbBlock *post = loop; - if (fs->post != nullptr) { - post = lb_create_block(p, "for.post"); - } - - - lb_emit_jump(p, loop); - lb_start_block(p, loop); - - if (loop != body) { - lb_build_cond(p, fs->cond, body, done); - lb_start_block(p, body); - } - - lb_push_target_list(p, fs->label, done, post, nullptr); - - lb_build_stmt(p, fs->body); - lb_close_scope(p, lbDeferExit_Default, nullptr); - - lb_pop_target_list(p); - - lb_emit_jump(p, post); - - if (fs->post != nullptr) { - lb_start_block(p, post); - lb_build_stmt(p, fs->post); - lb_emit_jump(p, loop); - } - - lb_start_block(p, done); + lb_build_for_stmt(p, node); case_end; case_ast_node(rs, RangeStmt, node); @@ -5493,7 +5429,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { case_end; case_ast_node(rs, UnrollRangeStmt, node); - lb_build_inline_range_stmt(p, rs, node->scope); + lb_build_unroll_range_stmt(p, rs, node->scope); case_end; case_ast_node(ss, SwitchStmt, node); |