authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-23 18:54:45-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-23 18:54:45-04:00
log7e9760de10e05a4c2a7bae4c4bb945351b9ae0cb
treeb755e4c57ec91d62f0ce60a12001dac03bd286ad
parent317d1ecb2cf3234b0259daf6cc0baac7d86264e2
signaturelock-open Commit is signed but in an unrecognized format.

inferring async from async calls


6 files changed, 123 insertions(+), 28 deletions(-)

build.zig+3-1
...@@ -375,7 +375,9 @@ fn addLibUserlandStep(b: *Builder) void {...@@ -375,7 +375,9 @@ fn addLibUserlandStep(b: *Builder) void {
375 artifact.bundle_compiler_rt = true;375 artifact.bundle_compiler_rt = true;
376 artifact.setTarget(builtin.arch, builtin.os, builtin.abi);376 artifact.setTarget(builtin.arch, builtin.os, builtin.abi);
377 artifact.linkSystemLibrary("c");377 artifact.linkSystemLibrary("c");
378 artifact.linkSystemLibrary("ntdll");378 if (builtin.os == .windows) {
379 artifact.linkSystemLibrary("ntdll");
380 }
379 const libuserland_step = b.step("libuserland", "Build the userland compiler library for use in stage1");381 const libuserland_step = b.step("libuserland", "Build the userland compiler library for use in stage1");
380 libuserland_step.dependOn(&artifact.step);382 libuserland_step.dependOn(&artifact.step);
381383
src/all_types.hpp+7
...@@ -1336,6 +1336,11 @@ struct GlobalExport {...@@ -1336,6 +1336,11 @@ struct GlobalExport {
1336 GlobalLinkageId linkage;1336 GlobalLinkageId linkage;
1337};1337};
13381338
1339struct FnCall {
1340 AstNode *source_node;
1341 ZigFn *callee;
1342};
1343
1339struct ZigFn {1344struct ZigFn {
1340 CodeGen *codegen;1345 CodeGen *codegen;
1341 LLVMValueRef llvm_value;1346 LLVMValueRef llvm_value;
...@@ -1379,8 +1384,10 @@ struct ZigFn {...@@ -1379,8 +1384,10 @@ struct ZigFn {
1379 AstNode *set_alignstack_node;1384 AstNode *set_alignstack_node;
13801385
1381 AstNode *set_cold_node;1386 AstNode *set_cold_node;
1387 const AstNode *inferred_async_node;
13821388
1383 ZigList<GlobalExport> export_list;1389 ZigList<GlobalExport> export_list;
1390 ZigList<FnCall> call_list;
13841391
1385 LLVMValueRef valgrind_client_request_array;1392 LLVMValueRef valgrind_client_request_array;
1386 LLVMBasicBlockRef preamble_llvm_block;1393 LLVMBasicBlockRef preamble_llvm_block;
src/analyze.cpp+81-19
...@@ -31,6 +31,11 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r...@@ -31,6 +31,11 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
31static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, ScopeDecls *dest_decls_scope);31static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, ScopeDecls *dest_decls_scope);
32static void resolve_use_decl(CodeGen *g, TldUsingNamespace *tld_using_namespace, ScopeDecls *dest_decls_scope);32static void resolve_use_decl(CodeGen *g, TldUsingNamespace *tld_using_namespace, ScopeDecls *dest_decls_scope);
3333
34// nullptr means not analyzed yet; this one means currently being analyzed
35static const AstNode *inferred_async_checking = reinterpret_cast<AstNode *>(0x1);
36// this one means analyzed and it's not async
37static const AstNode *inferred_async_none = reinterpret_cast<AstNode *>(0x2);
38
34static bool is_top_level_struct(ZigType *import) {39static bool is_top_level_struct(ZigType *import) {
35 return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr;40 return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr;
36}41}
...@@ -1892,8 +1897,12 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {...@@ -1892,8 +1897,12 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
1892 field_names.append("resume_index");1897 field_names.append("resume_index");
1893 field_types.append(g->builtin_types.entry_usize);1898 field_types.append(g->builtin_types.entry_usize);
18941899
1895 for (size_t arg_i = 0; arg_i < fn->type_entry->data.fn.fn_type_id.param_count; arg_i += 1) {1900 FnTypeId *fn_type_id = &fn->type_entry->data.fn.fn_type_id;
1896 FnTypeParamInfo *param_info = &fn->type_entry->data.fn.fn_type_id.param_info[arg_i];1901 field_names.append("result");
1902 field_types.append(fn_type_id->return_type);
1903
1904 for (size_t arg_i = 0; arg_i < fn_type_id->param_count; arg_i += 1) {
1905 FnTypeParamInfo *param_info = &fn_type_id->param_info[arg_i];
1897 AstNode *param_decl_node = get_param_decl_node(fn, arg_i);1906 AstNode *param_decl_node = get_param_decl_node(fn, arg_i);
1898 Buf *param_name;1907 Buf *param_name;
1899 bool is_var_args = param_decl_node && param_decl_node->data.param_decl.is_var_args;1908 bool is_var_args = param_decl_node && param_decl_node->data.param_decl.is_var_args;
...@@ -2796,6 +2805,16 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -2796,6 +2805,16 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
2796 g->fn_defs.append(fn_table_entry);2805 g->fn_defs.append(fn_table_entry);
2797 }2806 }
27982807
2808 switch (fn_table_entry->type_entry->data.fn.fn_type_id.cc) {
2809 case CallingConventionAsync:
2810 fn_table_entry->inferred_async_node = fn_table_entry->proto_node;
2811 break;
2812 case CallingConventionUnspecified:
2813 break;
2814 default:
2815 fn_table_entry->inferred_async_node = inferred_async_none;
2816 }
2817
2799 if (scope_is_root_decls(tld_fn->base.parent_scope) &&2818 if (scope_is_root_decls(tld_fn->base.parent_scope) &&
2800 (import == g->root_import || import->data.structure.root_struct->package == g->panic_package))2819 (import == g->root_import || import->data.structure.root_struct->package == g->panic_package))
2801 {2820 {
...@@ -3767,6 +3786,55 @@ bool resolve_inferred_error_set(CodeGen *g, ZigType *err_set_type, AstNode *sour...@@ -3767,6 +3786,55 @@ bool resolve_inferred_error_set(CodeGen *g, ZigType *err_set_type, AstNode *sour
3767 return true;3786 return true;
3768}3787}
37693788
3789static void resolve_async_fn_frame(CodeGen *g, ZigFn *fn) {
3790 ZigType *frame_type = get_coro_frame_type(g, fn);
3791 Error err;
3792 if ((err = type_resolve(g, frame_type, ResolveStatusSizeKnown))) {
3793 fn->anal_state = FnAnalStateInvalid;
3794 return;
3795 }
3796}
3797
3798bool fn_is_async(ZigFn *fn) {
3799 assert(fn->inferred_async_node != nullptr);
3800 assert(fn->inferred_async_node != inferred_async_checking);
3801 return fn->inferred_async_node != inferred_async_none;
3802}
3803
3804// This function resolves functions being inferred async.
3805static void analyze_fn_async(CodeGen *g, ZigFn *fn) {
3806 if (fn->inferred_async_node == inferred_async_checking) {
3807 // TODO call graph cycle detected, disallow the recursion
3808 fn->inferred_async_node = inferred_async_none;
3809 return;
3810 }
3811 if (fn->inferred_async_node == inferred_async_none) {
3812 return;
3813 }
3814 if (fn->inferred_async_node != nullptr) {
3815 resolve_async_fn_frame(g, fn);
3816 return;
3817 }
3818 fn->inferred_async_node = inferred_async_checking;
3819 for (size_t i = 0; i < fn->call_list.length; i += 1) {
3820 FnCall *call = &fn->call_list.at(i);
3821 if (call->callee->type_entry->data.fn.fn_type_id.cc != CallingConventionUnspecified)
3822 continue;
3823 assert(call->callee->anal_state == FnAnalStateComplete);
3824 analyze_fn_async(g, call->callee);
3825 if (call->callee->anal_state == FnAnalStateInvalid) {
3826 fn->anal_state = FnAnalStateInvalid;
3827 return;
3828 }
3829 if (fn_is_async(call->callee)) {
3830 fn->inferred_async_node = call->source_node;
3831 resolve_async_fn_frame(g, fn);
3832 return;
3833 }
3834 }
3835 fn->inferred_async_node = inferred_async_none;
3836}
3837
3770static void analyze_fn_ir(CodeGen *g, ZigFn *fn_table_entry, AstNode *return_type_node) {3838static void analyze_fn_ir(CodeGen *g, ZigFn *fn_table_entry, AstNode *return_type_node) {
3771 ZigType *fn_type = fn_table_entry->type_entry;3839 ZigType *fn_type = fn_table_entry->type_entry;
3772 assert(!fn_type->data.fn.is_generic);3840 assert(!fn_type->data.fn.is_generic);
...@@ -3824,17 +3892,7 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn_table_entry, AstNode *return_typ...@@ -3824,17 +3892,7 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn_table_entry, AstNode *return_typ
3824 ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);3892 ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);
3825 fprintf(stderr, "}\n");3893 fprintf(stderr, "}\n");
3826 }3894 }
3827
3828 fn_table_entry->anal_state = FnAnalStateComplete;3895 fn_table_entry->anal_state = FnAnalStateComplete;
3829
3830 if (fn_table_entry->resume_blocks.length != 0) {
3831 ZigType *frame_type = get_coro_frame_type(g, fn_table_entry);
3832 Error err;
3833 if ((err = type_resolve(g, frame_type, ResolveStatusSizeKnown))) {
3834 fn_table_entry->anal_state = FnAnalStateInvalid;
3835 return;
3836 }
3837 }
3838}3896}
38393897
3840static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {3898static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
...@@ -4004,6 +4062,16 @@ void semantic_analyze(CodeGen *g) {...@@ -4004,6 +4062,16 @@ void semantic_analyze(CodeGen *g) {
4004 analyze_fn_body(g, fn_entry);4062 analyze_fn_body(g, fn_entry);
4005 }4063 }
4006 }4064 }
4065
4066 if (g->errors.length != 0) {
4067 return;
4068 }
4069
4070 // second pass over functions for detecting async
4071 for (g->fn_defs_index = 0; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) {
4072 ZigFn *fn_entry = g->fn_defs.at(g->fn_defs_index);
4073 analyze_fn_async(g, fn_entry);
4074 }
4007}4075}
40084076
4009ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {4077ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
...@@ -7173,11 +7241,7 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn) {...@@ -7173,11 +7241,7 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn) {
7173 if (fn->raw_di_type != nullptr) return;7241 if (fn->raw_di_type != nullptr) return;
71747242
7175 ZigType *fn_type = fn->type_entry;7243 ZigType *fn_type = fn->type_entry;
7176 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;7244 if (!fn_is_async(fn)) {
7177 bool cc_async = fn_type_id->cc == CallingConventionAsync;
7178 bool inferred_async = fn->resume_blocks.length != 0;
7179 bool is_async = cc_async || inferred_async;
7180 if (!is_async) {
7181 resolve_llvm_types_fn_type(g, fn_type);7245 resolve_llvm_types_fn_type(g, fn_type);
7182 fn->raw_type_ref = fn_type->data.fn.raw_type_ref;7246 fn->raw_type_ref = fn_type->data.fn.raw_type_ref;
7183 fn->raw_di_type = fn_type->data.fn.raw_di_type;7247 fn->raw_di_type = fn_type->data.fn.raw_di_type;
...@@ -7223,8 +7287,6 @@ static void resolve_llvm_types_anyerror(CodeGen *g) {...@@ -7223,8 +7287,6 @@ static void resolve_llvm_types_anyerror(CodeGen *g) {
7223}7287}
72247288
7225static void resolve_llvm_types_coro_frame(CodeGen *g, ZigType *frame_type, ResolveStatus wanted_resolve_status) {7289static void resolve_llvm_types_coro_frame(CodeGen *g, ZigType *frame_type, ResolveStatus wanted_resolve_status) {
7226 if (frame_type->llvm_di_type != nullptr) return;
7227
7228 resolve_llvm_types_struct(g, frame_type->data.frame.locals_struct, wanted_resolve_status);7290 resolve_llvm_types_struct(g, frame_type->data.frame.locals_struct, wanted_resolve_status);
7229 frame_type->llvm_type = frame_type->data.frame.locals_struct->llvm_type;7291 frame_type->llvm_type = frame_type->data.frame.locals_struct->llvm_type;
7230 frame_type->llvm_di_type = frame_type->data.frame.locals_struct->llvm_di_type;7292 frame_type->llvm_di_type = frame_type->data.frame.locals_struct->llvm_di_type;
src/analyze.hpp+1
...@@ -248,5 +248,6 @@ bool is_container(ZigType *type_entry);...@@ -248,5 +248,6 @@ bool is_container(ZigType *type_entry);
248ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name);248ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name);
249249
250void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);250void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
251bool fn_is_async(ZigFn *fn);
251252
252#endif253#endif
src/codegen.cpp+12-8
...@@ -371,7 +371,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {...@@ -371,7 +371,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
371 symbol_name = buf_sprintf("\x01_%s", buf_ptr(symbol_name));371 symbol_name = buf_sprintf("\x01_%s", buf_ptr(symbol_name));
372 }372 }
373373
374 bool is_async = fn_table_entry->resume_blocks.length != 0 || cc == CallingConventionAsync;374 bool is_async = fn_is_async(fn_table_entry);
375375
376376
377 ZigType *fn_type = fn_table_entry->type_entry;377 ZigType *fn_type = fn_table_entry->type_entry;
...@@ -1847,7 +1847,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_...@@ -1847,7 +1847,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
1847 }1847 }
1848 case FnWalkIdInits: {1848 case FnWalkIdInits: {
1849 clear_debug_source_node(g);1849 clear_debug_source_node(g);
1850 if (fn_walk->data.inits.fn->resume_blocks.length == 0) {1850 if (!fn_is_async(fn_walk->data.inits.fn)) {
1851 LLVMValueRef arg = LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i);1851 LLVMValueRef arg = LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i);
1852 LLVMTypeRef ptr_to_int_type_ref = LLVMPointerType(LLVMIntType((unsigned)ty_size * 8), 0);1852 LLVMTypeRef ptr_to_int_type_ref = LLVMPointerType(LLVMIntType((unsigned)ty_size * 8), 0);
1853 LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, var->value_ref, ptr_to_int_type_ref, "");1853 LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, var->value_ref, ptr_to_int_type_ref, "");
...@@ -1945,7 +1945,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {...@@ -1945,7 +1945,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
1945 assert(variable);1945 assert(variable);
1946 assert(variable->value_ref);1946 assert(variable->value_ref);
19471947
1948 if (!handle_is_ptr(variable->var_type) && fn_walk->data.inits.fn->resume_blocks.length == 0) {1948 if (!handle_is_ptr(variable->var_type) && !fn_is_async(fn_walk->data.inits.fn)) {
1949 clear_debug_source_node(g);1949 clear_debug_source_node(g);
1950 ZigType *fn_type = fn_table_entry->type_entry;1950 ZigType *fn_type = fn_table_entry->type_entry;
1951 unsigned gen_arg_index = fn_type->data.fn.gen_param_info[variable->src_arg_index].gen_index;1951 unsigned gen_arg_index = fn_type->data.fn.gen_param_info[variable->src_arg_index].gen_index;
...@@ -1986,7 +1986,7 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut...@@ -1986,7 +1986,7 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut
1986}1986}
19871987
1988static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) {1988static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) {
1989 if (g->cur_fn->resume_blocks.length != 0) {1989 if (fn_is_async(g->cur_fn)) {
1990 if (ir_want_runtime_safety(g, &return_instruction->base)) {1990 if (ir_want_runtime_safety(g, &return_instruction->base)) {
1991 LLVMValueRef locals_ptr = g->cur_ret_ptr;1991 LLVMValueRef locals_ptr = g->cur_ret_ptr;
1992 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, locals_ptr, coro_resume_index_index, "");1992 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, locals_ptr, coro_resume_index_index, "");
...@@ -3387,8 +3387,10 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3387,8 +3387,10 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3387 LLVMValueRef result;3387 LLVMValueRef result;
33883388
3389 if (instruction->is_async) {3389 if (instruction->is_async) {
3390 size_t ret_1_or_0 = type_has_bits(fn_type->data.fn.fn_type_id.return_type) ? 1 : 0;
3390 for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) {3391 for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) {
3391 LLVMValueRef arg_ptr = LLVMBuildStructGEP(g->builder, result_loc, coro_arg_start + arg_i, "");3392 LLVMValueRef arg_ptr = LLVMBuildStructGEP(g->builder, result_loc,
3393 coro_arg_start + ret_1_or_0 + arg_i, "");
3392 LLVMBuildStore(g->builder, gen_param_values.at(arg_i), arg_ptr);3394 LLVMBuildStore(g->builder, gen_param_values.at(arg_i), arg_ptr);
3393 }3395 }
3394 ZigLLVMBuildCall(g->builder, fn_val, &result_loc, 1, llvm_cc, fn_inline, "");3396 ZigLLVMBuildCall(g->builder, fn_val, &result_loc, 1, llvm_cc, fn_inline, "");
...@@ -5983,7 +5985,7 @@ static void build_all_basic_blocks(CodeGen *g, ZigFn *fn) {...@@ -5983,7 +5985,7 @@ static void build_all_basic_blocks(CodeGen *g, ZigFn *fn) {
5983 assert(executable->basic_block_list.length > 0);5985 assert(executable->basic_block_list.length > 0);
5984 LLVMValueRef fn_val = fn_llvm_value(g, fn);5986 LLVMValueRef fn_val = fn_llvm_value(g, fn);
5985 LLVMBasicBlockRef first_bb = nullptr;5987 LLVMBasicBlockRef first_bb = nullptr;
5986 if (fn->resume_blocks.length != 0) {5988 if (fn_is_async(fn)) {
5987 first_bb = LLVMAppendBasicBlock(fn_val, "AsyncSwitch");5989 first_bb = LLVMAppendBasicBlock(fn_val, "AsyncSwitch");
5988 fn->preamble_llvm_block = first_bb;5990 fn->preamble_llvm_block = first_bb;
5989 }5991 }
...@@ -6171,7 +6173,7 @@ static void do_code_gen(CodeGen *g) {...@@ -6171,7 +6173,7 @@ static void do_code_gen(CodeGen *g) {
6171 build_all_basic_blocks(g, fn_table_entry);6173 build_all_basic_blocks(g, fn_table_entry);
6172 clear_debug_source_node(g);6174 clear_debug_source_node(g);
61736175
6174 bool is_async = cc == CallingConventionAsync || fn_table_entry->resume_blocks.length != 0;6176 bool is_async = fn_is_async(fn_table_entry);
61756177
6176 if (want_sret || is_async) {6178 if (want_sret || is_async) {
6177 g->cur_ret_ptr = LLVMGetParam(fn, 0);6179 g->cur_ret_ptr = LLVMGetParam(fn, 0);
...@@ -6261,7 +6263,9 @@ static void do_code_gen(CodeGen *g) {...@@ -6261,7 +6263,9 @@ static void do_code_gen(CodeGen *g) {
6261 fn_walk_var.data.vars.var = var;6263 fn_walk_var.data.vars.var = var;
6262 iter_function_params_c_abi(g, fn_table_entry->type_entry, &fn_walk_var, var->src_arg_index);6264 iter_function_params_c_abi(g, fn_table_entry->type_entry, &fn_walk_var, var->src_arg_index);
6263 } else if (is_async) {6265 } else if (is_async) {
6264 var->value_ref = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, coro_arg_start + var_i, "");6266 size_t ret_1_or_0 = type_has_bits(fn_type_id->return_type) ? 1 : 0;
6267 var->value_ref = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr,
6268 coro_arg_start + ret_1_or_0 + var_i, "");
6265 if (var->decl_node) {6269 if (var->decl_node) {
6266 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),6270 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
6267 buf_ptr(&var->name), import->data.structure.root_struct->di_file,6271 buf_ptr(&var->name), import->data.structure.root_struct->di_file,
src/ir.cpp+19
...@@ -15383,6 +15383,13 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15383,6 +15383,13 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15383 zig_panic("TODO async call");15383 zig_panic("TODO async call");
15384 }15384 }
1538515385
15386 if (!call_instruction->is_async) {
15387 if (impl_fn_type_id->cc == CallingConventionAsync && parent_fn_entry->inferred_async_node == nullptr) {
15388 parent_fn_entry->inferred_async_node = fn_ref->source_node;
15389 }
15390 parent_fn_entry->call_list.append({call_instruction->base.source_node, impl_fn});
15391 }
15392
15386 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base,15393 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base,
15387 impl_fn, nullptr, impl_param_count, casted_args, fn_inline,15394 impl_fn, nullptr, impl_param_count, casted_args, fn_inline,
15388 call_instruction->is_async, casted_new_stack, result_loc,15395 call_instruction->is_async, casted_new_stack, result_loc,
...@@ -15458,6 +15465,15 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15458,6 +15465,15 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15458 return ira->codegen->invalid_instruction;15465 return ira->codegen->invalid_instruction;
15459 }15466 }
1546015467
15468 if (!call_instruction->is_async) {
15469 if (fn_type_id->cc == CallingConventionAsync && parent_fn_entry->inferred_async_node == nullptr) {
15470 parent_fn_entry->inferred_async_node = fn_ref->source_node;
15471 }
15472 if (fn_entry != nullptr) {
15473 parent_fn_entry->call_list.append({call_instruction->base.source_node, fn_entry});
15474 }
15475 }
15476
15461 if (call_instruction->is_async) {15477 if (call_instruction->is_async) {
15462 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref,15478 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref,
15463 casted_args, call_param_count);15479 casted_args, call_param_count);
...@@ -24142,6 +24158,9 @@ static IrInstruction *ir_analyze_instruction_suspend_br(IrAnalyze *ira, IrInstru...@@ -24142,6 +24158,9 @@ static IrInstruction *ir_analyze_instruction_suspend_br(IrAnalyze *ira, IrInstru
24142 new_bb->resume_index = fn_entry->resume_blocks.length + 2;24158 new_bb->resume_index = fn_entry->resume_blocks.length + 2;
2414324159
24144 fn_entry->resume_blocks.append(new_bb);24160 fn_entry->resume_blocks.append(new_bb);
24161 if (fn_entry->inferred_async_node == nullptr) {
24162 fn_entry->inferred_async_node = instruction->base.source_node;
24163 }
2414524164
24146 ir_push_resume_block(ira, old_dest_block);24165 ir_push_resume_block(ira, old_dest_block);
2414724166