| author | |
| committer | |
| log | fbf21efd24bf812e0fd52a5917708a4c45f05b5e |
| tree | 96aeb27f9a24d57b477c763073b2f2198df2a05c |
| parent | 042914de75f7ccf520fb2058372cc3f255ccfecb |
| signature |
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 { |
| 1386 | 1386 | ||
| 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; | ||
| 1390 | 1389 | ||
| 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 { |
| 2114 | struct ScopeSuspend { | 2114 | struct ScopeSuspend { |
| 2115 | Scope base; | 2115 | Scope base; |
| 2116 | 2116 | ||
| 2117 | IrBasicBlock *resume_block; | ||
| 2118 | bool reported_err; | 2117 | bool reported_err; |
| 2119 | }; | 2118 | }; |
| 2120 | 2119 | ||
| ... | @@ -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 list | 2169 | // 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 to | 2173 | // 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 { |
| 3600 | struct IrInstructionSuspendBegin { | 3597 | struct IrInstructionSuspendBegin { |
| 3601 | IrInstruction base; | 3598 | IrInstruction base; |
| 3602 | 3599 | ||
| 3603 | IrBasicBlock *resume_block; | 3600 | LLVMBasicBlockRef resume_bb; |
| 3604 | }; | 3601 | }; |
| 3605 | 3602 | ||
| 3606 | struct IrInstructionSuspendBr { | 3603 | struct IrInstructionSuspendFinish { |
| 3607 | IrInstruction base; | 3604 | IrInstruction base; |
| 3608 | 3605 | ||
| 3609 | IrBasicBlock *resume_block; | 3606 | IrInstructionSuspendBegin *begin; |
| 3610 | }; | 3607 | }; |
| 3611 | 3608 | ||
| 3612 | struct IrInstructionAwait { | 3609 | struct 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; |
| 3710 | static const size_t coro_awaiter_index = 2; | 3707 | static const size_t coro_awaiter_index = 2; |
| 3711 | static const size_t coro_arg_start = 3; | 3708 | static const size_t coro_arg_start = 3; |
| 3712 | 3709 | ||
| 3713 | // one for the Entry block, resume blocks are indexed after that. | ||
| 3714 | static 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 function | 3710 | // 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. |
| 3718 | static const size_t stack_trace_ptr_count = 32; | 3712 | static 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); |
| 3662 | 3662 | ||
| 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); |
| 3668 | 3668 | ||
| ... | @@ -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 | } |
| 5160 | 5164 | ||
| 5161 | static LLVMValueRef ir_render_suspend_br(CodeGen *g, IrExecutable *executable, | 5165 | static 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 | } |
| 5167 | 5174 | ||
| ... | @@ -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 |
| 5173 | 5180 | ||
| 5174 | // Prepare to be suspended | 5181 | // 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); |
| 5554 | 5561 | ||
| 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 | } |
| 6758 | 6756 | ||
| 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; |
| 6783 | 6782 | ||
| 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); |
| 6786 | 6785 | 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 parameters | 6790 | // 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 | } |
| 1051 | 1051 | ||
| 1052 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendBr *) { | 1052 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendFinish *) { |
| 1053 | return IrInstructionIdSuspendBr; | 1053 | return IrInstructionIdSuspendFinish; |
| 1054 | } | 1054 | } |
| 1055 | 1055 | ||
| 1056 | static constexpr IrInstructionId ir_instruction_id(IrInstructionAwait *) { | 1056 | static 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 | } |
| 3262 | 3262 | ||
| 3263 | static IrInstruction *ir_build_suspend_begin(IrBuilder *irb, Scope *scope, AstNode *source_node, | 3263 | static 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); | ||
| 3271 | 3266 | ||
| 3272 | return &instruction->base; | 3267 | return instruction; |
| 3273 | } | 3268 | } |
| 3274 | 3269 | ||
| 3275 | static IrInstruction *ir_build_suspend_br(IrBuilder *irb, Scope *scope, AstNode *source_node, | 3270 | static 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; | ||
| 3280 | 3276 | ||
| 3281 | ir_ref_bb(resume_block); | 3277 | ir_ref_instruction(&begin->base, irb->current_basic_block); |
| 3282 | 3278 | ||
| 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 | } |
| 7892 | 7888 | ||
| 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 | } |
| 7904 | 7896 | ||
| 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 | } |
| 7910 | 7899 | ||
| 7911 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, | 7900 | static 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 | } |
| 24459 | 24448 | ||
| 24460 | static IrInstruction *ir_analyze_instruction_suspend_begin(IrAnalyze *ira, IrInstructionSuspendBegin *instruction) { | 24449 | static 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 | } |
| 24466 | 24454 | ||
| 24467 | static IrInstruction *ir_analyze_instruction_suspend_br(IrAnalyze *ira, IrInstructionSuspendBr *instruction) { | 24455 | static IrInstruction *ir_analyze_instruction_suspend_finish(IrAnalyze *ira, |
| 24468 | IrBasicBlock *old_dest_block = instruction->resume_block; | 24456 | IrInstructionSuspendFinish *instruction) |
| 24469 | 24457 | { | |
| 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); | ||
| 24473 | 24463 | ||
| 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); |
| 24476 | 24466 | ||
| 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 | } |
| 24483 | 24470 | ||
| 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 | } |
| 24491 | 24473 | ||
| 24492 | static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstructionAwait *instruction) { | 24474 | static 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 | } |
| 1536 | 1536 | ||
| 1537 | static void ir_print_suspend_br(IrPrint *irp, IrInstructionSuspendBr *instruction) { | 1537 | static 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 | } |
| 1542 | 1540 | ||
| 1543 | static void ir_print_coro_resume(IrPrint *irp, IrInstructionCoroResume *instruction) { | 1541 | static 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); |