authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-04 18:57:59-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-04 18:58:14-04:00
logfbf21efd24bf812e0fd52a5917708a4c45f05b5e
tree96aeb27f9a24d57b477c763073b2f2198df2a05c
parent042914de75f7ccf520fb2058372cc3f255ccfecb
signature Commit is signed but in an unrecognized format.

simpler, less memory intensive suspend/resume implementation


4 files changed, 62 insertions(+), 92 deletions(-)

src/all_types.hpp+5-11
...@@ -1386,7 +1386,6 @@ struct ZigFn {...@@ -1386,7 +1386,6 @@ struct ZigFn {
13861386
1387 ZigList<IrInstructionAllocaGen *> alloca_gen_list;1387 ZigList<IrInstructionAllocaGen *> alloca_gen_list;
1388 ZigList<ZigVar *> variable_list;1388 ZigList<ZigVar *> variable_list;
1389 ZigList<IrBasicBlock *> resume_blocks;
13901389
1391 Buf *section_name;1390 Buf *section_name;
1392 AstNode *set_alignstack_node;1391 AstNode *set_alignstack_node;
...@@ -1719,6 +1718,7 @@ struct CodeGen {...@@ -1719,6 +1718,7 @@ struct CodeGen {
1719 LLVMValueRef cur_async_resume_index_ptr;1718 LLVMValueRef cur_async_resume_index_ptr;
1720 LLVMValueRef cur_async_awaiter_ptr;1719 LLVMValueRef cur_async_awaiter_ptr;
1721 LLVMBasicBlockRef cur_preamble_llvm_block;1720 LLVMBasicBlockRef cur_preamble_llvm_block;
1721 size_t cur_resume_block_count;
1722 LLVMValueRef cur_err_ret_trace_val_arg;1722 LLVMValueRef cur_err_ret_trace_val_arg;
1723 LLVMValueRef cur_err_ret_trace_val_stack;1723 LLVMValueRef cur_err_ret_trace_val_stack;
1724 LLVMValueRef memcpy_fn_val;1724 LLVMValueRef memcpy_fn_val;
...@@ -2114,7 +2114,6 @@ struct ScopeRuntime {...@@ -2114,7 +2114,6 @@ struct ScopeRuntime {
2114struct ScopeSuspend {2114struct ScopeSuspend {
2115 Scope base;2115 Scope base;
21162116
2117 IrBasicBlock *resume_block;
2118 bool reported_err;2117 bool reported_err;
2119};2118};
21202119
...@@ -2169,8 +2168,6 @@ struct IrBasicBlock {...@@ -2169,8 +2168,6 @@ struct IrBasicBlock {
2169 size_t ref_count;2168 size_t ref_count;
2170 // index into the basic block list2169 // index into the basic block list
2171 size_t index;2170 size_t index;
2172 // for async functions, the resume index which corresponds to this block
2173 size_t resume_index;
2174 LLVMBasicBlockRef llvm_block;2171 LLVMBasicBlockRef llvm_block;
2175 LLVMBasicBlockRef llvm_exit_block;2172 LLVMBasicBlockRef llvm_exit_block;
2176 // The instruction that referenced this basic block and caused us to2173 // The instruction that referenced this basic block and caused us to
...@@ -2354,7 +2351,7 @@ enum IrInstructionId {...@@ -2354,7 +2351,7 @@ enum IrInstructionId {
2354 IrInstructionIdPtrOfArrayToSlice,2351 IrInstructionIdPtrOfArrayToSlice,
2355 IrInstructionIdUnionInitNamedField,2352 IrInstructionIdUnionInitNamedField,
2356 IrInstructionIdSuspendBegin,2353 IrInstructionIdSuspendBegin,
2357 IrInstructionIdSuspendBr,2354 IrInstructionIdSuspendFinish,
2358 IrInstructionIdAwait,2355 IrInstructionIdAwait,
2359 IrInstructionIdCoroResume,2356 IrInstructionIdCoroResume,
2360};2357};
...@@ -3600,13 +3597,13 @@ struct IrInstructionPtrOfArrayToSlice {...@@ -3600,13 +3597,13 @@ struct IrInstructionPtrOfArrayToSlice {
3600struct IrInstructionSuspendBegin {3597struct IrInstructionSuspendBegin {
3601 IrInstruction base;3598 IrInstruction base;
36023599
3603 IrBasicBlock *resume_block;3600 LLVMBasicBlockRef resume_bb;
3604};3601};
36053602
3606struct IrInstructionSuspendBr {3603struct IrInstructionSuspendFinish {
3607 IrInstruction base;3604 IrInstruction base;
36083605
3609 IrBasicBlock *resume_block;3606 IrInstructionSuspendBegin *begin;
3610};3607};
36113608
3612struct IrInstructionAwait {3609struct IrInstructionAwait {
...@@ -3710,9 +3707,6 @@ static const size_t coro_resume_index = 1;...@@ -3710,9 +3707,6 @@ static const size_t coro_resume_index = 1;
3710static const size_t coro_awaiter_index = 2;3707static const size_t coro_awaiter_index = 2;
3711static const size_t coro_arg_start = 3;3708static const size_t coro_arg_start = 3;
37123709
3713// one for the Entry block, resume blocks are indexed after that.
3714static const size_t coro_extra_resume_block_count = 1;
3715
3716// TODO call graph analysis to find out what this number needs to be for every function3710// TODO call graph analysis to find out what this number needs to be for every function
3717// MUST BE A POWER OF TWO.3711// MUST BE A POWER OF TWO.
3718static const size_t stack_trace_ptr_count = 32;3712static const size_t stack_trace_ptr_count = 32;
src/codegen.cpp+25-29
...@@ -3661,8 +3661,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3661,8 +3661,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3661 ZigType *ptr_result_type = get_pointer_to_type(g, src_return_type, true);3661 ZigType *ptr_result_type = get_pointer_to_type(g, src_return_type, true);
36623662
3663 LLVMBasicBlockRef call_bb = LLVMAppendBasicBlock(g->cur_fn_val, "CallResume");3663 LLVMBasicBlockRef call_bb = LLVMAppendBasicBlock(g->cur_fn_val, "CallResume");
3664 size_t new_block_index = g->cur_fn->resume_blocks.length + coro_extra_resume_block_count;3664 size_t new_block_index = g->cur_resume_block_count;
3665 g->cur_fn->resume_blocks.append(nullptr);3665 g->cur_resume_block_count += 1;
3666 LLVMValueRef new_block_index_val = LLVMConstInt(usize_type_ref, new_block_index, false);3666 LLVMValueRef new_block_index_val = LLVMConstInt(usize_type_ref, new_block_index, false);
3667 LLVMAddCase(g->cur_async_switch_instr, new_block_index_val, call_bb);3667 LLVMAddCase(g->cur_async_switch_instr, new_block_index_val, call_bb);
36683668
...@@ -5153,15 +5153,22 @@ static LLVMValueRef ir_render_suspend_begin(CodeGen *g, IrExecutable *executable...@@ -5153,15 +5153,22 @@ static LLVMValueRef ir_render_suspend_begin(CodeGen *g, IrExecutable *executable
5153 IrInstructionSuspendBegin *instruction)5153 IrInstructionSuspendBegin *instruction)
5154{5154{
5155 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;5155 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
5156 LLVMValueRef new_resume_index = LLVMConstInt(usize_type_ref, instruction->resume_block->resume_index, false);5156 instruction->resume_bb = LLVMAppendBasicBlock(g->cur_fn_val, "SuspendResume");
5157 LLVMBuildStore(g->builder, new_resume_index, g->cur_async_resume_index_ptr);5157 size_t new_block_index = g->cur_resume_block_count;
5158 g->cur_resume_block_count += 1;
5159 LLVMValueRef new_block_index_val = LLVMConstInt(usize_type_ref, new_block_index, false);
5160 LLVMAddCase(g->cur_async_switch_instr, new_block_index_val, instruction->resume_bb);
5161 LLVMBuildStore(g->builder, new_block_index_val, g->cur_async_resume_index_ptr);
5158 return nullptr;5162 return nullptr;
5159}5163}
51605164
5161static LLVMValueRef ir_render_suspend_br(CodeGen *g, IrExecutable *executable,5165static LLVMValueRef ir_render_suspend_finish(CodeGen *g, IrExecutable *executable,
5162 IrInstructionSuspendBr *instruction)5166 IrInstructionSuspendFinish *instruction)
5163{5167{
5164 LLVMBuildRetVoid(g->builder);5168 LLVMBuildRetVoid(g->builder);
5169
5170 LLVMPositionBuilderAtEnd(g->builder, instruction->begin->resume_bb);
5171 render_async_var_decls(g, instruction->base.scope);
5165 return nullptr;5172 return nullptr;
5166}5173}
51675174
...@@ -5173,8 +5180,8 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst...@@ -5173,8 +5180,8 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInst
51735180
5174 // Prepare to be suspended5181 // Prepare to be suspended
5175 LLVMBasicBlockRef resume_bb = LLVMAppendBasicBlock(g->cur_fn_val, "AwaitResume");5182 LLVMBasicBlockRef resume_bb = LLVMAppendBasicBlock(g->cur_fn_val, "AwaitResume");
5176 size_t new_block_index = g->cur_fn->resume_blocks.length + coro_extra_resume_block_count;5183 size_t new_block_index = g->cur_resume_block_count;
5177 g->cur_fn->resume_blocks.append(nullptr);5184 g->cur_resume_block_count += 1;
5178 LLVMValueRef new_block_index_val = LLVMConstInt(usize_type_ref, new_block_index, false);5185 LLVMValueRef new_block_index_val = LLVMConstInt(usize_type_ref, new_block_index, false);
5179 LLVMAddCase(g->cur_async_switch_instr, new_block_index_val, resume_bb);5186 LLVMAddCase(g->cur_async_switch_instr, new_block_index_val, resume_bb);
5180 LLVMBuildStore(g->builder, new_block_index_val, g->cur_async_resume_index_ptr);5187 LLVMBuildStore(g->builder, new_block_index_val, g->cur_async_resume_index_ptr);
...@@ -5534,8 +5541,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5534,8 +5541,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5534 return ir_render_ptr_of_array_to_slice(g, executable, (IrInstructionPtrOfArrayToSlice *)instruction);5541 return ir_render_ptr_of_array_to_slice(g, executable, (IrInstructionPtrOfArrayToSlice *)instruction);
5535 case IrInstructionIdSuspendBegin:5542 case IrInstructionIdSuspendBegin:
5536 return ir_render_suspend_begin(g, executable, (IrInstructionSuspendBegin *)instruction);5543 return ir_render_suspend_begin(g, executable, (IrInstructionSuspendBegin *)instruction);
5537 case IrInstructionIdSuspendBr:5544 case IrInstructionIdSuspendFinish:
5538 return ir_render_suspend_br(g, executable, (IrInstructionSuspendBr *)instruction);5545 return ir_render_suspend_finish(g, executable, (IrInstructionSuspendFinish *)instruction);
5539 case IrInstructionIdCoroResume:5546 case IrInstructionIdCoroResume:
5540 return ir_render_coro_resume(g, executable, (IrInstructionCoroResume *)instruction);5547 return ir_render_coro_resume(g, executable, (IrInstructionCoroResume *)instruction);
5541 case IrInstructionIdFrameSizeGen:5548 case IrInstructionIdFrameSizeGen:
...@@ -5552,19 +5559,10 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {...@@ -5552,19 +5559,10 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {
5552 IrExecutable *executable = &fn_entry->analyzed_executable;5559 IrExecutable *executable = &fn_entry->analyzed_executable;
5553 assert(executable->basic_block_list.length > 0);5560 assert(executable->basic_block_list.length > 0);
55545561
5555 if (fn_is_async(fn_entry)) {
5556 IrBasicBlock *entry_block = executable->basic_block_list.at(0);
5557 LLVMPositionBuilderAtEnd(g->builder, entry_block->llvm_block);
5558 render_async_var_decls(g, entry_block->instruction_list.at(0)->scope);
5559 }
5560
5561 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {5562 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {
5562 IrBasicBlock *current_block = executable->basic_block_list.at(block_i);5563 IrBasicBlock *current_block = executable->basic_block_list.at(block_i);
5563 assert(current_block->llvm_block);5564 assert(current_block->llvm_block);
5564 LLVMPositionBuilderAtEnd(g->builder, current_block->llvm_block);5565 LLVMPositionBuilderAtEnd(g->builder, current_block->llvm_block);
5565 if (current_block->resume_index != 0) {
5566 render_async_var_decls(g, current_block->instruction_list.at(0)->scope);
5567 }
5568 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {5566 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
5569 IrInstruction *instruction = current_block->instruction_list.at(instr_i);5567 IrInstruction *instruction = current_block->instruction_list.at(instr_i);
5570 if (instruction->ref_count == 0 && !ir_has_side_effects(instruction))5568 if (instruction->ref_count == 0 && !ir_has_side_effects(instruction))
...@@ -6757,6 +6755,8 @@ static void do_code_gen(CodeGen *g) {...@@ -6757,6 +6755,8 @@ static void do_code_gen(CodeGen *g) {
6757 }6755 }
67586756
6759 if (is_async) {6757 if (is_async) {
6758 g->cur_resume_block_count = 0;
6759
6760 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;6760 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
6761 LLVMValueRef size_val = LLVMConstInt(usize_type_ref, fn_table_entry->frame_type->abi_size, false);6761 LLVMValueRef size_val = LLVMConstInt(usize_type_ref, fn_table_entry->frame_type->abi_size, false);
6762 ZigLLVMFunctionSetPrefixData(fn_table_entry->llvm_value, size_val);6762 ZigLLVMFunctionSetPrefixData(fn_table_entry->llvm_value, size_val);
...@@ -6777,19 +6777,15 @@ static void do_code_gen(CodeGen *g) {...@@ -6777,19 +6777,15 @@ static void do_code_gen(CodeGen *g) {
6777 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_resume_index, "");6777 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_resume_index, "");
6778 g->cur_async_resume_index_ptr = resume_index_ptr;6778 g->cur_async_resume_index_ptr = resume_index_ptr;
6779 LLVMValueRef resume_index = LLVMBuildLoad(g->builder, resume_index_ptr, "");6779 LLVMValueRef resume_index = LLVMBuildLoad(g->builder, resume_index_ptr, "");
6780 LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, resume_index, bad_resume_block,6780 LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, resume_index, bad_resume_block, 4);
6781 fn_table_entry->resume_blocks.length + coro_extra_resume_block_count);
6782 g->cur_async_switch_instr = switch_instr;6781 g->cur_async_switch_instr = switch_instr;
67836782
6784 LLVMValueRef zero = LLVMConstNull(usize_type_ref);6783 LLVMValueRef zero = LLVMConstNull(usize_type_ref);
6785 LLVMAddCase(switch_instr, zero, executable->basic_block_list.at(0)->llvm_block);6784 IrBasicBlock *entry_block = executable->basic_block_list.at(0);
67866785 LLVMAddCase(switch_instr, zero, entry_block->llvm_block);
6787 for (size_t resume_i = 0; resume_i < fn_table_entry->resume_blocks.length; resume_i += 1) {6786 g->cur_resume_block_count += 1;
6788 IrBasicBlock *resume_block = fn_table_entry->resume_blocks.at(resume_i);6787 LLVMPositionBuilderAtEnd(g->builder, entry_block->llvm_block);
6789 LLVMValueRef case_value = LLVMConstInt(usize_type_ref, resume_block->resume_index, false);6788 render_async_var_decls(g, entry_block->instruction_list.at(0)->scope);
6790 LLVMAddCase(switch_instr, case_value, resume_block->llvm_block);
6791 }
6792
6793 } else {6789 } else {
6794 // create debug variable declarations for parameters6790 // create debug variable declarations for parameters
6795 // rely on the first variables in the variable_list being parameters.6791 // rely on the first variables in the variable_list being parameters.
src/ir.cpp+28-46
...@@ -1049,8 +1049,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendBegin *)...@@ -1049,8 +1049,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendBegin *)
1049 return IrInstructionIdSuspendBegin;1049 return IrInstructionIdSuspendBegin;
1050}1050}
10511051
1052static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendBr *) {1052static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendFinish *) {
1053 return IrInstructionIdSuspendBr;1053 return IrInstructionIdSuspendFinish;
1054}1054}
10551055
1056static constexpr IrInstructionId ir_instruction_id(IrInstructionAwait *) {1056static constexpr IrInstructionId ir_instruction_id(IrInstructionAwait *) {
...@@ -3260,25 +3260,21 @@ static IrInstruction *ir_build_end_expr(IrBuilder *irb, Scope *scope, AstNode *s...@@ -3260,25 +3260,21 @@ static IrInstruction *ir_build_end_expr(IrBuilder *irb, Scope *scope, AstNode *s
3260 return &instruction->base;3260 return &instruction->base;
3261}3261}
32623262
3263static IrInstruction *ir_build_suspend_begin(IrBuilder *irb, Scope *scope, AstNode *source_node,3263static IrInstructionSuspendBegin *ir_build_suspend_begin(IrBuilder *irb, Scope *scope, AstNode *source_node) {
3264 IrBasicBlock *resume_block)
3265{
3266 IrInstructionSuspendBegin *instruction = ir_build_instruction<IrInstructionSuspendBegin>(irb, scope, source_node);3264 IrInstructionSuspendBegin *instruction = ir_build_instruction<IrInstructionSuspendBegin>(irb, scope, source_node);
3267 instruction->base.value.type = irb->codegen->builtin_types.entry_void;3265 instruction->base.value.type = irb->codegen->builtin_types.entry_void;
3268 instruction->resume_block = resume_block;
3269
3270 ir_ref_bb(resume_block);
32713266
3272 return &instruction->base;3267 return instruction;
3273}3268}
32743269
3275static IrInstruction *ir_build_suspend_br(IrBuilder *irb, Scope *scope, AstNode *source_node,3270static IrInstruction *ir_build_suspend_finish(IrBuilder *irb, Scope *scope, AstNode *source_node,
3276 IrBasicBlock *resume_block)3271 IrInstructionSuspendBegin *begin)
3277{3272{
3278 IrInstructionSuspendBr *instruction = ir_build_instruction<IrInstructionSuspendBr>(irb, scope, source_node);3273 IrInstructionSuspendFinish *instruction = ir_build_instruction<IrInstructionSuspendFinish>(irb, scope, source_node);
3279 instruction->resume_block = resume_block;3274 instruction->base.value.type = irb->codegen->builtin_types.entry_void;
3275 instruction->begin = begin;
32803276
3281 ir_ref_bb(resume_block);3277 ir_ref_instruction(&begin->base, irb->current_basic_block);
32823278
3283 return &instruction->base;3279 return &instruction->base;
3284}3280}
...@@ -7890,22 +7886,15 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod...@@ -7890,22 +7886,15 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
7890 return irb->codegen->invalid_instruction;7886 return irb->codegen->invalid_instruction;
7891 }7887 }
78927888
7893 IrBasicBlock *resume_block = ir_create_basic_block(irb, parent_scope, "SuspendResume");7889 IrInstructionSuspendBegin *begin = ir_build_suspend_begin(irb, parent_scope, node);
7894
7895 ir_build_suspend_begin(irb, parent_scope, node, resume_block);
7896 if (node->data.suspend.block != nullptr) {7890 if (node->data.suspend.block != nullptr) {
7897 Scope *child_scope;
7898 ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope);7891 ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope);
7899 suspend_scope->resume_block = resume_block;7892 Scope *child_scope = &suspend_scope->base;
7900 child_scope = &suspend_scope->base;
7901 IrInstruction *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope);7893 IrInstruction *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope);
7902 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res));7894 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res));
7903 }7895 }
79047896
7905 IrInstruction *result = ir_build_suspend_br(irb, parent_scope, node, resume_block);7897 return ir_build_suspend_finish(irb, parent_scope, node, begin);
7906 result->value.type = irb->codegen->builtin_types.entry_void;
7907 ir_set_cursor_at_end_and_append_block(irb, resume_block);
7908 return result;
7909}7898}
79107899
7911static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,7900static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,
...@@ -24458,35 +24447,28 @@ static IrInstruction *ir_analyze_instruction_union_init_named_field(IrAnalyze *i...@@ -24458,35 +24447,28 @@ static IrInstruction *ir_analyze_instruction_union_init_named_field(IrAnalyze *i
24458}24447}
2445924448
24460static IrInstruction *ir_analyze_instruction_suspend_begin(IrAnalyze *ira, IrInstructionSuspendBegin *instruction) {24449static IrInstruction *ir_analyze_instruction_suspend_begin(IrAnalyze *ira, IrInstructionSuspendBegin *instruction) {
24461 IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, instruction->resume_block, &instruction->base);24450 IrInstructionSuspendBegin *result = ir_build_suspend_begin(&ira->new_irb, instruction->base.scope,
24462 if (new_bb == nullptr)24451 instruction->base.source_node);
24463 return ir_unreach_error(ira);24452 return &result->base;
24464 return ir_build_suspend_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node, new_bb);
24465}24453}
2446624454
24467static IrInstruction *ir_analyze_instruction_suspend_br(IrAnalyze *ira, IrInstructionSuspendBr *instruction) {24455static IrInstruction *ir_analyze_instruction_suspend_finish(IrAnalyze *ira,
24468 IrBasicBlock *old_dest_block = instruction->resume_block;24456 IrInstructionSuspendFinish *instruction)
2446924457{
24470 IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &instruction->base);24458 IrInstruction *begin_base = instruction->begin->base.child;
24471 if (new_bb == nullptr)24459 if (type_is_invalid(begin_base->value.type))
24472 return ir_unreach_error(ira);24460 return ira->codegen->invalid_instruction;
24461 ir_assert(begin_base->id == IrInstructionIdSuspendBegin, &instruction->base);
24462 IrInstructionSuspendBegin *begin = reinterpret_cast<IrInstructionSuspendBegin *>(begin_base);
2447324463
24474 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);24464 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
24475 ir_assert(fn_entry != nullptr, &instruction->base);24465 ir_assert(fn_entry != nullptr, &instruction->base);
2447624466
24477 new_bb->resume_index = fn_entry->resume_blocks.length + coro_extra_resume_block_count;
24478
24479 fn_entry->resume_blocks.append(new_bb);
24480 if (fn_entry->inferred_async_node == nullptr) {24467 if (fn_entry->inferred_async_node == nullptr) {
24481 fn_entry->inferred_async_node = instruction->base.source_node;24468 fn_entry->inferred_async_node = instruction->base.source_node;
24482 }24469 }
2448324470
24484 ir_push_resume_block(ira, old_dest_block);24471 return ir_build_suspend_finish(&ira->new_irb, instruction->base.scope, instruction->base.source_node, begin);
24485
24486 IrInstruction *result = ir_build_suspend_br(&ira->new_irb,
24487 instruction->base.scope, instruction->base.source_node, new_bb);
24488 result->value.type = ira->codegen->builtin_types.entry_unreachable;
24489 return ir_finish_anal(ira, result);
24490}24472}
2449124473
24492static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstructionAwait *instruction) {24474static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstructionAwait *instruction) {
...@@ -24847,8 +24829,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction...@@ -24847,8 +24829,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
24847 return ir_analyze_instruction_union_init_named_field(ira, (IrInstructionUnionInitNamedField *)instruction);24829 return ir_analyze_instruction_union_init_named_field(ira, (IrInstructionUnionInitNamedField *)instruction);
24848 case IrInstructionIdSuspendBegin:24830 case IrInstructionIdSuspendBegin:
24849 return ir_analyze_instruction_suspend_begin(ira, (IrInstructionSuspendBegin *)instruction);24831 return ir_analyze_instruction_suspend_begin(ira, (IrInstructionSuspendBegin *)instruction);
24850 case IrInstructionIdSuspendBr:24832 case IrInstructionIdSuspendFinish:
24851 return ir_analyze_instruction_suspend_br(ira, (IrInstructionSuspendBr *)instruction);24833 return ir_analyze_instruction_suspend_finish(ira, (IrInstructionSuspendFinish *)instruction);
24852 case IrInstructionIdCoroResume:24834 case IrInstructionIdCoroResume:
24853 return ir_analyze_instruction_coro_resume(ira, (IrInstructionCoroResume *)instruction);24835 return ir_analyze_instruction_coro_resume(ira, (IrInstructionCoroResume *)instruction);
24854 case IrInstructionIdAwait:24836 case IrInstructionIdAwait:
...@@ -24986,7 +24968,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24986,7 +24968,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24986 case IrInstructionIdVectorToArray:24968 case IrInstructionIdVectorToArray:
24987 case IrInstructionIdResetResult:24969 case IrInstructionIdResetResult:
24988 case IrInstructionIdSuspendBegin:24970 case IrInstructionIdSuspendBegin:
24989 case IrInstructionIdSuspendBr:24971 case IrInstructionIdSuspendFinish:
24990 case IrInstructionIdCoroResume:24972 case IrInstructionIdCoroResume:
24991 case IrInstructionIdAwait:24973 case IrInstructionIdAwait:
24992 return true;24974 return true;
src/ir_print.cpp+4-6
...@@ -1534,10 +1534,8 @@ static void ir_print_suspend_begin(IrPrint *irp, IrInstructionSuspendBegin *inst...@@ -1534,10 +1534,8 @@ static void ir_print_suspend_begin(IrPrint *irp, IrInstructionSuspendBegin *inst
1534 fprintf(irp->f, "@suspendBegin()");1534 fprintf(irp->f, "@suspendBegin()");
1535}1535}
15361536
1537static void ir_print_suspend_br(IrPrint *irp, IrInstructionSuspendBr *instruction) {1537static void ir_print_suspend_finish(IrPrint *irp, IrInstructionSuspendFinish *instruction) {
1538 fprintf(irp->f, "@suspendBr(");1538 fprintf(irp->f, "@suspendFinish()");
1539 ir_print_other_block(irp, instruction->resume_block);
1540 fprintf(irp->f, ")");
1541}1539}
15421540
1543static void ir_print_coro_resume(IrPrint *irp, IrInstructionCoroResume *instruction) {1541static void ir_print_coro_resume(IrPrint *irp, IrInstructionCoroResume *instruction) {
...@@ -2025,8 +2023,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -2025,8 +2023,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
2025 case IrInstructionIdSuspendBegin:2023 case IrInstructionIdSuspendBegin:
2026 ir_print_suspend_begin(irp, (IrInstructionSuspendBegin *)instruction);2024 ir_print_suspend_begin(irp, (IrInstructionSuspendBegin *)instruction);
2027 break;2025 break;
2028 case IrInstructionIdSuspendBr:2026 case IrInstructionIdSuspendFinish:
2029 ir_print_suspend_br(irp, (IrInstructionSuspendBr *)instruction);2027 ir_print_suspend_finish(irp, (IrInstructionSuspendFinish *)instruction);
2030 break;2028 break;
2031 case IrInstructionIdCoroResume:2029 case IrInstructionIdCoroResume:
2032 ir_print_coro_resume(irp, (IrInstructionCoroResume *)instruction);2030 ir_print_coro_resume(irp, (IrInstructionCoroResume *)instruction);