| ... | @@ -3327,6 +3327,92 @@ static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) { | ... | @@ -3327,6 +3327,92 @@ static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) { |
| 3327 | LLVMAddCallSiteAttribute(call_instr, 1, sret_attr); | 3327 | LLVMAddCallSiteAttribute(call_instr, 1, sret_attr); |
| 3328 | } | 3328 | } |
| 3329 | | 3329 | |
| | 3330 | static void render_async_spills(CodeGen *g) { |
| | 3331 | ZigType *fn_type = g->cur_fn->type_entry; |
| | 3332 | ZigType *import = get_scope_import(&g->cur_fn->fndef_scope->base); |
| | 3333 | size_t async_var_index = coro_arg_start + (type_has_bits(fn_type->data.fn.fn_type_id.return_type) ? 2 : 0); |
| | 3334 | for (size_t var_i = 0; var_i < g->cur_fn->variable_list.length; var_i += 1) { |
| | 3335 | ZigVar *var = g->cur_fn->variable_list.at(var_i); |
| | 3336 | |
| | 3337 | if (!type_has_bits(var->var_type)) { |
| | 3338 | continue; |
| | 3339 | } |
| | 3340 | if (ir_get_var_is_comptime(var)) |
| | 3341 | continue; |
| | 3342 | switch (type_requires_comptime(g, var->var_type)) { |
| | 3343 | case ReqCompTimeInvalid: |
| | 3344 | zig_unreachable(); |
| | 3345 | case ReqCompTimeYes: |
| | 3346 | continue; |
| | 3347 | case ReqCompTimeNo: |
| | 3348 | break; |
| | 3349 | } |
| | 3350 | if (var->src_arg_index == SIZE_MAX) { |
| | 3351 | continue; |
| | 3352 | } |
| | 3353 | |
| | 3354 | var->value_ref = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, async_var_index, |
| | 3355 | buf_ptr(&var->name)); |
| | 3356 | async_var_index += 1; |
| | 3357 | if (var->decl_node) { |
| | 3358 | var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope), |
| | 3359 | buf_ptr(&var->name), import->data.structure.root_struct->di_file, |
| | 3360 | (unsigned)(var->decl_node->line + 1), |
| | 3361 | get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0); |
| | 3362 | gen_var_debug_decl(g, var); |
| | 3363 | } |
| | 3364 | } |
| | 3365 | for (size_t alloca_i = 0; alloca_i < g->cur_fn->alloca_gen_list.length; alloca_i += 1) { |
| | 3366 | IrInstructionAllocaGen *instruction = g->cur_fn->alloca_gen_list.at(alloca_i); |
| | 3367 | ZigType *ptr_type = instruction->base.value.type; |
| | 3368 | assert(ptr_type->id == ZigTypeIdPointer); |
| | 3369 | ZigType *child_type = ptr_type->data.pointer.child_type; |
| | 3370 | if (!type_has_bits(child_type)) |
| | 3371 | continue; |
| | 3372 | if (instruction->base.ref_count == 0) |
| | 3373 | continue; |
| | 3374 | if (instruction->base.value.special != ConstValSpecialRuntime) { |
| | 3375 | if (const_ptr_pointee(nullptr, g, &instruction->base.value, nullptr)->special != |
| | 3376 | ConstValSpecialRuntime) |
| | 3377 | { |
| | 3378 | continue; |
| | 3379 | } |
| | 3380 | } |
| | 3381 | instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, async_var_index, |
| | 3382 | instruction->name_hint); |
| | 3383 | async_var_index += 1; |
| | 3384 | } |
| | 3385 | } |
| | 3386 | |
| | 3387 | static void render_async_var_decls(CodeGen *g, Scope *scope) { |
| | 3388 | render_async_spills(g); |
| | 3389 | for (;;) { |
| | 3390 | switch (scope->id) { |
| | 3391 | case ScopeIdCImport: |
| | 3392 | zig_unreachable(); |
| | 3393 | case ScopeIdFnDef: |
| | 3394 | return; |
| | 3395 | case ScopeIdVarDecl: { |
| | 3396 | ZigVar *var = reinterpret_cast<ScopeVarDecl *>(scope)->var; |
| | 3397 | if (var->ptr_instruction != nullptr) { |
| | 3398 | render_decl_var(g, var); |
| | 3399 | } |
| | 3400 | // fallthrough |
| | 3401 | } |
| | 3402 | case ScopeIdDecls: |
| | 3403 | case ScopeIdBlock: |
| | 3404 | case ScopeIdDefer: |
| | 3405 | case ScopeIdDeferExpr: |
| | 3406 | case ScopeIdLoop: |
| | 3407 | case ScopeIdSuspend: |
| | 3408 | case ScopeIdCompTime: |
| | 3409 | case ScopeIdRuntime: |
| | 3410 | scope = scope->parent; |
| | 3411 | continue; |
| | 3412 | } |
| | 3413 | } |
| | 3414 | } |
| | 3415 | |
| 3330 | static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCallGen *instruction) { | 3416 | static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCallGen *instruction) { |
| 3331 | LLVMValueRef fn_val; | 3417 | LLVMValueRef fn_val; |
| 3332 | ZigType *fn_type; | 3418 | ZigType *fn_type; |
| ... | @@ -3431,15 +3517,19 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr | ... | @@ -3431,15 +3517,19 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 3431 | ZigLLVMBuildCall(g->builder, fn_val, &frame_result_loc, 1, llvm_cc, fn_inline, ""); | 3517 | ZigLLVMBuildCall(g->builder, fn_val, &frame_result_loc, 1, llvm_cc, fn_inline, ""); |
| 3432 | return nullptr; | 3518 | return nullptr; |
| 3433 | } else if (callee_is_async) { | 3519 | } else if (callee_is_async) { |
| | 3520 | LLVMValueRef split_llvm_fn = make_fn_llvm_value(g, g->cur_fn); |
| 3434 | LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_fn_ptr_index, ""); | 3521 | LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_fn_ptr_index, ""); |
| 3435 | LLVMValueRef new_fn_ptr = instruction->resume_block->split_llvm_fn; | 3522 | LLVMBuildStore(g->builder, split_llvm_fn, fn_ptr_ptr); |
| 3436 | LLVMBuildStore(g->builder, new_fn_ptr, fn_ptr_ptr); | | |
| 3437 | | 3523 | |
| 3438 | LLVMValueRef call_inst = ZigLLVMBuildCall(g->builder, fn_val, &frame_result_loc, 1, llvm_cc, fn_inline, ""); | 3524 | LLVMValueRef call_inst = ZigLLVMBuildCall(g->builder, fn_val, &frame_result_loc, 1, llvm_cc, fn_inline, ""); |
| 3439 | ZigLLVMSetTailCall(call_inst); | 3525 | ZigLLVMSetTailCall(call_inst); |
| 3440 | LLVMBuildRetVoid(g->builder); | 3526 | LLVMBuildRetVoid(g->builder); |
| 3441 | | 3527 | |
| 3442 | LLVMPositionBuilderAtEnd(g->builder, instruction->resume_block->llvm_block); | 3528 | g->cur_fn_val = split_llvm_fn; |
| | 3529 | g->cur_ret_ptr = LLVMGetParam(split_llvm_fn, 0); |
| | 3530 | LLVMBasicBlockRef call_bb = LLVMAppendBasicBlock(split_llvm_fn, "CallResume"); |
| | 3531 | LLVMPositionBuilderAtEnd(g->builder, call_bb); |
| | 3532 | render_async_var_decls(g, instruction->base.scope); |
| 3443 | return nullptr; | 3533 | return nullptr; |
| 3444 | } | 3534 | } |
| 3445 | | 3535 | |
| ... | @@ -5193,92 +5283,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -5193,92 +5283,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 5193 | zig_unreachable(); | 5283 | zig_unreachable(); |
| 5194 | } | 5284 | } |
| 5195 | | 5285 | |
| 5196 | static void render_async_spills(CodeGen *g) { | | |
| 5197 | ZigType *fn_type = g->cur_fn->type_entry; | | |
| 5198 | ZigType *import = get_scope_import(&g->cur_fn->fndef_scope->base); | | |
| 5199 | size_t async_var_index = coro_arg_start + (type_has_bits(fn_type->data.fn.fn_type_id.return_type) ? 2 : 0); | | |
| 5200 | for (size_t var_i = 0; var_i < g->cur_fn->variable_list.length; var_i += 1) { | | |
| 5201 | ZigVar *var = g->cur_fn->variable_list.at(var_i); | | |
| 5202 | | | |
| 5203 | if (!type_has_bits(var->var_type)) { | | |
| 5204 | continue; | | |
| 5205 | } | | |
| 5206 | if (ir_get_var_is_comptime(var)) | | |
| 5207 | continue; | | |
| 5208 | switch (type_requires_comptime(g, var->var_type)) { | | |
| 5209 | case ReqCompTimeInvalid: | | |
| 5210 | zig_unreachable(); | | |
| 5211 | case ReqCompTimeYes: | | |
| 5212 | continue; | | |
| 5213 | case ReqCompTimeNo: | | |
| 5214 | break; | | |
| 5215 | } | | |
| 5216 | if (var->src_arg_index == SIZE_MAX) { | | |
| 5217 | continue; | | |
| 5218 | } | | |
| 5219 | | | |
| 5220 | var->value_ref = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, async_var_index, | | |
| 5221 | buf_ptr(&var->name)); | | |
| 5222 | async_var_index += 1; | | |
| 5223 | if (var->decl_node) { | | |
| 5224 | var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope), | | |
| 5225 | buf_ptr(&var->name), import->data.structure.root_struct->di_file, | | |
| 5226 | (unsigned)(var->decl_node->line + 1), | | |
| 5227 | get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0); | | |
| 5228 | gen_var_debug_decl(g, var); | | |
| 5229 | } | | |
| 5230 | } | | |
| 5231 | for (size_t alloca_i = 0; alloca_i < g->cur_fn->alloca_gen_list.length; alloca_i += 1) { | | |
| 5232 | IrInstructionAllocaGen *instruction = g->cur_fn->alloca_gen_list.at(alloca_i); | | |
| 5233 | ZigType *ptr_type = instruction->base.value.type; | | |
| 5234 | assert(ptr_type->id == ZigTypeIdPointer); | | |
| 5235 | ZigType *child_type = ptr_type->data.pointer.child_type; | | |
| 5236 | if (!type_has_bits(child_type)) | | |
| 5237 | continue; | | |
| 5238 | if (instruction->base.ref_count == 0) | | |
| 5239 | continue; | | |
| 5240 | if (instruction->base.value.special != ConstValSpecialRuntime) { | | |
| 5241 | if (const_ptr_pointee(nullptr, g, &instruction->base.value, nullptr)->special != | | |
| 5242 | ConstValSpecialRuntime) | | |
| 5243 | { | | |
| 5244 | continue; | | |
| 5245 | } | | |
| 5246 | } | | |
| 5247 | instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, async_var_index, | | |
| 5248 | instruction->name_hint); | | |
| 5249 | async_var_index += 1; | | |
| 5250 | } | | |
| 5251 | } | | |
| 5252 | | | |
| 5253 | static void render_async_var_decls(CodeGen *g, Scope *scope) { | | |
| 5254 | render_async_spills(g); | | |
| 5255 | for (;;) { | | |
| 5256 | switch (scope->id) { | | |
| 5257 | case ScopeIdCImport: | | |
| 5258 | zig_unreachable(); | | |
| 5259 | case ScopeIdFnDef: | | |
| 5260 | return; | | |
| 5261 | case ScopeIdVarDecl: { | | |
| 5262 | ZigVar *var = reinterpret_cast<ScopeVarDecl *>(scope)->var; | | |
| 5263 | if (var->ptr_instruction != nullptr) { | | |
| 5264 | render_decl_var(g, var); | | |
| 5265 | } | | |
| 5266 | // fallthrough | | |
| 5267 | } | | |
| 5268 | case ScopeIdDecls: | | |
| 5269 | case ScopeIdBlock: | | |
| 5270 | case ScopeIdDefer: | | |
| 5271 | case ScopeIdDeferExpr: | | |
| 5272 | case ScopeIdLoop: | | |
| 5273 | case ScopeIdSuspend: | | |
| 5274 | case ScopeIdCompTime: | | |
| 5275 | case ScopeIdRuntime: | | |
| 5276 | scope = scope->parent; | | |
| 5277 | continue; | | |
| 5278 | } | | |
| 5279 | } | | |
| 5280 | } | | |
| 5281 | | | |
| 5282 | static void ir_render(CodeGen *g, ZigFn *fn_entry) { | 5286 | static void ir_render(CodeGen *g, ZigFn *fn_entry) { |
| 5283 | assert(fn_entry); | 5287 | assert(fn_entry); |
| 5284 | | 5288 | |