| author | |
| committer | |
| log | c9b2210fcf58d9e99851ad2a6a1219c997cf0d82 |
| tree | b4976b37d6a29279abf003ffff47fe58707db169 |
| parent | 7101e583d6a752fa1145c13c6e1a58f36bd35f2d |
| signature |
See #30692 files changed, 33 insertions(+), 3 deletions(-)
src/analyze.cpp+21-2| ... | @@ -2538,6 +2538,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { | ... | @@ -2538,6 +2538,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { |
| 2538 | enum_type->data.enumeration.resolve_loop_flag = false; | 2538 | enum_type->data.enumeration.resolve_loop_flag = false; |
| 2539 | enum_type->data.enumeration.resolve_status = ResolveStatusSizeKnown; | 2539 | enum_type->data.enumeration.resolve_status = ResolveStatusSizeKnown; |
| 2540 | 2540 | ||
| 2541 | occupied_tag_values.deinit(); | ||
| 2542 | |||
| 2541 | return ErrorNone; | 2543 | return ErrorNone; |
| 2542 | } | 2544 | } |
| 2543 | 2545 | ||
| ... | @@ -5878,6 +5880,11 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { | ... | @@ -5878,6 +5880,11 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { |
| 5878 | fn->err_code_spill = &alloca_gen->base; | 5880 | fn->err_code_spill = &alloca_gen->base; |
| 5879 | } | 5881 | } |
| 5880 | 5882 | ||
| 5883 | ZigType *largest_call_frame_type = nullptr; | ||
| 5884 | // Later we'll change this to be largest_call_frame_type instead of void. | ||
| 5885 | IrInstruction *all_calls_alloca = ir_create_alloca(g, &fn->fndef_scope->base, fn->body_node, | ||
| 5886 | fn, g->builtin_types.entry_void, "@async_call_frame"); | ||
| 5887 | |||
| 5881 | for (size_t i = 0; i < fn->call_list.length; i += 1) { | 5888 | for (size_t i = 0; i < fn->call_list.length; i += 1) { |
| 5882 | IrInstructionCallGen *call = fn->call_list.at(i); | 5889 | IrInstructionCallGen *call = fn->call_list.at(i); |
| 5883 | if (call->new_stack != nullptr) { | 5890 | if (call->new_stack != nullptr) { |
| ... | @@ -5921,9 +5928,21 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { | ... | @@ -5921,9 +5928,21 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) { |
| 5921 | 5928 | ||
| 5922 | mark_suspension_point(call->base.scope); | 5929 | mark_suspension_point(call->base.scope); |
| 5923 | 5930 | ||
| 5924 | call->frame_result_loc = ir_create_alloca(g, call->base.scope, call->base.source_node, fn, | 5931 | if ((err = type_resolve(g, callee_frame_type, ResolveStatusSizeKnown))) { |
| 5925 | callee_frame_type, ""); | 5932 | return err; |
| 5933 | } | ||
| 5934 | if (largest_call_frame_type == nullptr || | ||
| 5935 | callee_frame_type->abi_size > largest_call_frame_type->abi_size) | ||
| 5936 | { | ||
| 5937 | largest_call_frame_type = callee_frame_type; | ||
| 5938 | } | ||
| 5939 | |||
| 5940 | call->frame_result_loc = all_calls_alloca; | ||
| 5926 | } | 5941 | } |
| 5942 | if (largest_call_frame_type != nullptr) { | ||
| 5943 | all_calls_alloca->value.type = get_pointer_to_type(g, largest_call_frame_type, false); | ||
| 5944 | } | ||
| 5945 | |||
| 5927 | // Since this frame is async, an await might represent a suspend point, and | 5946 | // Since this frame is async, an await might represent a suspend point, and |
| 5928 | // therefore need to spill. It also needs to mark expr scopes as having to spill. | 5947 | // therefore need to spill. It also needs to mark expr scopes as having to spill. |
| 5929 | // For example: foo() + await z | 5948 | // For example: foo() + await z |
src/codegen.cpp+12-1| ... | @@ -3863,6 +3863,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -3863,6 +3863,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 3863 | ZigList<ZigType *> gen_param_types = {}; | 3863 | ZigList<ZigType *> gen_param_types = {}; |
| 3864 | LLVMValueRef result_loc = instruction->result_loc ? ir_llvm_value(g, instruction->result_loc) : nullptr; | 3864 | LLVMValueRef result_loc = instruction->result_loc ? ir_llvm_value(g, instruction->result_loc) : nullptr; |
| 3865 | LLVMValueRef zero = LLVMConstNull(usize_type_ref); | 3865 | LLVMValueRef zero = LLVMConstNull(usize_type_ref); |
| 3866 | LLVMValueRef frame_result_loc_uncasted = nullptr; | ||
| 3866 | LLVMValueRef frame_result_loc; | 3867 | LLVMValueRef frame_result_loc; |
| 3867 | LLVMValueRef awaiter_init_val; | 3868 | LLVMValueRef awaiter_init_val; |
| 3868 | LLVMValueRef ret_ptr; | 3869 | LLVMValueRef ret_ptr; |
| ... | @@ -3871,7 +3872,10 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -3871,7 +3872,10 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 3871 | if (instruction->modifier == CallModifierAsync) { | 3872 | if (instruction->modifier == CallModifierAsync) { |
| 3872 | frame_result_loc = result_loc; | 3873 | frame_result_loc = result_loc; |
| 3873 | } else { | 3874 | } else { |
| 3874 | frame_result_loc = ir_llvm_value(g, instruction->frame_result_loc); | 3875 | frame_result_loc_uncasted = ir_llvm_value(g, instruction->frame_result_loc); |
| 3876 | src_assert(instruction->fn_entry != nullptr, instruction->base.source_node); | ||
| 3877 | frame_result_loc = LLVMBuildBitCast(g->builder, frame_result_loc_uncasted, | ||
| 3878 | LLVMPointerType(get_llvm_type(g, instruction->fn_entry->frame_type), 0), ""); | ||
| 3875 | } | 3879 | } |
| 3876 | } else { | 3880 | } else { |
| 3877 | if (instruction->new_stack->value.type->id == ZigTypeIdPointer && | 3881 | if (instruction->new_stack->value.type->id == ZigTypeIdPointer && |
| ... | @@ -4138,6 +4142,13 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -4138,6 +4142,13 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 4138 | } | 4142 | } |
| 4139 | } | 4143 | } |
| 4140 | 4144 | ||
| 4145 | if (frame_result_loc_uncasted != nullptr && instruction->fn_entry != nullptr) { | ||
| 4146 | // Instead of a spill, we do the bitcast again. The uncasted LLVM IR instruction will | ||
| 4147 | // be an Alloca from the entry block, so it does not need to be spilled. | ||
| 4148 | frame_result_loc = LLVMBuildBitCast(g->builder, frame_result_loc_uncasted, | ||
| 4149 | LLVMPointerType(get_llvm_type(g, instruction->fn_entry->frame_type), 0), ""); | ||
| 4150 | } | ||
| 4151 | |||
| 4141 | LLVMValueRef result_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, ""); | 4152 | LLVMValueRef result_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, ""); |
| 4142 | return LLVMBuildLoad(g->builder, result_ptr, ""); | 4153 | return LLVMBuildLoad(g->builder, result_ptr, ""); |
| 4143 | } | 4154 | } |