From e9f5176cb39061056b8ae7fd3b600ee7ed699ad2 Mon Sep 17 00:00:00 2001 From: Benoit Vey Date: Wed, 21 Feb 2018 21:48:31 +0100 Subject: [PATCH] Use deferred reification during code generation (#2557) This change is a followup to abdcf2e and 884c62d. Instead of fully reifying each function before generating it, the code generator now reifies part of the function as needed. This further reduces the amount of AST duplication during compilation and will simplify the upcoming work on type-erased generics, which will in turn be used in the separate compilation work. --- src/libponyc/codegen/codegen.c | 6 +- src/libponyc/codegen/codegen.h | 3 +- src/libponyc/codegen/gencall.c | 87 ++++++++++++++-------- src/libponyc/codegen/gencontrol.c | 107 ++++++++++++++++++++++------ src/libponyc/codegen/gendesc.c | 2 +- src/libponyc/codegen/genexe.c | 2 +- src/libponyc/codegen/genfun.c | 103 ++++++++++++-------------- src/libponyc/codegen/genident.c | 20 ++++-- src/libponyc/codegen/genmatch.c | 59 +++++++++++---- src/libponyc/codegen/genoperator.c | 73 +++++++++++++------ src/libponyc/codegen/genprim.c | 22 +++--- src/libponyc/codegen/genreference.c | 67 +++++++++++------ src/libponyc/codegen/genserialise.c | 4 +- src/libponyc/codegen/gentype.c | 4 +- 14 files changed, 374 insertions(+), 185 deletions(-) diff --git a/src/libponyc/codegen/codegen.c b/src/libponyc/codegen/codegen.c index 7686a3cff2..0d668cb55c 100644 --- a/src/libponyc/codegen/codegen.c +++ b/src/libponyc/codegen/codegen.c @@ -977,12 +977,13 @@ LLVMValueRef codegen_addfun(compile_t* c, const char* name, LLVMTypeRef type, } void codegen_startfun(compile_t* c, LLVMValueRef fun, LLVMMetadataRef file, - LLVMMetadataRef scope, bool bare) + LLVMMetadataRef scope, deferred_reification_t* reify, bool bare) { compile_frame_t* frame = push_frame(c); frame->fun = fun; frame->is_function = true; + frame->reify = reify; frame->bare_function = bare; frame->di_file = file; frame->di_scope = scope; @@ -1006,6 +1007,7 @@ void codegen_pushscope(compile_t* c, ast_t* ast) compile_frame_t* frame = push_frame(c); frame->fun = frame->prev->fun; + frame->reify = frame->prev->reify; frame->bare_function = frame->prev->bare_function; frame->break_target = frame->prev->break_target; frame->break_novalue_target = frame->prev->break_novalue_target; @@ -1111,6 +1113,7 @@ void codegen_pushloop(compile_t* c, LLVMBasicBlockRef continue_target, compile_frame_t* frame = push_frame(c); frame->fun = frame->prev->fun; + frame->reify = frame->prev->reify; frame->bare_function = frame->prev->bare_function; frame->break_target = break_target; frame->break_novalue_target = break_novalue_target; @@ -1130,6 +1133,7 @@ void codegen_pushtry(compile_t* c, LLVMBasicBlockRef invoke_target) compile_frame_t* frame = push_frame(c); frame->fun = frame->prev->fun; + frame->reify = frame->prev->reify; frame->bare_function = frame->prev->bare_function; frame->break_target = frame->prev->break_target; frame->break_novalue_target = frame->prev->break_novalue_target; diff --git a/src/libponyc/codegen/codegen.h b/src/libponyc/codegen/codegen.h index c5ed914301..2b4830b00e 100644 --- a/src/libponyc/codegen/codegen.h +++ b/src/libponyc/codegen/codegen.h @@ -79,6 +79,7 @@ typedef struct compile_frame_t bool is_function; bool early_termination; bool bare_function; + deferred_reification_t* reify; struct compile_frame_t* prev; } compile_frame_t; @@ -240,7 +241,7 @@ LLVMValueRef codegen_addfun(compile_t* c, const char* name, LLVMTypeRef type, bool pony_abi); void codegen_startfun(compile_t* c, LLVMValueRef fun, LLVMMetadataRef file, - LLVMMetadataRef scope, bool bare); + LLVMMetadataRef scope, deferred_reification_t* reify, bool bare); void codegen_finishfun(compile_t* c); diff --git a/src/libponyc/codegen/gencall.c b/src/libponyc/codegen/gencall.c index 681584711a..ee127285c5 100644 --- a/src/libponyc/codegen/gencall.c +++ b/src/libponyc/codegen/gencall.c @@ -214,17 +214,23 @@ static bool special_case_call(compile_t* c, ast_t* ast, LLVMValueRef* value) return false; AST_GET_CHILDREN(postfix, receiver, method); - ast_t* receiver_type = ast_type(receiver); + ast_t* receiver_type = deferred_reify(c->frame->reify, ast_type(receiver), + c->opt); - if(ast_id(receiver_type) != TK_NOMINAL) - return false; + const char* name = NULL; - AST_GET_CHILDREN(receiver_type, package, id); + if(ast_id(receiver_type) == TK_NOMINAL) + { + AST_GET_CHILDREN(receiver_type, package, id); - if(ast_name(package) != c->str_builtin) - return false; + if(ast_name(package) == c->str_builtin) + name = ast_name(id); + } + + ast_free_unattached(receiver_type); - const char* name = ast_name(id); + if(name == NULL) + return false; if(name == c->str_Bool) return special_case_operator(c, ast, value, true, true); @@ -478,7 +484,7 @@ LLVMValueRef gen_funptr(compile_t* c, ast_t* ast) LLVMValueRef value = gen_expr(c, receiver); // Get the receiver type. - ast_t* type = ast_type(receiver); + ast_t* type = deferred_reify(c->frame->reify, ast_type(receiver), c->opt); reach_type_t* t = reach_type(c->reach, type); pony_assert(t != NULL); @@ -487,6 +493,8 @@ LLVMValueRef gen_funptr(compile_t* c, ast_t* ast) reach_method_t* m = reach_method(t, cap, name, typeargs); LLVMValueRef funptr = dispatch_function(c, t, m, value); + ast_free_unattached(type); + if((m->cap != TK_AT) && (c->linkage != LLVMExternalLinkage)) { // We must reset the function linkage and calling convention since we're @@ -535,13 +543,18 @@ void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[], size_t args_buf_size = (m->param_count + 1) * sizeof(LLVMValueRef); LLVMValueRef* cast_args = (LLVMValueRef*)ponyint_pool_alloc_size(args_buf_size); + size_t arg_types_buf_size = m->param_count * sizeof(ast_t*); + ast_t** arg_types = (ast_t**)ponyint_pool_alloc_size(arg_types_buf_size); ast_t* arg_ast = ast_child(args_ast); + deferred_reification_t* reify = c->frame->reify; + for(size_t i = 0; i < m->param_count; i++) { + arg_types[i] = deferred_reify(reify, ast_type(arg_ast), c->opt); cast_args[i+1] = gen_assign_cast(c, param_types[i+3], args[i+1], - ast_type(arg_ast)); + arg_types[i]); arg_ast = ast_sibling(arg_ast); } @@ -561,18 +574,15 @@ void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[], } // Trace while populating the message contents. - arg_ast = ast_child(args_ast); bool need_trace = false; for(size_t i = 0; i < m->param_count; i++) { - if(gentrace_needed(c, ast_type(arg_ast), m->params[i].ast)) + if(gentrace_needed(c, arg_types[i], m->params[i].ast)) { need_trace = true; break; } - - arg_ast = ast_sibling(arg_ast); } LLVMValueRef ctx = codegen_ctx(c); @@ -581,13 +591,11 @@ void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[], { LLVMValueRef gc = gencall_runtime(c, "pony_gc_send", &ctx, 1, ""); LLVMSetMetadataStr(gc, "pony.msgsend", md); - arg_ast = ast_child(args_ast); for(size_t i = 0; i < m->param_count; i++) { - gentrace(c, ctx, args[i+1], cast_args[i+1], ast_type(arg_ast), + gentrace(c, ctx, args[i+1], cast_args[i+1], arg_types[i], m->params[i].ast); - arg_ast = ast_sibling(arg_ast); } gc = gencall_runtime(c, "pony_send_done", &ctx, 1, ""); @@ -611,6 +619,11 @@ void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[], ponyint_pool_free_size(params_buf_size, param_types); ponyint_pool_free_size(args_buf_size, cast_args); + + for(size_t i = 0; i < m->param_count; i++) + ast_free_unattached(arg_types[i]); + + ponyint_pool_free_size(arg_types_buf_size, arg_types); } static bool contains_boxable(ast_t* type) @@ -726,6 +739,8 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) AST_GET_CHILDREN(postfix, receiver, method); ast_t* typeargs = NULL; + deferred_reification_t* reify = c->frame->reify; + // Dig through function qualification. switch(ast_id(receiver)) { @@ -735,7 +750,7 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) case TK_FUNREF: case TK_BECHAIN: case TK_FUNCHAIN: - typeargs = method; + typeargs = deferred_reify(reify, method, c->opt); AST_GET_CHILDREN_NO_DECL(receiver, receiver, method); break; @@ -744,12 +759,18 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) // Get the receiver type. const char* method_name = ast_name(method); - ast_t* type = ast_type(receiver); + ast_t* type = deferred_reify(reify, ast_type(receiver), c->opt); reach_type_t* t = reach_type(c->reach, type); pony_assert(t != NULL); + token_id cap = cap_dispatch(type); + reach_method_t* m = reach_method(t, cap, method_name, typeargs); + + ast_free_unattached(type); + ast_free_unattached(typeargs); + // Generate the arguments. - size_t count = ast_childcount(positional) + 1; + size_t count = m->param_count + 1; size_t buf_size = count * sizeof(void*); LLVMValueRef* args = (LLVMValueRef*)ponyint_pool_alloc_size(buf_size); @@ -802,8 +823,6 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) } // Static or virtual dispatch. - token_id cap = cap_dispatch(type); - reach_method_t* m = reach_method(t, cap, method_name, typeargs); LLVMValueRef func = dispatch_function(c, t, m, args[0]); bool is_message = false; @@ -836,9 +855,6 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) { // If we're sending a message, trace and send here instead of calling the // sender to trace the most specific types possible. - token_id cap = cap_dispatch(type); - reach_method_t* m = reach_method(t, cap, method_name, typeargs); - codegen_debugloc(c, ast); gen_send_message(c, m, args, positional); codegen_debugloc(c, NULL); @@ -863,7 +879,9 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) while(arg != NULL) { - args[i] = gen_assign_cast(c, params[i], args[i], ast_type(arg)); + ast_t* arg_type = deferred_reify(reify, ast_type(arg), c->opt); + args[i] = gen_assign_cast(c, params[i], args[i], arg_type); + ast_free_unattached(arg_type); arg = ast_sibling(arg); i++; } @@ -918,7 +936,8 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) LLVMValueRef gen_pattern_eq(compile_t* c, ast_t* pattern, LLVMValueRef r_value) { // This is used for structural equality in pattern matching. - ast_t* pattern_type = ast_type(pattern); + ast_t* pattern_type = deferred_reify(c->frame->reify, ast_type(pattern), + c->opt); if(ast_id(pattern_type) == TK_NOMINAL) { @@ -948,6 +967,7 @@ LLVMValueRef gen_pattern_eq(compile_t* c, ast_t* pattern, LLVMValueRef r_value) (name == c->str_F64) ) { + ast_free_unattached(pattern_type); return gen_eq_rvalue(c, pattern, r_value, true); } } @@ -963,6 +983,8 @@ LLVMValueRef gen_pattern_eq(compile_t* c, ast_t* pattern, LLVMValueRef r_value) reach_method_t* m = reach_method(t, cap, c->str_eq, NULL); LLVMValueRef func = dispatch_function(c, t, m, l_value); + ast_free_unattached(pattern_type); + if(func == NULL) return NULL; @@ -1042,6 +1064,8 @@ static LLVMValueRef declare_ffi(compile_t* c, const char* f_name, ast_t* arg = ast_child(args); + deferred_reification_t* reify = c->frame->reify; + while(arg != NULL) { ast_t* p_type = ast_type(arg); @@ -1049,9 +1073,11 @@ static LLVMValueRef declare_ffi(compile_t* c, const char* f_name, if(p_type == NULL) p_type = ast_childidx(arg, 1); + p_type = deferred_reify(reify, p_type, c->opt); reach_type_t* pt = reach_type(c->reach, p_type); pony_assert(pt != NULL); f_params[count++] = ((compile_type_t*)pt->c_type)->use_type; + ast_free_unattached(p_type); arg = ast_sibling(arg); } @@ -1126,10 +1152,13 @@ LLVMValueRef gen_ffi(compile_t* c, ast_t* ast) // Get the function name, +1 to skip leading @ const char* f_name = ast_name(id) + 1; + deferred_reification_t* reify = c->frame->reify; + // Get the return type. - ast_t* type = ast_type(ast); + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); reach_type_t* t = reach_type(c->reach, type); pony_assert(t != NULL); + ast_free_unattached(type); // Get the function. First check if the name is in use by a global and error // if it's the case. @@ -1260,7 +1289,7 @@ LLVMValueRef gen_ffi(compile_t* c, ast_t* ast) compile_type_t* c_t = (compile_type_t*)t->c_type; // Special case a None return value, which is used for void functions. - bool isnone = is_none(type); + bool isnone = is_none(t->ast); bool isvoid = LLVMGetReturnType(f_type) == c->void_type; if(isnone && isvoid) @@ -1273,7 +1302,7 @@ LLVMValueRef gen_ffi(compile_t* c, ast_t* ast) result = cast_ffi_arg(c, ffi_decl, ast, result, c_t->use_type, "return values"); - result = gen_assign_cast(c, c_t->use_type, result, type); + result = gen_assign_cast(c, c_t->use_type, result, t->ast_cap); return result; } diff --git a/src/libponyc/codegen/gencontrol.c b/src/libponyc/codegen/gencontrol.c index 8aee7332f1..69c54763d9 100644 --- a/src/libponyc/codegen/gencontrol.c +++ b/src/libponyc/codegen/gencontrol.c @@ -33,22 +33,24 @@ LLVMValueRef gen_seq(compile_t* c, ast_t* ast) LLVMValueRef gen_if(compile_t* c, ast_t* ast) { bool needed = is_result_needed(ast); - ast_t* type = ast_type(ast); AST_GET_CHILDREN(ast, cond, left, right); - ast_t* left_type = ast_type(left); - ast_t* right_type = ast_type(right); + LLVMValueRef c_value = gen_expr(c, cond); + + if(c_value == NULL) + return NULL; + + deferred_reification_t* reify = c->frame->reify; // We will have no type if both branches have return statements. compile_type_t* phi_type = NULL; if(needed && !ast_checkflag(ast, AST_FLAG_JUMPS_AWAY)) + { + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); phi_type = (compile_type_t*)reach_type(c->reach, type)->c_type; - - LLVMValueRef c_value = gen_expr(c, cond); - - if(c_value == NULL) - return NULL; + ast_free_unattached(type); + } // If the conditional is constant, generate only one branch. bool gen_left = true; @@ -93,7 +95,17 @@ LLVMValueRef gen_if(compile_t* c, ast_t* ast) if(l_value != GEN_NOVALUE) { if(needed) - l_value = gen_assign_cast(c, phi_type->use_type, l_value, left_type); + { + ast_t* left_type = ast_type(left); + + // May be NULL if we're in an ifdef with a compile_error. + if(left_type != NULL) + { + left_type = deferred_reify(reify, left_type, c->opt); + l_value = gen_assign_cast(c, phi_type->use_type, l_value, left_type); + ast_free_unattached(left_type); + } + } if(l_value == NULL) return NULL; @@ -121,7 +133,17 @@ LLVMValueRef gen_if(compile_t* c, ast_t* ast) if(r_value != GEN_NOVALUE) { if(needed) - r_value = gen_assign_cast(c, phi_type->use_type, r_value, right_type); + { + ast_t* right_type = ast_type(right); + + // May be NULL if we're in an ifdef with a compile_error. + if(right_type != NULL) + { + right_type = deferred_reify(reify, right_type, c->opt); + r_value = gen_assign_cast(c, phi_type->use_type, r_value, right_type); + ast_free_unattached(right_type); + } + } if(r_value == NULL) return NULL; @@ -159,7 +181,17 @@ LLVMValueRef gen_iftype(compile_t* c, ast_t* ast) AST_GET_CHILDREN(ast, left, right); AST_GET_CHILDREN(left, subtype, supertype, body); - if(is_subtype_constraint(subtype, supertype, NULL, c->opt)) + deferred_reification_t* reify = c->frame->reify; + + ast_t* r_sub = deferred_reify(reify, subtype, c->opt); + ast_t* r_super = deferred_reify(reify, supertype, c->opt); + + bool is_sub = is_subtype_constraint(r_sub, r_super, NULL, c->opt); + + ast_free_unattached(r_sub); + ast_free_unattached(r_super); + + if(is_sub) return gen_expr(c, body); return gen_expr(c, right); @@ -170,14 +202,16 @@ LLVMValueRef gen_while(compile_t* c, ast_t* ast) bool needed = is_result_needed(ast); AST_GET_CHILDREN(ast, cond, body, else_clause); - ast_t* type = ast_type(ast); - ast_t* body_type = ast_type(body); - ast_t* else_type = ast_type(else_clause); + deferred_reification_t* reify = c->frame->reify; compile_type_t* phi_type = NULL; if(needed && !ast_checkflag(ast, AST_FLAG_JUMPS_AWAY)) + { + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); phi_type = (compile_type_t*)reach_type(c->reach, type)->c_type; + ast_free_unattached(type); + } LLVMBasicBlockRef init_block = codegen_block(c, "while_init"); LLVMBasicBlockRef body_block = codegen_block(c, "while_body"); @@ -219,7 +253,11 @@ LLVMValueRef gen_while(compile_t* c, ast_t* ast) LLVMValueRef l_value = gen_expr(c, body); if(needed) + { + ast_t* body_type = deferred_reify(reify, ast_type(body), c->opt); l_value = gen_assign_cast(c, phi_type->use_type, l_value, body_type); + ast_free_unattached(body_type); + } if(l_value == NULL) return NULL; @@ -260,7 +298,11 @@ LLVMValueRef gen_while(compile_t* c, ast_t* ast) return NULL; if(needed) + { + ast_t* else_type = deferred_reify(reify, ast_type(else_clause), c->opt); r_value = gen_assign_cast(c, phi_type->use_type, r_value, else_type); + ast_free_unattached(else_type); + } else_from = LLVMGetInsertBlock(c->builder); LLVMBuildBr(c->builder, post_block); @@ -292,14 +334,16 @@ LLVMValueRef gen_repeat(compile_t* c, ast_t* ast) bool needed = is_result_needed(ast); AST_GET_CHILDREN(ast, body, cond, else_clause); - ast_t* type = ast_type(ast); - ast_t* body_type = ast_type(body); - ast_t* else_type = ast_type(else_clause); + deferred_reification_t* reify = c->frame->reify; compile_type_t* phi_type = NULL; if(needed && !ast_checkflag(ast, AST_FLAG_JUMPS_AWAY)) + { + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); phi_type = (compile_type_t*)reach_type(c->reach, type)->c_type; + ast_free_unattached(type); + } LLVMBasicBlockRef body_block = codegen_block(c, "repeat_body"); LLVMBasicBlockRef cond_block = codegen_block(c, "repeat_cond"); @@ -328,7 +372,11 @@ LLVMValueRef gen_repeat(compile_t* c, ast_t* ast) LLVMValueRef value = gen_expr(c, body); if(needed) + { + ast_t* body_type = deferred_reify(reify, ast_type(body), c->opt); value = gen_assign_cast(c, phi_type->use_type, value, body_type); + ast_free_unattached(body_type); + } if(value == NULL) return NULL; @@ -378,7 +426,11 @@ LLVMValueRef gen_repeat(compile_t* c, ast_t* ast) return NULL; if(needed) + { + ast_t* else_type = deferred_reify(reify, ast_type(else_clause), c->opt); else_value = gen_assign_cast(c, phi_type->use_type, else_value, else_type); + ast_free_unattached(else_type); + } if(else_value != GEN_NOVALUE) { @@ -417,8 +469,6 @@ LLVMValueRef gen_break(compile_t* c, ast_t* ast) { target = c->frame->break_novalue_target; } else { - ast_t* body_type = ast_type(body); - // Get the break target. target = c->frame->break_target; @@ -433,7 +483,10 @@ LLVMValueRef gen_break(compile_t* c, ast_t* ast) { // Cast it to the phi type if we need to. LLVMTypeRef phi_type = LLVMTypeOf(post_phi); + ast_t* body_type = deferred_reify(c->frame->reify, ast_type(body), + c->opt); value = gen_assign_cast(c, phi_type, value, body_type); + ast_free_unattached(body_type); } if(value == NULL) @@ -489,7 +542,9 @@ LLVMValueRef gen_return(compile_t* c, ast_t* ast) if(LLVMGetTypeKind(r_type) != LLVMVoidTypeKind) { - LLVMValueRef ret = gen_assign_cast(c, r_type, value, ast_type(expr)); + ast_t* type = deferred_reify(c->frame->reify, ast_type(expr), c->opt); + LLVMValueRef ret = gen_assign_cast(c, r_type, value, type); + ast_free_unattached(type); codegen_scope_lifetime_end(c); LLVMBuildRet(c->builder, ret); } else { @@ -506,15 +561,17 @@ LLVMValueRef gen_try(compile_t* c, ast_t* ast) bool needed = is_result_needed(ast); AST_GET_CHILDREN(ast, body, else_clause, then_clause); - ast_t* type = ast_type(ast); - ast_t* body_type = ast_type(body); - ast_t* else_type = ast_type(else_clause); + deferred_reification_t* reify = c->frame->reify; compile_type_t* phi_type = NULL; // We will have no type if both branches have return statements. if(needed && !ast_checkflag(ast, AST_FLAG_JUMPS_AWAY)) + { + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); phi_type = (compile_type_t*)reach_type(c->reach, type)->c_type; + ast_free_unattached(type); + } LLVMBasicBlockRef block = LLVMGetInsertBlock(c->builder); LLVMBasicBlockRef else_block = codegen_block(c, "try_else"); @@ -534,8 +591,10 @@ LLVMValueRef gen_try(compile_t* c, ast_t* ast) { if(needed) { + ast_t* body_type = deferred_reify(reify, ast_type(body), c->opt); body_value = gen_assign_cast(c, phi_type->use_type, body_value, body_type); + ast_free_unattached(body_type); } if(body_value == NULL) @@ -572,8 +631,10 @@ LLVMValueRef gen_try(compile_t* c, ast_t* ast) { if(needed) { + ast_t* else_type = deferred_reify(reify, ast_type(else_clause), c->opt); else_value = gen_assign_cast(c, phi_type->use_type, else_value, else_type); + ast_free_unattached(else_type); } if(else_value == NULL) diff --git a/src/libponyc/codegen/gendesc.c b/src/libponyc/codegen/gendesc.c index 443e756ccd..18dab986e0 100644 --- a/src/libponyc/codegen/gendesc.c +++ b/src/libponyc/codegen/gendesc.c @@ -62,7 +62,7 @@ static LLVMValueRef make_unbox_function(compile_t* c, reach_type_t* t, LLVMTypeRef unbox_type = LLVMFunctionType(ret_type, params, count, false); LLVMValueRef unbox_fun = codegen_addfun(c, unbox_name, unbox_type, true); - codegen_startfun(c, unbox_fun, NULL, NULL, false); + codegen_startfun(c, unbox_fun, NULL, NULL, NULL, false); // Extract the primitive type from element 1 and call the real function. LLVMValueRef this_ptr = LLVMGetParam(unbox_fun, 0); diff --git a/src/libponyc/codegen/genexe.c b/src/libponyc/codegen/genexe.c index 8597753870..6f2f490574 100644 --- a/src/libponyc/codegen/genexe.c +++ b/src/libponyc/codegen/genexe.c @@ -100,7 +100,7 @@ LLVMValueRef gen_main(compile_t* c, reach_type_t* t_main, reach_type_t* t_env) LLVMTypeRef ftype = LLVMFunctionType(c->i32, params, 3, false); LLVMValueRef func = LLVMAddFunction(c->module, "main", ftype); - codegen_startfun(c, func, NULL, NULL, false); + codegen_startfun(c, func, NULL, NULL, NULL, false); LLVMBasicBlockRef start_fail_block = codegen_block(c, "start_fail"); LLVMBasicBlockRef post_block = codegen_block(c, "post"); diff --git a/src/libponyc/codegen/genfun.c b/src/libponyc/codegen/genfun.c index ceddec04d4..5aa9bb864f 100644 --- a/src/libponyc/codegen/genfun.c +++ b/src/libponyc/codegen/genfun.c @@ -327,13 +327,13 @@ static void make_prototype(compile_t* c, reach_type_t* t, } } -static void add_dispatch_case(compile_t* c, reach_type_t* t, ast_t* params, - uint32_t index, LLVMValueRef handler, LLVMTypeRef fun_type, - LLVMTypeRef msg_type) +static void add_dispatch_case(compile_t* c, reach_type_t* t, + reach_param_t* params, uint32_t index, LLVMValueRef handler, + LLVMTypeRef fun_type, LLVMTypeRef msg_type) { // Add a case to the dispatch function to handle this message. compile_type_t* c_t = (compile_type_t*)t->c_type; - codegen_startfun(c, c_t->dispatch_fn, NULL, NULL, false); + codegen_startfun(c, c_t->dispatch_fn, NULL, NULL, NULL, false); LLVMBasicBlockRef block = codegen_block(c, "handler"); LLVMValueRef id = LLVMConstInt(c->i32, index, false); LLVMAddCase(c_t->dispatch_switch, id, block); @@ -345,7 +345,7 @@ static void add_dispatch_case(compile_t* c, reach_type_t* t, ast_t* params, LLVMValueRef msg = LLVMBuildBitCast(c->builder, LLVMGetParam(c_t->dispatch_fn, 2), msg_type, ""); - int count = LLVMCountParamTypes(fun_type); + size_t count = LLVMCountParamTypes(fun_type); size_t params_buf_size = count * sizeof(LLVMTypeRef); LLVMTypeRef* param_types = (LLVMTypeRef*)ponyint_pool_alloc_size(params_buf_size); @@ -355,42 +355,34 @@ static void add_dispatch_case(compile_t* c, reach_type_t* t, ast_t* params, LLVMValueRef* args = (LLVMValueRef*)ponyint_pool_alloc_size(args_buf_size); args[0] = LLVMBuildBitCast(c->builder, this_ptr, c_t->use_type, ""); - ast_t* param = ast_child(params); - - for(int i = 1; i < count; i++) + for(int i = 1; i < (int)count; i++) { LLVMValueRef field = LLVMBuildStructGEP(c->builder, msg, i + 2, ""); args[i] = LLVMBuildLoad(c->builder, field, ""); - args[i] = gen_assign_cast(c, param_types[i], args[i], ast_type(param)); - param = ast_sibling(param); + args[i] = gen_assign_cast(c, param_types[i], args[i], + params[i - 1].type->ast_cap); } // Trace the message. - param = ast_child(params); bool need_trace = false; - while(param != NULL) + for(size_t i = 0; i < count - 1; i++) { - ast_t* param_type = ast_type(param); - if(gentrace_needed(c, param_type, param_type)) + if(gentrace_needed(c, params[i].type->ast_cap, params[i].type->ast_cap)) { need_trace = true; break; } - - param = ast_sibling(param); } if(need_trace) { - param = ast_child(params); gencall_runtime(c, "pony_gc_recv", &ctx, 1, ""); - for(int i = 1; i < count; i++) + for(size_t i = 1; i < count; i++) { - ast_t* param_type = ast_type(param); - gentrace(c, ctx, args[i], args[i], param_type, param_type); - param = ast_sibling(param); + gentrace(c, ctx, args[i], args[i], params[i - 1].type->ast_cap, + params[i - 1].type->ast_cap); } gencall_runtime(c, "pony_recv_done", &ctx, 1, ""); @@ -437,12 +429,10 @@ static bool genfun_fun(compile_t* c, reach_type_t* t, reach_method_t* m) compile_method_t* c_m = (compile_method_t*)m->c_method; pony_assert(c_m->func != NULL); - ast_t* r_fun = deferred_reify(m->fun, m->fun->ast, c->opt); - - AST_GET_CHILDREN(r_fun, cap, id, typeparams, params, result, can_error, + AST_GET_CHILDREN(m->fun->ast, cap, id, typeparams, params, result, can_error, body); - codegen_startfun(c, c_m->func, c_m->di_file, c_m->di_method, + codegen_startfun(c, c_m->func, c_m->di_file, c_m->di_method, m->fun, ast_id(cap) == TK_AT); name_params(c, t, m, c_m->func); @@ -458,8 +448,11 @@ static bool genfun_fun(compile_t* c, reach_type_t* t, reach_method_t* m) if(value != GEN_NOVALUE) { - if(finaliser || ((ast_id(cap) == TK_AT) && is_none(result))) + ast_t* r_result = deferred_reify(m->fun, result, c->opt); + + if(finaliser || ((ast_id(cap) == TK_AT) && is_none(r_result))) { + ast_free_unattached(r_result); codegen_scope_lifetime_end(c); codegen_debugloc(c, ast_childlast(body)); LLVMBuildRetVoid(c->builder); @@ -469,13 +462,20 @@ static bool genfun_fun(compile_t* c, reach_type_t* t, reach_method_t* m) // If the result type is known to be a tuple, do the correct assignment // cast even if the body type is not a tuple. - ast_t* body_type = ast_type(body); + ast_t* body_type = deferred_reify(m->fun, ast_type(body), c->opt); if((ast_id(result) == TK_TUPLETYPE) && (ast_id(body_type) != TK_TUPLETYPE)) - body_type = result; + { + ast_free_unattached(body_type); + body_type = r_result; + r_result = NULL; + } LLVMValueRef ret = gen_assign_cast(c, r_type, value, body_type); + ast_free_unattached(body_type); + ast_free_unattached(r_result); + if(ret == NULL) return false; @@ -489,8 +489,6 @@ static bool genfun_fun(compile_t* c, reach_type_t* t, reach_method_t* m) codegen_finishfun(c); - ast_free_unattached(r_fun); - return true; } @@ -500,13 +498,12 @@ static bool genfun_be(compile_t* c, reach_type_t* t, reach_method_t* m) pony_assert(c_m->func != NULL); pony_assert(c_m->func_handler != NULL); - ast_t* r_fun = deferred_reify(m->fun, m->fun->ast, c->opt); - - AST_GET_CHILDREN(r_fun, cap, id, typeparams, params, result, can_error, + AST_GET_CHILDREN(m->fun->ast, cap, id, typeparams, params, result, can_error, body); // Generate the handler. - codegen_startfun(c, c_m->func_handler, c_m->di_file, c_m->di_method, false); + codegen_startfun(c, c_m->func_handler, c_m->di_file, c_m->di_method, m->fun, + false); name_params(c, t, m, c_m->func_handler); LLVMValueRef value = gen_expr(c, body); @@ -521,7 +518,7 @@ static bool genfun_be(compile_t* c, reach_type_t* t, reach_method_t* m) codegen_finishfun(c); // Generate the sender. - codegen_startfun(c, c_m->func, NULL, NULL, false); + codegen_startfun(c, c_m->func, NULL, NULL, m->fun, false); size_t buf_size = (m->param_count + 1) * sizeof(LLVMValueRef); LLVMValueRef* param_vals = (LLVMValueRef*)ponyint_pool_alloc_size(buf_size); LLVMGetParams(c_m->func, param_vals); @@ -537,11 +534,9 @@ static bool genfun_be(compile_t* c, reach_type_t* t, reach_method_t* m) // Add the dispatch case. LLVMTypeRef msg_type_ptr = LLVMPointerType(c_m->msg_type, 0); - add_dispatch_case(c, t, params, m->vtable_index, c_m->func_handler, + add_dispatch_case(c, t, m->params, m->vtable_index, c_m->func_handler, c_m->func_type, msg_type_ptr); - ast_free_unattached(r_fun); - return true; } @@ -551,12 +546,10 @@ static bool genfun_new(compile_t* c, reach_type_t* t, reach_method_t* m) compile_method_t* c_m = (compile_method_t*)m->c_method; pony_assert(c_m->func != NULL); - ast_t* r_fun = deferred_reify(m->fun, m->fun->ast, c->opt); - - AST_GET_CHILDREN(r_fun, cap, id, typeparams, params, result, can_error, + AST_GET_CHILDREN(m->fun->ast, cap, id, typeparams, params, result, can_error, body); - codegen_startfun(c, c_m->func, c_m->di_file, c_m->di_method, false); + codegen_startfun(c, c_m->func, c_m->di_file, c_m->di_method, m->fun, false); name_params(c, t, m, c_m->func); LLVMValueRef value = gen_expr(c, body); @@ -578,8 +571,6 @@ static bool genfun_new(compile_t* c, reach_type_t* t, reach_method_t* m) codegen_finishfun(c); - ast_free_unattached(r_fun); - return true; } @@ -589,13 +580,12 @@ static bool genfun_newbe(compile_t* c, reach_type_t* t, reach_method_t* m) pony_assert(c_m->func != NULL); pony_assert(c_m->func_handler != NULL); - ast_t* r_fun = deferred_reify(m->fun, m->fun->ast, c->opt); - - AST_GET_CHILDREN(r_fun, cap, id, typeparams, params, result, can_error, + AST_GET_CHILDREN(m->fun->ast, cap, id, typeparams, params, result, can_error, body); // Generate the handler. - codegen_startfun(c, c_m->func_handler, c_m->di_file, c_m->di_method, false); + codegen_startfun(c, c_m->func_handler, c_m->di_file, c_m->di_method, m->fun, + false); name_params(c, t, m, c_m->func_handler); LLVMValueRef value = gen_expr(c, body); @@ -608,7 +598,7 @@ static bool genfun_newbe(compile_t* c, reach_type_t* t, reach_method_t* m) codegen_finishfun(c); // Generate the sender. - codegen_startfun(c, c_m->func, NULL, NULL, false); + codegen_startfun(c, c_m->func, NULL, NULL, m->fun, false); size_t buf_size = (m->param_count + 1) * sizeof(LLVMValueRef); LLVMValueRef* param_vals = (LLVMValueRef*)ponyint_pool_alloc_size(buf_size); LLVMGetParams(c_m->func, param_vals); @@ -624,11 +614,9 @@ static bool genfun_newbe(compile_t* c, reach_type_t* t, reach_method_t* m) // Add the dispatch case. LLVMTypeRef msg_type_ptr = LLVMPointerType(c_m->msg_type, 0); - add_dispatch_case(c, t, params, m->vtable_index, c_m->func_handler, + add_dispatch_case(c, t, m->params, m->vtable_index, c_m->func_handler, c_m->func_type, msg_type_ptr); - ast_free_unattached(r_fun); - return true; } @@ -665,7 +653,7 @@ static bool genfun_implicit_final(compile_t* c, reach_type_t* t, { compile_method_t* c_m = (compile_method_t*)m->c_method; - codegen_startfun(c, c_m->func, NULL, NULL, false); + codegen_startfun(c, c_m->func, NULL, NULL, NULL, false); call_embed_finalisers(c, t, NULL, gen_this(c, NULL)); LLVMBuildRetVoid(c->builder); codegen_finishfun(c); @@ -709,7 +697,7 @@ static bool genfun_allocator(compile_t* c, reach_type_t* t) LLVMAddAttributeAtIndex(fun, LLVMAttributeReturnIndex, deref_attr); LLVMAddAttributeAtIndex(fun, LLVMAttributeReturnIndex, align_attr); } - codegen_startfun(c, fun, NULL, NULL, false); + codegen_startfun(c, fun, NULL, NULL, NULL, false); LLVMValueRef result; @@ -748,7 +736,8 @@ static bool genfun_forward(compile_t* c, reach_type_t* t, pony_assert(m2 != m); compile_method_t* c_m2 = (compile_method_t*)m2->c_method; - codegen_startfun(c, c_m->func, c_m->di_file, c_m->di_method, m->cap == TK_AT); + codegen_startfun(c, c_m->func, c_m->di_file, c_m->di_method, m->fun, + m->cap == TK_AT); int count = LLVMCountParams(c_m->func); size_t buf_size = count * sizeof(LLVMValueRef); @@ -1014,7 +1003,7 @@ void genfun_primitive_calls(compile_t* c) const char* fn_name = genname_program_fn(c->filename, "primitives_init"); c->primitives_init = LLVMAddFunction(c->module, fn_name, fn_type); - codegen_startfun(c, c->primitives_init, NULL, NULL, false); + codegen_startfun(c, c->primitives_init, NULL, NULL, NULL, false); primitive_call(c, c->str__init); LLVMBuildRetVoid(c->builder); codegen_finishfun(c); @@ -1027,7 +1016,7 @@ void genfun_primitive_calls(compile_t* c) const char* fn_name = genname_program_fn(c->filename, "primitives_final"); c->primitives_final = LLVMAddFunction(c->module, fn_name, fn_type); - codegen_startfun(c, c->primitives_final, NULL, NULL, false); + codegen_startfun(c, c->primitives_final, NULL, NULL, NULL, false); primitive_call(c, c->str__final); LLVMBuildRetVoid(c->builder); codegen_finishfun(c); diff --git a/src/libponyc/codegen/genident.c b/src/libponyc/codegen/genident.c index d5dc87fef2..c393daff97 100644 --- a/src/libponyc/codegen/genident.c +++ b/src/libponyc/codegen/genident.c @@ -441,8 +441,6 @@ static LLVMValueRef gen_is_value(compile_t* c, ast_t* left_type, LLVMValueRef gen_is(compile_t* c, ast_t* ast) { AST_GET_CHILDREN(ast, left, right); - ast_t* left_type = ast_type(left); - ast_t* right_type = ast_type(right); LLVMValueRef l_value = gen_expr(c, left); LLVMValueRef r_value = gen_expr(c, right); @@ -450,18 +448,23 @@ LLVMValueRef gen_is(compile_t* c, ast_t* ast) if((l_value == NULL) || (r_value == NULL)) return NULL; + deferred_reification_t* reify = c->frame->reify; + ast_t* left_type = deferred_reify(reify, ast_type(left), c->opt); + ast_t* right_type = deferred_reify(reify, ast_type(right), c->opt); + codegen_debugloc(c, ast); LLVMValueRef result = gen_is_value(c, left_type, right_type, l_value, r_value); codegen_debugloc(c, NULL); + + ast_free_unattached(left_type); + ast_free_unattached(right_type); return result; } LLVMValueRef gen_isnt(compile_t* c, ast_t* ast) { AST_GET_CHILDREN(ast, left, right); - ast_t* left_type = ast_type(left); - ast_t* right_type = ast_type(right); LLVMValueRef l_value = gen_expr(c, left); LLVMValueRef r_value = gen_expr(c, right); @@ -469,11 +472,18 @@ LLVMValueRef gen_isnt(compile_t* c, ast_t* ast) if((l_value == NULL) || (r_value == NULL)) return NULL; + deferred_reification_t* reify = c->frame->reify; + ast_t* left_type = deferred_reify(reify, ast_type(left), c->opt); + ast_t* right_type = deferred_reify(reify, ast_type(right), c->opt); + codegen_debugloc(c, ast); LLVMValueRef result = gen_is_value(c, left_type, right_type, l_value, r_value); result = LLVMBuildNot(c->builder, result, ""); codegen_debugloc(c, NULL); + + ast_free_unattached(left_type); + ast_free_unattached(right_type); return result; } @@ -495,7 +505,7 @@ void gen_is_tuple_fun(compile_t* c, reach_type_t* t) c_m->func_type = LLVMFunctionType(c->i1, params, 3, false); c_m->func = codegen_addfun(c, m->full_name, c_m->func_type, true); - codegen_startfun(c, c_m->func, NULL, NULL, false); + codegen_startfun(c, c_m->func, NULL, NULL, NULL, false); LLVMValueRef l_value = LLVMGetParam(codegen_fun(c), 0); LLVMValueRef r_value = LLVMGetParam(codegen_fun(c), 1); LLVMValueRef r_id = LLVMGetParam(codegen_fun(c), 2); diff --git a/src/libponyc/codegen/genmatch.c b/src/libponyc/codegen/genmatch.c index c20c55bbc0..1b4c2f9125 100644 --- a/src/libponyc/codegen/genmatch.c +++ b/src/libponyc/codegen/genmatch.c @@ -35,7 +35,8 @@ static bool static_match(compile_t* c, LLVMValueRef value, ast_t* type, static ast_t* eq_param_type(compile_t* c, ast_t* pattern) { - ast_t* pattern_type = ast_type(pattern); + ast_t* pattern_type = deferred_reify(c->frame->reify, ast_type(pattern), + c->opt); deferred_reification_t* fun = lookup(NULL, pattern, pattern_type, c->str_eq); AST_GET_CHILDREN(fun->ast, cap, id, typeparams, params, result, partial); @@ -44,6 +45,7 @@ static ast_t* eq_param_type(compile_t* c, ast_t* pattern) ast_t* r_type = deferred_reify(fun, type, c->opt); + ast_free_unattached(pattern_type); deferred_reify_free(fun); return r_type; } @@ -403,7 +405,8 @@ static bool dynamic_capture_ptr(compile_t* c, LLVMValueRef ptr, { // Here, ptr is a pointer to a tuple field. It could be a primitive, an // object, or a nested tuple. - ast_t* pattern_type = ast_type(pattern); + ast_t* pattern_type = deferred_reify(c->frame->reify, ast_type(pattern), + c->opt); ast_t* the_case = ast_parent(pattern); match_weight_t weight; @@ -417,7 +420,10 @@ static bool dynamic_capture_ptr(compile_t* c, LLVMValueRef ptr, // Check the runtime type. We pass a pointer to the fields because we may // still need to match a tuple type inside a type expression. if(!check_type(c, ptr, desc, pattern_type, next_block, weight)) + { + ast_free_unattached(pattern_type); return false; + } // We now know that ptr points to something of type pattern_type, and that // it isn't a boxed primitive or tuple, as that would go through the other @@ -429,7 +435,10 @@ static bool dynamic_capture_ptr(compile_t* c, LLVMValueRef ptr, ptr = LLVMBuildBitCast(c->builder, ptr, ptr_type, ""); LLVMValueRef value = LLVMBuildLoad(c->builder, ptr, ""); - return gen_assign_value(c, pattern, value, pattern_type) != NULL; + LLVMValueRef r = gen_assign_value(c, pattern, value, pattern_type); + + ast_free_unattached(pattern_type); + return r != NULL; } static bool dynamic_match_ptr(compile_t* c, LLVMValueRef ptr, @@ -494,7 +503,8 @@ static bool dynamic_value_object(compile_t* c, LLVMValueRef object, static bool dynamic_capture_object(compile_t* c, LLVMValueRef object, LLVMValueRef desc, ast_t* pattern, LLVMBasicBlockRef next_block) { - ast_t* pattern_type = ast_type(pattern); + ast_t* pattern_type = deferred_reify(c->frame->reify, ast_type(pattern), + c->opt); // Build a base pointer that skips the object header. LLVMValueRef ptr = gendesc_ptr_to_fields(c, object, desc); @@ -511,12 +521,18 @@ static bool dynamic_capture_object(compile_t* c, LLVMValueRef object, // Check the runtime type. We pass a pointer to the fields because we may // still need to match a tuple type inside a type expression. if(!check_type(c, ptr, desc, pattern_type, next_block, weight)) + { + ast_free_unattached(pattern_type); return false; + } // As long as the type is correct, we can assign it, with gen_assign_value() // handling boxing and unboxing. We pass the type of the pattern as the type // of the object. - return gen_assign_value(c, pattern, object, pattern_type) != NULL; + LLVMValueRef r = gen_assign_value(c, pattern, object, pattern_type); + + ast_free_unattached(pattern_type); + return r != NULL; } static bool dynamic_match_object(compile_t* c, LLVMValueRef object, @@ -641,7 +657,6 @@ static bool static_capture(compile_t* c, LLVMValueRef value, ast_t* type, ast_t* pattern, LLVMBasicBlockRef next_block) { // The pattern is a capture. Make sure we are the right type, then assign. - ast_t* pattern_type = ast_type(pattern); if(ast_id(pattern) == TK_MATCH_CAPTURE) { @@ -650,7 +665,14 @@ static bool static_capture(compile_t* c, LLVMValueRef value, ast_t* type, return false; } - if(!is_subtype(type, pattern_type, NULL, c->opt)) + ast_t* pattern_type = deferred_reify(c->frame->reify, ast_type(pattern), + c->opt); + + bool is_sub = is_subtype(type, pattern_type, NULL, c->opt); + + ast_free_unattached(pattern_type); + + if(!is_sub) { // Switch to dynamic capture. pony_assert(LLVMTypeOf(value) == c->object_ptr); @@ -738,8 +760,9 @@ static bool case_body(compile_t* c, ast_t* body, if(is_result_needed(body)) { - ast_t* body_type = ast_type(body); + ast_t* body_type = deferred_reify(c->frame->reify, ast_type(body), c->opt); body_value = gen_assign_cast(c, phi_type, body_value, body_type); + ast_free_unattached(body_type); if(body_value == NULL) return false; @@ -756,19 +779,27 @@ static bool case_body(compile_t* c, ast_t* body, LLVMValueRef gen_match(compile_t* c, ast_t* ast) { bool needed = is_result_needed(ast); - ast_t* type = ast_type(ast); AST_GET_CHILDREN(ast, match_expr, cases, else_expr); // We will have no type if all cases jump away. LLVMTypeRef phi_type = NULL; + deferred_reification_t* reify = c->frame->reify; + if(needed && !ast_checkflag(ast, AST_FLAG_JUMPS_AWAY)) { + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); reach_type_t* t_phi = reach_type(c->reach, type); phi_type = ((compile_type_t*)t_phi->c_type)->use_type; + ast_free_unattached(type); } - ast_t* match_type = alias(ast_type(match_expr)); + ast_t* expr_type = deferred_reify(reify, ast_type(match_expr), c->opt); + ast_t* match_type = alias(expr_type); + + if(match_type != expr_type) + ast_free_unattached(expr_type); + LLVMValueRef match_value = gen_expr(c, match_expr); LLVMBasicBlockRef pattern_block = codegen_block(c, "case_pattern"); @@ -814,10 +845,14 @@ LLVMValueRef gen_match(compile_t* c, ast_t* ast) LLVMPositionBuilderAtEnd(c->builder, pattern_block); codegen_pushscope(c, the_case); - ast_t* pattern_type = ast_type(the_case); + ast_t* pattern_type = deferred_reify(reify, ast_type(the_case), c->opt); bool ok = true; - if(is_matchtype(match_type, pattern_type, c->opt) != MATCHTYPE_ACCEPT) + matchtype_t match = is_matchtype(match_type, pattern_type, c->opt); + + ast_free_unattached(pattern_type); + + if(match != MATCHTYPE_ACCEPT) { // If there's no possible match, jump directly to the next block. LLVMBuildBr(c->builder, next_block); diff --git a/src/libponyc/codegen/genoperator.c b/src/libponyc/codegen/genoperator.c index 5de949cb25..5939095fdf 100644 --- a/src/libponyc/codegen/genoperator.c +++ b/src/libponyc/codegen/genoperator.c @@ -78,8 +78,9 @@ static LLVMValueRef make_divmod(compile_t* c, ast_t* left, ast_t* right, build_binop build_f, build_binop build_ui, build_binop build_si, bool safe) { - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); LLVMValueRef l_value = gen_expr(c, left); LLVMValueRef r_value = gen_expr(c, right); @@ -239,8 +240,9 @@ static LLVMValueRef make_cmp(compile_t* c, ast_t* left, ast_t* right, LLVMRealPredicate cmp_f, LLVMIntPredicate cmp_si, LLVMIntPredicate cmp_ui, bool safe) { - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); LLVMValueRef l_value = gen_expr(c, left); LLVMValueRef r_value = gen_expr(c, right); @@ -430,6 +432,8 @@ static bool assign_tuple(compile_t* c, ast_t* left, ast_t* r_type, static LLVMValueRef assign_rvalue(compile_t* c, ast_t* left, ast_t* r_type, LLVMValueRef r_value) { + deferred_reification_t* reify = c->frame->reify; + switch(ast_id(left)) { case TK_SEQ: @@ -460,18 +464,30 @@ static LLVMValueRef assign_rvalue(compile_t* c, ast_t* left, ast_t* r_type, { // The result is the previous value of the field. LLVMValueRef l_value = gen_fieldptr(c, left); - ast_t* p_type = ast_type(ast_child(left)); - ast_t* l_type = ast_type(left); - return assign_field(c, l_value, r_value, p_type, l_type, r_type); + ast_t* p_type = deferred_reify(reify, ast_type(ast_child(left)), c->opt); + ast_t* l_type = deferred_reify(reify, ast_type(left), c->opt); + + LLVMValueRef ret = assign_field(c, l_value, r_value, p_type, l_type, + r_type); + + ast_free_unattached(p_type); + ast_free_unattached(l_type); + return ret; } case TK_TUPLEELEMREF: { // The result is the previous value of the tuple element. LLVMValueRef l_value = gen_tupleelemptr(c, left); - ast_t* p_type = ast_type(ast_child(left)); - ast_t* l_type = ast_type(left); - return assign_field(c, l_value, r_value, p_type, l_type, r_type); + ast_t* p_type = deferred_reify(reify, ast_type(ast_child(left)), c->opt); + ast_t* l_type = deferred_reify(reify, ast_type(left), c->opt); + + LLVMValueRef r = assign_field(c, l_value, r_value, p_type, l_type, + r_type); + + ast_free_unattached(p_type); + ast_free_unattached(l_type); + return r; } case TK_EMBEDREF: @@ -486,8 +502,11 @@ static LLVMValueRef assign_rvalue(compile_t* c, ast_t* left, ast_t* r_type, const char* name = ast_name(ast_child(left)); codegen_local_lifetime_start(c, name); LLVMValueRef l_value = codegen_getlocal(c, name); - ast_t* l_type = ast_type(left); + ast_t* l_type = deferred_reify(reify, ast_type(left), c->opt); + LLVMValueRef ret = assign_local(c, l_value, r_value, l_type, r_type); + + ast_free_unattached(l_type); return ret; } @@ -521,8 +540,11 @@ static LLVMValueRef assign_rvalue(compile_t* c, ast_t* left, ast_t* r_type, const char* name = ast_name(left); codegen_local_lifetime_start(c, name); LLVMValueRef l_value = codegen_getlocal(c, name); - ast_t* l_type = ast_type(ast_parent(left)); + ast_t* l_type = deferred_reify(reify, ast_type(ast_parent(left)), c->opt); + LLVMValueRef ret = assign_local(c, l_value, r_value, l_type, r_type); + + ast_free_unattached(l_type); return ret; } @@ -587,8 +609,9 @@ LLVMValueRef gen_add(compile_t* c, ast_t* left, ast_t* right, bool safe) return make_binop(c, left, right, LLVMConstFAdd, LLVMConstAdd, LLVMBuildFAdd, LLVMBuildAdd); - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); return make_binop(c, left, right, LLVMConstFAdd, LLVMConstAdd, make_unsafe_fadd, sign ? LLVMBuildNSWAdd : LLVMBuildNUWAdd); @@ -600,8 +623,9 @@ LLVMValueRef gen_sub(compile_t* c, ast_t* left, ast_t* right, bool safe) return make_binop(c, left, right, LLVMConstFSub, LLVMConstSub, LLVMBuildFSub, LLVMBuildSub); - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); return make_binop(c, left, right, LLVMConstFSub, LLVMConstSub, make_unsafe_fsub, sign ? LLVMBuildNSWSub : LLVMBuildNUWSub); @@ -613,8 +637,9 @@ LLVMValueRef gen_mul(compile_t* c, ast_t* left, ast_t* right, bool safe) return make_binop(c, left, right, LLVMConstFMul, LLVMConstMul, LLVMBuildFMul, LLVMBuildMul); - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); return make_binop(c, left, right, LLVMConstFMul, LLVMConstMul, make_unsafe_fmul, sign ? LLVMBuildNSWMul : LLVMBuildNUWMul); @@ -653,8 +678,9 @@ LLVMValueRef gen_neg(compile_t* c, ast_t* ast, bool safe) if(safe) return LLVMBuildNeg(c->builder, value, ""); - ast_t* type = ast_type(ast); + ast_t* type = deferred_reify(c->frame->reify, ast_type(ast), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); if(sign) return LLVMBuildNSWNeg(c->builder, value, ""); @@ -697,8 +723,9 @@ LLVMValueRef gen_shl(compile_t* c, ast_t* left, ast_t* right, bool safe) return LLVMBuildShl(c->builder, l_value, select, ""); } - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); LLVMValueRef result = LLVMBuildShl(c->builder, l_value, r_value, ""); @@ -713,8 +740,9 @@ LLVMValueRef gen_shl(compile_t* c, ast_t* left, ast_t* right, bool safe) LLVMValueRef gen_shr(compile_t* c, ast_t* left, ast_t* right, bool safe) { (void)safe; - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); LLVMValueRef l_value = gen_expr(c, left); LLVMValueRef r_value = gen_expr(c, right); @@ -826,9 +854,11 @@ LLVMValueRef gen_not(compile_t* c, ast_t* ast) if(value == NULL) return NULL; - ast_t* type = ast_type(ast); + ast_t* type = deferred_reify(c->frame->reify, ast_type(ast), c->opt); + bool bool_type = is_bool(type); + ast_free_unattached(type); - if(is_bool(type)) + if(bool_type) { if(LLVMIsAConstantInt(value)) { @@ -856,8 +886,9 @@ LLVMValueRef gen_eq(compile_t* c, ast_t* left, ast_t* right, bool safe) LLVMValueRef gen_eq_rvalue(compile_t* c, ast_t* left, LLVMValueRef r_value, bool safe) { - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); LLVMValueRef l_value = gen_expr(c, left); return make_cmp_value(c, sign, l_value, r_value, LLVMRealOEQ, LLVMIntEQ, @@ -899,7 +930,9 @@ LLVMValueRef gen_assign(compile_t* c, ast_t* ast) return NULL; codegen_debugloc(c, ast); - LLVMValueRef result = assign_rvalue(c, left, ast_type(right), r_value); + ast_t* type = deferred_reify(c->frame->reify, ast_type(right), c->opt); + LLVMValueRef result = assign_rvalue(c, left, type, r_value); + ast_free_unattached(type); codegen_debugloc(c, NULL); return result; } diff --git a/src/libponyc/codegen/genprim.c b/src/libponyc/codegen/genprim.c index c94af9d23a..1818944ea2 100644 --- a/src/libponyc/codegen/genprim.c +++ b/src/libponyc/codegen/genprim.c @@ -43,7 +43,7 @@ static void start_function(compile_t* c, reach_type_t* t, reach_method_t* m, c_m->func_type = LLVMFunctionType(result, params, count, false); c_m->func = codegen_addfun(c, m->full_name, c_m->func_type, true); genfun_param_attrs(c, t, m, c_m->func); - codegen_startfun(c, c_m->func, NULL, NULL, false); + codegen_startfun(c, c_m->func, NULL, NULL, NULL, false); } static void box_function(compile_t* c, generate_box_fn gen, void* gen_data) @@ -737,7 +737,7 @@ static void trace_array_elements(compile_t* c, reach_type_t* t, void genprim_array_trace(compile_t* c, reach_type_t* t) { compile_type_t* c_t = (compile_type_t*)t->c_type; - codegen_startfun(c, c_t->trace_fn, NULL, NULL, false); + codegen_startfun(c, c_t->trace_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->trace_fn, LLVMCCallConv); LLVMSetLinkage(c_t->trace_fn, LLVMExternalLinkage); LLVMValueRef ctx = LLVMGetParam(c_t->trace_fn, 0); @@ -765,7 +765,7 @@ void genprim_array_serialise_trace(compile_t* c, reach_type_t* t) c_t->serialise_trace_fn = codegen_addfun(c, genname_serialise_trace(t->name), c->trace_type, true); - codegen_startfun(c, c_t->serialise_trace_fn, NULL, NULL, false); + codegen_startfun(c, c_t->serialise_trace_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->serialise_trace_fn, LLVMCCallConv); LLVMSetLinkage(c_t->serialise_trace_fn, LLVMExternalLinkage); @@ -820,7 +820,7 @@ void genprim_array_serialise(compile_t* c, reach_type_t* t) c_t->serialise_fn = codegen_addfun(c, genname_serialise(t->name), c->serialise_type, true); - codegen_startfun(c, c_t->serialise_fn, NULL, NULL, false); + codegen_startfun(c, c_t->serialise_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->serialise_fn, LLVMCCallConv); LLVMSetLinkage(c_t->serialise_fn, LLVMExternalLinkage); @@ -947,7 +947,7 @@ void genprim_array_deserialise(compile_t* c, reach_type_t* t) c_t->deserialise_fn = codegen_addfun(c, genname_deserialise(t->name), c->trace_type, true); - codegen_startfun(c, c_t->deserialise_fn, NULL, NULL, false); + codegen_startfun(c, c_t->deserialise_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->deserialise_fn, LLVMCCallConv); LLVMSetLinkage(c_t->deserialise_fn, LLVMExternalLinkage); @@ -1031,7 +1031,7 @@ void genprim_string_serialise_trace(compile_t* c, reach_type_t* t) c_t->serialise_trace_fn = codegen_addfun(c, genname_serialise_trace(t->name), c->serialise_type, true); - codegen_startfun(c, c_t->serialise_trace_fn, NULL, NULL, false); + codegen_startfun(c, c_t->serialise_trace_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->serialise_trace_fn, LLVMCCallConv); LLVMSetLinkage(c_t->serialise_trace_fn, LLVMExternalLinkage); @@ -1064,7 +1064,7 @@ void genprim_string_serialise(compile_t* c, reach_type_t* t) c_t->serialise_fn = codegen_addfun(c, genname_serialise(t->name), c->serialise_type, true); - codegen_startfun(c, c_t->serialise_fn, NULL, NULL, false); + codegen_startfun(c, c_t->serialise_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->serialise_fn, LLVMCCallConv); LLVMSetLinkage(c_t->serialise_fn, LLVMExternalLinkage); @@ -1134,7 +1134,7 @@ void genprim_string_deserialise(compile_t* c, reach_type_t* t) c_t->deserialise_fn = codegen_addfun(c, genname_deserialise(t->name), c->trace_type, true); - codegen_startfun(c, c_t->deserialise_fn, NULL, NULL, false); + codegen_startfun(c, c_t->deserialise_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->deserialise_fn, LLVMCCallConv); LLVMSetLinkage(c_t->deserialise_fn, LLVMExternalLinkage); @@ -1917,7 +1917,7 @@ static void make_cpuid(compile_t* c) LLVMTypeRef f_type = LLVMFunctionType(r_type, &c->i32, 1, false); LLVMValueRef fun = codegen_addfun(c, "internal.x86.cpuid", f_type, false); LLVMSetFunctionCallConv(fun, LLVMCCallConv); - codegen_startfun(c, fun, NULL, NULL, false); + codegen_startfun(c, fun, NULL, NULL, NULL, false); LLVMValueRef cpuid = LLVMConstInlineAsm(f_type, "cpuid", "={ax},={bx},={cx},={dx},{ax}", false, false); @@ -1946,7 +1946,7 @@ static void make_rdtscp(compile_t* c) f_type = LLVMFunctionType(c->i64, &i32_ptr, 1, false); LLVMValueRef fun = codegen_addfun(c, "internal.x86.rdtscp", f_type, false); LLVMSetFunctionCallConv(fun, LLVMCCallConv); - codegen_startfun(c, fun, NULL, NULL, false); + codegen_startfun(c, fun, NULL, NULL, NULL, false); // Cast i32* to i8* and call the intrinsic. LLVMValueRef arg = LLVMGetParam(fun, 0); @@ -2017,7 +2017,7 @@ void genprim_signature(compile_t* c) LLVMTypeRef f_type = LLVMFunctionType(c_t->use_type, NULL, 0, false); LLVMValueRef fun = codegen_addfun(c, "internal.signature", f_type, false); LLVMSetFunctionCallConv(fun, LLVMCCallConv); - codegen_startfun(c, fun, NULL, NULL, false); + codegen_startfun(c, fun, NULL, NULL, NULL, false); LLVMBuildRet(c->builder, g_array); codegen_finishfun(c); } diff --git a/src/libponyc/codegen/genreference.c b/src/libponyc/codegen/genreference.c index 3a07a74749..31c4921dc2 100644 --- a/src/libponyc/codegen/genreference.c +++ b/src/libponyc/codegen/genreference.c @@ -86,8 +86,10 @@ LLVMValueRef gen_fieldptr(compile_t* c, ast_t* ast) if(l_value == NULL) return NULL; - ast_t* l_type = ast_type(left); - return make_fieldptr(c, l_value, l_type, right); + ast_t* l_type = deferred_reify(c->frame->reify, ast_type(left), c->opt); + LLVMValueRef ret = make_fieldptr(c, l_value, l_type, right); + ast_free_unattached(l_type); + return ret; } LLVMValueRef gen_fieldload(compile_t* c, ast_t* ast) @@ -99,14 +101,20 @@ LLVMValueRef gen_fieldload(compile_t* c, ast_t* ast) if(field == NULL) return NULL; - ast_t* type = ast_type(right); + deferred_reification_t* reify = c->frame->reify; + + ast_t* type = deferred_reify(reify, ast_type(right), c->opt); reach_type_t* t = reach_type(c->reach, type); pony_assert(t != NULL); + ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; field = LLVMBuildLoad(c->builder, field, ""); - LLVMValueRef metadata = tbaa_metadata_for_type(c, ast_type(left)); + type = deferred_reify(reify, ast_type(left), c->opt); + LLVMValueRef metadata = tbaa_metadata_for_type(c, type); + ast_free_unattached(type); + #if PONY_LLVM >= 400 tbaa_tag(c, metadata, field); #else @@ -114,7 +122,7 @@ LLVMValueRef gen_fieldload(compile_t* c, ast_t* ast) LLVMSetMetadata(field, LLVMGetMDKindID(id, sizeof(id) - 1), metadata); #endif - return gen_assign_cast(c, c_t->use_type, field, type); + return gen_assign_cast(c, c_t->use_type, field, t->ast_cap); } @@ -146,14 +154,18 @@ LLVMValueRef gen_tupleelemptr(compile_t* c, ast_t* ast) if(l_value == NULL) return NULL; - ast_t* type = ast_type(ast); + deferred_reification_t* reify = c->frame->reify; + + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); reach_type_t* t = reach_type(c->reach, type); pony_assert(t != NULL); + ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; - ast_t* l_type = ast_type(left); + ast_t* l_type = deferred_reify(reify, ast_type(left), c->opt); LLVMValueRef value = make_tupleelemptr(c, l_value, l_type, right); - return gen_assign_cast(c, c_t->use_type, value, type); + ast_free_unattached(l_type); + return gen_assign_cast(c, c_t->use_type, value, t->ast_cap); } LLVMValueRef gen_tuple(compile_t* c, ast_t* ast) @@ -163,11 +175,16 @@ LLVMValueRef gen_tuple(compile_t* c, ast_t* ast) if(ast_sibling(child) == NULL) return gen_expr(c, child); - ast_t* type = ast_type(ast); + deferred_reification_t* reify = c->frame->reify; + + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); // If we contain '_', we have no usable value. if(contains_dontcare(type)) + { + ast_free_unattached(type); return GEN_NOTNEEDED; + } reach_type_t* t = reach_type(c->reach, type); compile_type_t* c_t = (compile_type_t*)t->c_type; @@ -198,7 +215,9 @@ LLVMValueRef gen_tuple(compile_t* c, ast_t* ast) return GEN_NOTNEEDED; } - value = gen_assign_cast(c, elements[i], value, ast_type(child)); + ast_t* child_type = deferred_reify(reify, ast_type(child), c->opt); + value = gen_assign_cast(c, elements[i], value, child_type); + ast_free_unattached(child_type); tuple = LLVMBuildInsertValue(c->builder, tuple, value, i++, ""); child = ast_sibling(child); } @@ -210,7 +229,6 @@ LLVMValueRef gen_tuple(compile_t* c, ast_t* ast) LLVMValueRef gen_localdecl(compile_t* c, ast_t* ast) { ast_t* id = ast_child(ast); - ast_t* type = ast_type(id); const char* name = ast_name(id); // If this local has already been generated, don't create another copy. This @@ -221,7 +239,9 @@ LLVMValueRef gen_localdecl(compile_t* c, ast_t* ast) if(value != NULL) return GEN_NOVALUE; + ast_t* type = deferred_reify(c->frame->reify, ast_type(id), c->opt); reach_type_t* t = reach_type(c->reach, type); + ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; // All alloca should happen in the entry block of a function. @@ -274,12 +294,13 @@ LLVMValueRef gen_localload(compile_t* c, ast_t* ast) if(local_ptr == NULL) return NULL; - ast_t* type = ast_type(ast); + ast_t* type = deferred_reify(c->frame->reify, ast_type(ast), c->opt); reach_type_t* t = reach_type(c->reach, type); + ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; LLVMValueRef value = LLVMBuildLoad(c->builder, local_ptr, ""); - return gen_assign_cast(c, c_t->use_type, value, type); + return gen_assign_cast(c, c_t->use_type, value, t->ast_cap); } LLVMValueRef gen_addressof(compile_t* c, ast_t* ast) @@ -435,7 +456,10 @@ LLVMValueRef gen_digestof(compile_t* c, ast_t* ast) { ast_t* expr = ast_child(ast); LLVMValueRef value = gen_expr(c, expr); - return gen_digestof_value(c, ast_type(expr), value); + ast_t* type = deferred_reify(c->frame->reify, ast_type(expr), c->opt); + LLVMValueRef ret = gen_digestof_value(c, type, value); + ast_free_unattached(type); + return ret; } void gen_digestof_fun(compile_t* c, reach_type_t* t) @@ -452,7 +476,7 @@ void gen_digestof_fun(compile_t* c, reach_type_t* t) c_m->func_type = LLVMFunctionType(c->i64, &c_t->structure_ptr, 1, false); c_m->func = codegen_addfun(c, m->full_name, c_m->func_type, true); - codegen_startfun(c, c_m->func, NULL, NULL, false); + codegen_startfun(c, c_m->func, NULL, NULL, NULL, false); LLVMValueRef value = LLVMGetParam(codegen_fun(c), 0); value = gen_unbox(c, t->ast_cap, value); @@ -463,8 +487,9 @@ void gen_digestof_fun(compile_t* c, reach_type_t* t) LLVMValueRef gen_int(compile_t* c, ast_t* ast) { - ast_t* type = ast_type(ast); + ast_t* type = deferred_reify(c->frame->reify, ast_type(ast), c->opt); reach_type_t* t = reach_type(c->reach, type); + ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; lexint_t* value = ast_int(ast); @@ -485,8 +510,9 @@ LLVMValueRef gen_int(compile_t* c, ast_t* ast) LLVMValueRef gen_float(compile_t* c, ast_t* ast) { - ast_t* type = ast_type(ast); + ast_t* type = deferred_reify(c->frame->reify, ast_type(ast), c->opt); reach_type_t* t = reach_type(c->reach, type); + ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; return LLVMConstReal(c_t->primitive, ast_float(ast)); @@ -494,7 +520,6 @@ LLVMValueRef gen_float(compile_t* c, ast_t* ast) LLVMValueRef gen_string(compile_t* c, ast_t* ast) { - ast_t* type = ast_type(ast); const char* name = ast_name(ast); genned_string_t k; @@ -505,11 +530,13 @@ LLVMValueRef gen_string(compile_t* c, ast_t* ast) if(string != NULL) return string->global; - size_t len = ast_name_len(ast); - + ast_t* type = ast_type(ast); + pony_assert(is_literal(type, "String")); reach_type_t* t = reach_type(c->reach, type); compile_type_t* c_t = (compile_type_t*)t->c_type; + size_t len = ast_name_len(ast); + LLVMValueRef args[4]; args[0] = c_t->desc; args[1] = LLVMConstInt(c->intptr, len, false); diff --git a/src/libponyc/codegen/genserialise.c b/src/libponyc/codegen/genserialise.c index 1e7e3c3ce9..e150ada7c2 100644 --- a/src/libponyc/codegen/genserialise.c +++ b/src/libponyc/codegen/genserialise.c @@ -215,7 +215,7 @@ static void make_serialise(compile_t* c, reach_type_t* t) c_t->serialise_fn = codegen_addfun(c, genname_serialise(t->name), c->serialise_type, true); - codegen_startfun(c, c_t->serialise_fn, NULL, NULL, false); + codegen_startfun(c, c_t->serialise_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->serialise_fn, LLVMCCallConv); LLVMSetLinkage(c_t->serialise_fn, LLVMExternalLinkage); @@ -361,7 +361,7 @@ static void make_deserialise(compile_t* c, reach_type_t* t) c_t->deserialise_fn = codegen_addfun(c, genname_deserialise(t->name), c->trace_type, true); - codegen_startfun(c, c_t->deserialise_fn, NULL, NULL, false); + codegen_startfun(c, c_t->deserialise_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->deserialise_fn, LLVMCCallConv); LLVMSetLinkage(c_t->deserialise_fn, LLVMExternalLinkage); diff --git a/src/libponyc/codegen/gentype.c b/src/libponyc/codegen/gentype.c index f96f34d501..9c38fd0080 100644 --- a/src/libponyc/codegen/gentype.c +++ b/src/libponyc/codegen/gentype.c @@ -477,7 +477,7 @@ static void make_dispatch(compile_t* c, reach_type_t* t) c_t->dispatch_fn = codegen_addfun(c, dispatch_name, c->dispatch_type, true); LLVMSetFunctionCallConv(c_t->dispatch_fn, LLVMCCallConv); LLVMSetLinkage(c_t->dispatch_fn, LLVMExternalLinkage); - codegen_startfun(c, c_t->dispatch_fn, NULL, NULL, false); + codegen_startfun(c, c_t->dispatch_fn, NULL, NULL, NULL, false); LLVMBasicBlockRef unreachable = codegen_block(c, "unreachable"); @@ -778,7 +778,7 @@ static bool make_trace(compile_t* c, reach_type_t* t) } // Generate the trace function. - codegen_startfun(c, c_t->trace_fn, NULL, NULL, false); + codegen_startfun(c, c_t->trace_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->trace_fn, LLVMCCallConv); LLVMSetLinkage(c_t->trace_fn, LLVMExternalLinkage);