Commit 5e1003bc81
Changed files (6)
src/all_types.hpp
@@ -34,12 +34,14 @@ struct CodeGen;
struct ConstExprValue;
struct IrInstruction;
struct IrInstructionCast;
+struct IrInstructionAllocaGen;
struct IrBasicBlock;
struct ScopeDecls;
struct ZigWindowsSDK;
struct Tld;
struct TldExport;
struct IrAnalyze;
+struct ResultLoc;
enum X64CABIClass {
X64CABIClass_Unknown,
@@ -1359,6 +1361,7 @@ struct ZigFn {
AstNode *fn_static_eval_set_node;
ZigList<IrInstruction *> alloca_list;
+ ZigList<IrInstructionAllocaGen *> alloca_gen_list;
ZigList<ZigVar *> variable_list;
Buf *section_name;
@@ -2171,7 +2174,9 @@ enum IrInstructionId {
IrInstructionIdUnionFieldPtr,
IrInstructionIdElemPtr,
IrInstructionIdVarPtr,
- IrInstructionIdCall,
+ IrInstructionIdReturnPtr,
+ IrInstructionIdCallSrc,
+ IrInstructionIdCallGen,
IrInstructionIdConst,
IrInstructionIdReturn,
IrInstructionIdCast,
@@ -2308,6 +2313,8 @@ enum IrInstructionId {
IrInstructionIdAssertNonNull,
IrInstructionIdHasDecl,
IrInstructionIdUndeclaredIdent,
+ IrInstructionIdAllocaSrc,
+ IrInstructionIdAllocaGen,
};
struct IrInstruction {
@@ -2335,14 +2342,14 @@ struct IrInstructionDeclVarSrc {
ZigVar *var;
IrInstruction *var_type;
IrInstruction *align_value;
- IrInstruction *init_value;
+ IrInstruction *ptr;
};
struct IrInstructionDeclVarGen {
IrInstruction base;
ZigVar *var;
- IrInstruction *init_value;
+ IrInstruction *var_ptr;
};
struct IrInstructionCondBr {
@@ -2528,14 +2535,21 @@ struct IrInstructionVarPtr {
ScopeFnDef *crossed_fndef_scope;
};
-struct IrInstructionCall {
+// For functions that have a return type for which handle_is_ptr is true, a
+// result location pointer is the secret first parameter ("sret"). This
+// instruction returns that pointer.
+struct IrInstructionReturnPtr {
+ IrInstruction base;
+};
+
+struct IrInstructionCallSrc {
IrInstruction base;
IrInstruction *fn_ref;
ZigFn *fn_entry;
size_t arg_count;
IrInstruction **args;
- LLVMValueRef tmp_ptr;
+ ResultLoc *result_loc;
IrInstruction *async_allocator;
IrInstruction *new_stack;
@@ -2544,6 +2558,21 @@ struct IrInstructionCall {
bool is_comptime;
};
+struct IrInstructionCallGen {
+ IrInstruction base;
+
+ IrInstruction *fn_ref;
+ ZigFn *fn_entry;
+ size_t arg_count;
+ IrInstruction **args;
+ IrInstruction *result_loc;
+
+ IrInstruction *async_allocator;
+ IrInstruction *new_stack;
+ FnInline fn_inline;
+ bool is_async;
+};
+
struct IrInstructionConst {
IrInstruction base;
};
@@ -3527,6 +3556,47 @@ struct IrInstructionUndeclaredIdent {
Buf *name;
};
+struct IrInstructionAllocaSrc {
+ IrInstruction base;
+
+ IrInstruction *align;
+ IrInstruction *is_comptime;
+ const char *name_hint;
+};
+
+struct IrInstructionAllocaGen {
+ IrInstruction base;
+
+ uint32_t align;
+ const char *name_hint;
+};
+
+enum ResultLocId {
+ ResultLocIdInvalid,
+ ResultLocIdNone,
+ ResultLocIdVar,
+ ResultLocIdReturn,
+};
+
+struct ResultLoc {
+ ResultLocId id;
+ IrInstruction *source_instruction;
+};
+
+struct ResultLocNone {
+ ResultLoc base;
+};
+
+struct ResultLocVar {
+ ResultLoc base;
+
+ ZigVar *var;
+};
+
+struct ResultLocReturn {
+ ResultLoc base;
+};
+
static const size_t slice_ptr_index = 0;
static const size_t slice_len_index = 1;
@@ -3574,7 +3644,7 @@ struct FnWalkAttrs {
struct FnWalkCall {
ZigList<LLVMValueRef> *gen_param_values;
- IrInstructionCall *inst;
+ IrInstructionCallGen *inst;
bool is_var_args;
};
src/codegen.cpp
@@ -1982,6 +1982,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty
}
static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {
+ if (g->strip_debug_symbols) return;
assert(var->di_loc_var != nullptr);
AstNode *source_node = var->decl_node;
ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc((unsigned)source_node->line + 1,
@@ -2288,7 +2289,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
return;
}
if (fn_walk->id == FnWalkIdCall) {
- IrInstructionCall *instruction = fn_walk->data.call.inst;
+ IrInstructionCallGen *instruction = fn_walk->data.call.inst;
bool is_var_args = fn_walk->data.call.is_var_args;
for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) {
IrInstruction *param_instruction = instruction->args[call_i];
@@ -3328,10 +3329,8 @@ static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutable *executable, IrI
return LLVMBuildICmp(g->builder, LLVMIntEQ, value, zero, "");
}
-static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
- IrInstructionDeclVarGen *decl_var_instruction)
-{
- ZigVar *var = decl_var_instruction->var;
+static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, IrInstructionDeclVarGen *instruction) {
+ ZigVar *var = instruction->var;
if (!type_has_bits(var->var_type))
return nullptr;
@@ -3339,20 +3338,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
if (var->ref_count == 0 && g->build_mode != BuildModeDebug)
return nullptr;
- IrInstruction *init_value = decl_var_instruction->init_value;
-
- bool have_init_expr = !value_is_all_undef(&init_value->value);
-
- if (have_init_expr) {
- ZigType *var_ptr_type = get_pointer_to_type_extra(g, var->var_type, false, false,
- PtrLenSingle, var->align_bytes, 0, 0, false);
- LLVMValueRef llvm_init_val = ir_llvm_value(g, init_value);
- gen_assign_raw(g, var->value_ref, var_ptr_type, llvm_init_val);
- } else if (ir_want_runtime_safety(g, &decl_var_instruction->base)) {
- uint32_t align_bytes = (var->align_bytes == 0) ? get_abi_alignment(g, var->var_type) : var->align_bytes;
- gen_undef_init(g, align_bytes, var->var_type, var->value_ref);
- }
-
+ var->value_ref = ir_llvm_value(g, instruction->var_ptr);
gen_var_debug_decl(g, var);
return nullptr;
}
@@ -3568,6 +3554,13 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrIn
}
}
+static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutable *executable,
+ IrInstructionReturnPtr *instruction)
+{
+ assert(g->cur_ret_ptr != nullptr || !type_has_bits(instruction->base.value.type));
+ return g->cur_ret_ptr;
+}
+
static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrInstructionElemPtr *instruction) {
LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr);
ZigType *array_ptr_type = instruction->array_ptr->value.type;
@@ -3719,7 +3712,7 @@ static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) {
LLVMAddCallSiteAttribute(call_instr, 1, sret_attr);
}
-static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {
+static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCallGen *instruction) {
LLVMValueRef fn_val;
ZigType *fn_type;
if (instruction->fn_entry) {
@@ -3742,8 +3735,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
bool prefix_arg_err_ret_stack = get_prefix_arg_err_ret_stack(g, fn_type_id);
bool is_var_args = fn_type_id->is_var_args;
ZigList<LLVMValueRef> gen_param_values = {};
+ LLVMValueRef result_loc = first_arg_ret ? ir_llvm_value(g, instruction->result_loc) : nullptr;
if (first_arg_ret) {
- gen_param_values.append(instruction->tmp_ptr);
+ gen_param_values.append(result_loc);
}
if (prefix_arg_err_ret_stack) {
gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope));
@@ -3751,7 +3745,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
if (instruction->is_async) {
gen_param_values.append(ir_llvm_value(g, instruction->async_allocator));
- LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");
+ LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
gen_param_values.append(err_val_ptr);
}
FnWalk fn_walk = {};
@@ -3794,9 +3788,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
if (instruction->is_async) {
- LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");
+ LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, "");
LLVMBuildStore(g->builder, result, payload_ptr);
- return instruction->tmp_ptr;
+ return result_loc;
}
if (src_return_type->id == ZigTypeIdUnreachable) {
@@ -3805,11 +3799,11 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
return nullptr;
} else if (first_arg_ret) {
set_call_instr_sret(g, result);
- return instruction->tmp_ptr;
+ return result_loc;
} else if (handle_is_ptr(src_return_type)) {
- auto store_instr = LLVMBuildStore(g->builder, result, instruction->tmp_ptr);
- LLVMSetAlignment(store_instr, LLVMGetAlignment(instruction->tmp_ptr));
- return instruction->tmp_ptr;
+ LLVMValueRef store_instr = LLVMBuildStore(g->builder, result, result_loc);
+ LLVMSetAlignment(store_instr, LLVMGetAlignment(result_loc));
+ return result_loc;
} else {
return result;
}
@@ -5535,7 +5529,9 @@ static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
}
static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {
- set_debug_location(g, instruction);
+ if (!g->strip_debug_symbols) {
+ set_debug_location(g, instruction);
+ }
switch (instruction->id) {
case IrInstructionIdInvalid:
@@ -5608,8 +5604,13 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdGlobalAsm:
case IrInstructionIdHasDecl:
case IrInstructionIdUndeclaredIdent:
+ case IrInstructionIdCallSrc:
+ case IrInstructionIdAllocaSrc:
zig_unreachable();
+ case IrInstructionIdAllocaGen:
+ return nullptr;
+
case IrInstructionIdDeclVarGen:
return ir_render_decl_var(g, executable, (IrInstructionDeclVarGen *)instruction);
case IrInstructionIdReturn:
@@ -5632,10 +5633,12 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_store_ptr(g, executable, (IrInstructionStorePtr *)instruction);
case IrInstructionIdVarPtr:
return ir_render_var_ptr(g, executable, (IrInstructionVarPtr *)instruction);
+ case IrInstructionIdReturnPtr:
+ return ir_render_return_ptr(g, executable, (IrInstructionReturnPtr *)instruction);
case IrInstructionIdElemPtr:
return ir_render_elem_ptr(g, executable, (IrInstructionElemPtr *)instruction);
- case IrInstructionIdCall:
- return ir_render_call(g, executable, (IrInstructionCall *)instruction);
+ case IrInstructionIdCallGen:
+ return ir_render_call(g, executable, (IrInstructionCallGen *)instruction);
case IrInstructionIdStructFieldPtr:
return ir_render_struct_field_ptr(g, executable, (IrInstructionStructFieldPtr *)instruction);
case IrInstructionIdUnionFieldPtr:
@@ -6851,6 +6854,26 @@ static void do_code_gen(CodeGen *g) {
}
// allocate temporary stack data
+ for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_gen_list.length; alloca_i += 1) {
+ IrInstructionAllocaGen *instruction = fn_table_entry->alloca_gen_list.at(alloca_i);
+ ZigType *ptr_type = instruction->base.value.type;
+ assert(ptr_type->id == ZigTypeIdPointer);
+ ZigType *child_type = ptr_type->data.pointer.child_type;
+ if (!type_has_bits(child_type))
+ continue;
+ if (instruction->base.ref_count == 0)
+ continue;
+ if (instruction->base.value.special != ConstValSpecialRuntime) {
+ if (const_ptr_pointee(nullptr, g, &instruction->base.value, nullptr)->special !=
+ ConstValSpecialRuntime)
+ {
+ continue;
+ }
+ }
+ instruction->base.llvm_value = build_alloca(g, child_type, instruction->name_hint,
+ get_ptr_align(g, ptr_type));
+ }
+
for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_list.length; alloca_i += 1) {
IrInstruction *instruction = fn_table_entry->alloca_list.at(alloca_i);
LLVMValueRef *slot;
@@ -6873,9 +6896,6 @@ static void do_code_gen(CodeGen *g) {
} else if (instruction->id == IrInstructionIdUnionInit) {
IrInstructionUnionInit *union_init_instruction = (IrInstructionUnionInit *)instruction;
slot = &union_init_instruction->tmp_ptr;
- } else if (instruction->id == IrInstructionIdCall) {
- IrInstructionCall *call_instruction = (IrInstructionCall *)instruction;
- slot = &call_instruction->tmp_ptr;
} else if (instruction->id == IrInstructionIdSlice) {
IrInstructionSlice *slice_instruction = (IrInstructionSlice *)instruction;
slot = &slice_instruction->tmp_ptr;
@@ -6939,8 +6959,6 @@ static void do_code_gen(CodeGen *g) {
}
if (var->src_arg_index == SIZE_MAX) {
- var->value_ref = build_alloca(g, var->var_type, buf_ptr(&var->name), var->align_bytes);
-
var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
buf_ptr(&var->name), import->data.structure.root_struct->di_file, (unsigned)(var->decl_node->line + 1),
get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);
src/ir.cpp
@@ -157,7 +157,8 @@ enum UndefAllowed {
};
static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
-static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval);
+static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,
+ ResultLoc *result_loc);
static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction);
static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type);
static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr);
@@ -475,8 +476,16 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) {
return IrInstructionIdVarPtr;
}
-static constexpr IrInstructionId ir_instruction_id(IrInstructionCall *) {
- return IrInstructionIdCall;
+static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnPtr *) {
+ return IrInstructionIdReturnPtr;
+}
+
+static constexpr IrInstructionId ir_instruction_id(IrInstructionCallSrc *) {
+ return IrInstructionIdCallSrc;
+}
+
+static constexpr IrInstructionId ir_instruction_id(IrInstructionCallGen *) {
+ return IrInstructionIdCallGen;
}
static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) {
@@ -1019,6 +1028,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent
return IrInstructionIdUndeclaredIdent;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaSrc *) {
+ return IrInstructionIdAllocaSrc;
+}
+
+static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaGen *) {
+ return IrInstructionIdAllocaGen;
+}
+
template<typename T>
static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
T *special_instruction = allocate<T>(1);
@@ -1254,6 +1271,13 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so
return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr);
}
+static IrInstruction *ir_build_return_ptr(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) {
+ IrInstructionReturnPtr *instruction = ir_build_instruction<IrInstructionReturnPtr>(&ira->new_irb,
+ source_instruction->scope, source_instruction->source_node);
+ instruction->base.value.type = ty;
+ return &instruction->base;
+}
+
static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr,
IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len)
{
@@ -1320,12 +1344,12 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast
return &instruction->base;
}
-static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node,
+static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator,
- IrInstruction *new_stack)
+ IrInstruction *new_stack, ResultLoc *result_loc)
{
- IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node);
+ IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node);
call_instruction->fn_entry = fn_entry;
call_instruction->fn_ref = fn_ref;
call_instruction->is_comptime = is_comptime;
@@ -1335,6 +1359,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
call_instruction->is_async = is_async;
call_instruction->async_allocator = async_allocator;
call_instruction->new_stack = new_stack;
+ call_instruction->result_loc = result_loc;
if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block);
for (size_t i = 0; i < arg_count; i += 1)
@@ -1345,6 +1370,33 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
return &call_instruction->base;
}
+static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction,
+ ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
+ FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack,
+ IrInstruction *result_loc)
+{
+ IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb,
+ source_instruction->scope, source_instruction->source_node);
+ call_instruction->fn_entry = fn_entry;
+ call_instruction->fn_ref = fn_ref;
+ call_instruction->fn_inline = fn_inline;
+ call_instruction->args = args;
+ call_instruction->arg_count = arg_count;
+ call_instruction->is_async = is_async;
+ call_instruction->async_allocator = async_allocator;
+ call_instruction->new_stack = new_stack;
+ call_instruction->result_loc = result_loc;
+
+ if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block);
+ for (size_t i = 0; i < arg_count; i += 1)
+ ir_ref_instruction(args[i], ira->new_irb.current_basic_block);
+ if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block);
+ if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block);
+ if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
+
+ return &call_instruction->base;
+}
+
static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node,
size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values)
{
@@ -1511,7 +1563,7 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *
}
static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
- ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value)
+ ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *ptr)
{
IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node);
decl_var_instruction->base.value.special = ConstValSpecialStatic;
@@ -1519,26 +1571,26 @@ static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNod
decl_var_instruction->var = var;
decl_var_instruction->var_type = var_type;
decl_var_instruction->align_value = align_value;
- decl_var_instruction->init_value = init_value;
+ decl_var_instruction->ptr = ptr;
if (var_type != nullptr) ir_ref_instruction(var_type, irb->current_basic_block);
if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);
- ir_ref_instruction(init_value, irb->current_basic_block);
+ ir_ref_instruction(ptr, irb->current_basic_block);
return &decl_var_instruction->base;
}
static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction,
- ZigVar *var, IrInstruction *init_value)
+ ZigVar *var, IrInstruction *var_ptr)
{
IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb,
source_instruction->scope, source_instruction->source_node);
decl_var_instruction->base.value.special = ConstValSpecialStatic;
decl_var_instruction->base.value.type = ira->codegen->builtin_types.entry_void;
decl_var_instruction->var = var;
- decl_var_instruction->init_value = init_value;
+ decl_var_instruction->var_ptr = var_ptr;
- ir_ref_instruction(init_value, ira->new_irb.current_basic_block);
+ ir_ref_instruction(var_ptr, ira->new_irb.current_basic_block);
return &decl_var_instruction->base;
}
@@ -3109,6 +3161,32 @@ static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *so
return &instruction->base;
}
+static IrInstruction *ir_build_alloca_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *align, const char *name_hint, IrInstruction *is_comptime)
+{
+ IrInstructionAllocaSrc *instruction = ir_build_instruction<IrInstructionAllocaSrc>(irb, scope, source_node);
+ instruction->base.is_gen = true;
+ instruction->align = align;
+ instruction->name_hint = name_hint;
+ instruction->is_comptime = is_comptime;
+
+ if (align != nullptr) ir_ref_instruction(align, irb->current_basic_block);
+ if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block);
+
+ return &instruction->base;
+}
+
+static IrInstructionAllocaGen *ir_create_alloca_gen(IrAnalyze *ira, IrInstruction *source_instruction,
+ uint32_t align, const char *name_hint)
+{
+ IrInstructionAllocaGen *instruction = ir_create_instruction<IrInstructionAllocaGen>(&ira->new_irb,
+ source_instruction->scope, source_instruction->source_node);
+ instruction->align = align;
+ instruction->name_hint = name_hint;
+
+ return instruction;
+}
+
static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
results[ReturnKindUnconditional] = 0;
results[ReturnKindError] = 0;
@@ -3321,12 +3399,15 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
switch (node->data.return_expr.kind) {
case ReturnKindUnconditional:
{
+ ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1);
+ result_loc_ret->base.id = ResultLocIdReturn;
+
IrInstruction *return_value;
if (expr_node) {
// Temporarily set this so that if we return a type it gets the name of the function
ZigFn *prev_name_fn = irb->exec->name_fn;
irb->exec->name_fn = exec_fn_entry(irb->exec);
- return_value = ir_gen_node(irb, expr_node, scope);
+ return_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_ret->base);
irb->exec->name_fn = prev_name_fn;
if (return_value == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
@@ -3373,17 +3454,21 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);
ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block);
- return ir_gen_async_return(irb, scope, node, return_value, false);
+ IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false);
+ result_loc_ret->base.source_instruction = result;
+ return result;
} else {
// generate unconditional defers
ir_gen_defers_for_block(irb, scope, outer_scope, false);
- return ir_gen_async_return(irb, scope, node, return_value, false);
+ IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false);
+ result_loc_ret->base.source_instruction = result;
+ return result;
}
}
case ReturnKindError:
{
assert(expr_node);
- IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
+ IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
if (err_union_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr);
@@ -3592,7 +3677,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no
}
static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) {
- IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr);
+ IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr);
IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction)
@@ -3603,7 +3688,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node)
}
static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) {
- IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr);
+ IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr);
if (lvalue == irb->codegen->invalid_instruction)
return lvalue;
IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue);
@@ -3705,7 +3790,7 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode
AstNode *op1_node = node->data.bin_op_expr.op1;
AstNode *op2_node = node->data.bin_op_expr.op2;
- IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr);
+ IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr);
if (maybe_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
@@ -3968,7 +4053,7 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode
assert(node->type == NodeTypeArrayAccessExpr);
AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;
- IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr);
+ IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr);
if (array_ref_instruction == irb->codegen->invalid_instruction)
return array_ref_instruction;
@@ -3991,7 +4076,7 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode
AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
Buf *field_name = node->data.field_access_expr.field_name;
- IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr);
+ IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr);
if (container_ref_instruction == irb->codegen->invalid_instruction)
return container_ref_instruction;
@@ -4041,7 +4126,9 @@ static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *no
zig_unreachable();
}
-static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
+static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
+ ResultLoc *result_loc)
+{
assert(node->type == NodeTypeFnCallExpr);
AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
@@ -4625,7 +4712,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
case BuiltinFnIdField:
{
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
- IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr);
+ IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr);
if (arg0_value == irb->codegen->invalid_instruction)
return arg0_value;
@@ -4855,7 +4942,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
}
FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever;
- IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr, nullptr);
+ IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
+ fn_inline, false, nullptr, nullptr, result_loc);
return ir_lval_wrap(irb, scope, call, lval);
}
case BuiltinFnIdNewStackCall:
@@ -4885,7 +4973,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
return args[i];
}
- IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, false, nullptr, new_stack);
+ IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
+ FnInlineAuto, false, nullptr, new_stack, result_loc);
return ir_lval_wrap(irb, scope, call, lval);
}
case BuiltinFnIdTypeId:
@@ -5148,11 +5237,13 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
zig_unreachable();
}
-static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
+static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
+ ResultLoc *result_loc)
+{
assert(node->type == NodeTypeFnCallExpr);
if (node->data.fn_call_expr.is_builtin)
- return ir_gen_builtin_fn_call(irb, scope, node, lval);
+ return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc);
AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope);
@@ -5178,8 +5269,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
}
}
- IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto,
- is_async, async_allocator, nullptr);
+ IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto,
+ is_async, async_allocator, nullptr, result_loc);
return ir_lval_wrap(irb, scope, fn_call, lval);
}
@@ -5244,7 +5335,7 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, Ast
assert(node->type == NodeTypePrefixOpExpr);
AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
- IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);
+ IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr);
if (value == irb->codegen->invalid_instruction)
return value;
@@ -5339,7 +5430,7 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode
static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node,
LVal lval)
{
- IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
+ IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
if (err_union_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
@@ -5384,7 +5475,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval);
case PrefixOpAddrOf: {
AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
- return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr), lval);
+ return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr), lval);
}
}
zig_unreachable();
@@ -5486,17 +5577,27 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
// Parser should ensure that this never happens
assert(variable_declaration->threadlocal_tok == nullptr);
+ IrInstruction *alloca = ir_build_alloca_src(irb, scope, node, align_value,
+ buf_ptr(variable_declaration->symbol), is_comptime);
+
+ // Create a result location for the initialization expression.
+ ResultLocVar *result_loc_var = allocate<ResultLocVar>(1);
+ result_loc_var->base.id = ResultLocIdVar;
+ result_loc_var->base.source_instruction = alloca;
+ result_loc_var->var = var;
+
// Temporarily set the name of the IrExecutable to the VariableDeclaration
// so that the struct or enum from the init expression inherits the name.
Buf *old_exec_name = irb->exec->name;
irb->exec->name = variable_declaration->symbol;
- IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope);
+ IrInstruction *init_value = ir_gen_node_extra(irb, variable_declaration->expr, scope, LValNone,
+ &result_loc_var->base);
irb->exec->name = old_exec_name;
if (init_value == irb->codegen->invalid_instruction)
return init_value;
- return ir_build_var_decl_src(irb, scope, node, var, type_instruction, align_value, init_value);
+ return ir_build_var_decl_src(irb, scope, node, var, type_instruction, align_value, alloca);
}
static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
@@ -5534,7 +5635,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
} else {
payload_scope = subexpr_scope;
}
- IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr);
+ IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope,
+ LValPtr, nullptr);
if (err_val_ptr == irb->codegen->invalid_instruction)
return err_val_ptr;
IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr);
@@ -5621,7 +5723,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol,
true, false, false, is_comptime);
Scope *child_scope = payload_var->child_scope;
- IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr);
+ IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope,
+ LValPtr, nullptr);
if (maybe_val_ptr == irb->codegen->invalid_instruction)
return maybe_val_ptr;
IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr);
@@ -5775,7 +5878,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
}
assert(elem_node->type == NodeTypeSymbol);
- IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr);
+ IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr, nullptr);
if (array_val_ptr == irb->codegen->invalid_instruction)
return array_val_ptr;
@@ -6182,7 +6285,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
AstNode *else_node = node->data.test_expr.else_node;
bool var_is_ptr = node->data.test_expr.var_is_ptr;
- IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
+ IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
if (maybe_val_ptr == irb->codegen->invalid_instruction)
return maybe_val_ptr;
@@ -6261,7 +6364,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
Buf *var_symbol = node->data.if_err_expr.var_symbol;
Buf *err_symbol = node->data.if_err_expr.err_symbol;
- IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr);
+ IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr);
if (err_val_ptr == irb->codegen->invalid_instruction)
return err_val_ptr;
@@ -6397,7 +6500,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
assert(node->type == NodeTypeSwitchExpr);
AstNode *target_node = node->data.switch_expr.expr;
- IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr);
+ IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr);
if (target_value_ptr == irb->codegen->invalid_instruction)
return target_value_ptr;
IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr);
@@ -6597,7 +6700,7 @@ static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNo
assert(node->type == NodeTypeCompTime);
Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope);
- return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval);
+ return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);
}
static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) {
@@ -6776,7 +6879,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)
AstNode *start_node = slice_expr->start;
AstNode *end_node = slice_expr->end;
- IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr);
+ IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr);
if (ptr_value == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
@@ -6814,7 +6917,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
}
- IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr);
+ IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr);
if (err_union_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
@@ -7560,7 +7663,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
}
static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,
- LVal lval)
+ LVal lval, ResultLoc *result_loc)
{
assert(scope);
switch (node->type) {
@@ -7576,7 +7679,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
case NodeTypeBlock:
return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval);
case NodeTypeGroupedExpr:
- return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval);
+ return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc);
case NodeTypeBinOpExpr:
return ir_lval_wrap(irb, scope, ir_gen_bin_op(irb, scope, node), lval);
case NodeTypeIntLiteral:
@@ -7588,7 +7691,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
case NodeTypeSymbol:
return ir_gen_symbol(irb, scope, node, lval);
case NodeTypeFnCallExpr:
- return ir_gen_fn_call(irb, scope, node, lval);
+ return ir_gen_fn_call(irb, scope, node, lval, result_loc);
case NodeTypeIfBoolExpr:
return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval);
case NodeTypePrefixOpExpr:
@@ -7617,7 +7720,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
}
case NodeTypePtrDeref: {
AstNode *expr_node = node->data.ptr_deref_expr.target;
- IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);
+ IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr);
if (value == irb->codegen->invalid_instruction)
return value;
@@ -7629,7 +7732,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
case NodeTypeUnwrapOptional: {
AstNode *expr_node = node->data.unwrap_optional.expr;
- IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
+ IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
if (maybe_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
@@ -7697,14 +7800,23 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
zig_unreachable();
}
-static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval) {
- IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval);
+static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,
+ ResultLoc *result_loc)
+{
+ if (result_loc == nullptr) {
+ // Create a result location indicating there is none - but if one gets created
+ // it will be properly distributed.
+ ResultLocNone *result_loc_none = allocate<ResultLocNone>(1);
+ result_loc_none->base.id = ResultLocIdNone;
+ result_loc = &result_loc_none->base;
+ }
+ IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc);
irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction);
return result;
}
static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) {
- return ir_gen_node_extra(irb, node, scope, LValNone);
+ return ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
}
static void invalidate_exec(IrExecutable *exec) {
@@ -7837,7 +7949,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup");
}
- IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone);
+ IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
assert(result);
if (irb->exec->invalid)
return false;
@@ -7946,7 +8058,10 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
// non-allocating. Basically coroutines are not supported right now until they are reworked.
args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size
args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align
- ir_build_call(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr);
+ ResultLocNone *result_loc_none = allocate<ResultLocNone>(1);
+ result_loc_none->base.id = ResultLocIdNone;
+ ir_build_call_src(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr,
+ nullptr, &result_loc_none->base);
IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");
ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false);
@@ -13641,12 +13756,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
Error err;
ZigVar *var = decl_var_instruction->var;
- IrInstruction *init_value = decl_var_instruction->init_value->child;
- if (type_is_invalid(init_value->value.type)) {
- var->var_type = ira->codegen->builtin_types.entry_invalid;
- return ira->codegen->invalid_instruction;
- }
-
ZigType *explicit_type = nullptr;
IrInstruction *var_type = nullptr;
if (decl_var_instruction->var_type != nullptr) {
@@ -13661,12 +13770,19 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
AstNode *source_node = decl_var_instruction->base.source_node;
- IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type);
bool is_comptime_var = ir_get_var_is_comptime(var);
bool var_class_requires_const = false;
- ZigType *result_type = casted_init_value->value.type;
+ IrInstruction *var_ptr = decl_var_instruction->ptr->child;
+ if (type_is_invalid(var_ptr->value.type)) {
+ var->var_type = ira->codegen->builtin_types.entry_invalid;
+ return ira->codegen->invalid_instruction;
+ }
+
+ assert(var_ptr->value.type->id == ZigTypeIdPointer);
+
+ ZigType *result_type = var_ptr->value.type->data.pointer.child_type;
if (type_is_invalid(result_type)) {
result_type = ira->codegen->builtin_types.entry_invalid;
} else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) {
@@ -13675,6 +13791,14 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
result_type = ira->codegen->builtin_types.entry_invalid;
}
+ ConstExprValue *init_val = nullptr;
+ if (instr_is_comptime(var_ptr) && var_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) {
+ init_val = const_ptr_pointee(ira, ira->codegen, &var_ptr->value, decl_var_instruction->base.source_node);
+ if (is_comptime_var) {
+ var->const_value = init_val;
+ }
+ }
+
switch (type_requires_comptime(ira->codegen, result_type)) {
case ReqCompTimeInvalid:
result_type = ira->codegen->builtin_types.entry_invalid;
@@ -13689,18 +13813,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
}
break;
case ReqCompTimeNo:
- if (casted_init_value->value.special == ConstValSpecialStatic &&
- casted_init_value->value.type->id == ZigTypeIdFn &&
- casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
- casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways)
- {
- var_class_requires_const = true;
- if (!var->src_is_const && !is_comptime_var) {
- ErrorMsg *msg = ir_add_error_node(ira, source_node,
- buf_sprintf("functions marked inline must be stored in const or comptime var"));
- AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node;
- add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here"));
- result_type = ira->codegen->builtin_types.entry_invalid;
+ if (init_val != nullptr) {
+ if (init_val->special == ConstValSpecialStatic &&
+ init_val->type->id == ZigTypeIdFn &&
+ init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
+ init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways)
+ {
+ var_class_requires_const = true;
+ if (!var->src_is_const && !is_comptime_var) {
+ ErrorMsg *msg = ir_add_error_node(ira, source_node,
+ buf_sprintf("functions marked inline must be stored in const or comptime var"));
+ AstNode *proto_node = init_val->data.x_ptr.data.fn.fn_entry->proto_node;
+ add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here"));
+ result_type = ira->codegen->builtin_types.entry_invalid;
+ }
}
}
break;
@@ -13747,11 +13873,11 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
}
}
- if (casted_init_value->value.special != ConstValSpecialRuntime) {
+ if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) {
if (var->mem_slot_index != SIZE_MAX) {
assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length);
ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index);
- copy_const_val(mem_slot, &casted_init_value->value, !is_comptime_var || var->gen_is_const);
+ copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const);
if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) {
return ir_const_void(ira, &decl_var_instruction->base);
@@ -13768,7 +13894,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
if (fn_entry)
fn_entry->variable_list.append(var);
- return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, casted_init_value);
+ return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, var_ptr);
}
static VarLinkage global_linkage_to_var_linkage(GlobalLinkageId id) {
@@ -14076,7 +14202,67 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i
zig_unreachable();
}
-static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry,
+static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_inst, ZigType *var_type,
+ uint32_t align, const char *name_hint, bool force_comptime)
+{
+ Error err;
+
+ ConstExprValue *pointee = create_const_vals(1);
+ pointee->special = ConstValSpecialUndef;
+
+ IrInstructionAllocaGen *result = ir_create_alloca_gen(ira, source_inst, align, name_hint);
+ result->base.value.special = force_comptime ? ConstValSpecialStatic : ConstValSpecialRuntime;
+ result->base.value.data.x_ptr.special = ConstPtrSpecialRef;
+ result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutRuntimeVar;
+ result->base.value.data.x_ptr.data.ref.pointee = pointee;
+
+ if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown)))
+ return ira->codegen->invalid_instruction;
+ assert(result->base.value.data.x_ptr.special != ConstPtrSpecialInvalid);
+
+ pointee->type = var_type;
+ result->base.value.type = get_pointer_to_type_extra(ira->codegen, var_type, false, false,
+ PtrLenSingle, align, 0, 0, false);
+
+ ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
+ if (fn_entry != nullptr) {
+ fn_entry->alloca_gen_list.append(result);
+ }
+ result->base.is_gen = true;
+ return &result->base;
+}
+
+static IrInstruction *ir_resolve_result_loc(IrAnalyze *ira, ResultLoc *result_loc, ZigType *elem_type) {
+ switch (result_loc->id) {
+ case ResultLocIdInvalid:
+ zig_unreachable();
+ case ResultLocIdNone:
+ return nullptr;
+ case ResultLocIdVar: {
+ // TODO implicit cast?
+ //ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc);
+ assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc);
+ IrInstructionAllocaSrc *alloca_src =
+ reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction);
+ if (alloca_src->base.child == nullptr) {
+ uint32_t align = 0; // TODO
+ bool force_comptime = false; // TODO
+ IrInstruction *alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, elem_type, align,
+ alloca_src->name_hint, force_comptime);
+ alloca_src->base.child = alloca_gen;
+ }
+ return alloca_src->base.child;
+ }
+ case ResultLocIdReturn: {
+ //ResultLocReturn *result_loc_ret = reinterpret_cast<ResultLocReturn *>(result_loc);
+ // TODO implicit cast?
+ return ir_build_return_ptr(ira, result_loc->source_instruction, elem_type);
+ }
+ }
+ zig_unreachable();
+}
+
+static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry,
ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count,
IrInstruction *async_allocator_inst)
{
@@ -14109,8 +14295,10 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c
ZigType *promise_type = get_promise_type(ira->codegen, return_type);
ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);
- IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node,
- fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, nullptr);
+ IrInstruction *result_loc = ir_resolve_result_loc(ira, call_instruction->result_loc, async_return_type);
+
+ IrInstruction *result = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count,
+ casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, result_loc);
result->value.type = async_return_type;
return result;
}
@@ -14416,7 +14604,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
return result;
}
-static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction,
+static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction,
ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref,
IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline)
{
@@ -14861,19 +15049,17 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
if (call_instruction->is_async) {
IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry,
fn_ref, casted_args, impl_param_count, async_allocator_inst);
- ir_add_alloca(ira, result, result->value.type);
return ir_finish_anal(ira, result);
}
assert(async_allocator_inst == nullptr);
- IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb,
- call_instruction->base.scope, call_instruction->base.source_node,
- impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline,
- call_instruction->is_async, nullptr, casted_new_stack);
+ IrInstruction *result_loc = ir_resolve_result_loc(ira, call_instruction->result_loc,
+ impl_fn_type_id->return_type);
+ IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base,
+ impl_fn, nullptr, impl_param_count, casted_args, fn_inline,
+ call_instruction->is_async, nullptr, casted_new_stack, result_loc);
new_call_instruction->value.type = impl_fn_type_id->return_type;
- ir_add_alloca(ira, new_call_instruction, impl_fn_type_id->return_type);
-
return ir_finish_anal(ira, new_call_instruction);
}
@@ -14957,7 +15143,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref,
casted_args, call_param_count, async_allocator_inst);
- ir_add_alloca(ira, result, result->value.type);
return ir_finish_anal(ira, result);
}
@@ -14967,15 +15152,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
return ira->codegen->invalid_instruction;
}
- IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb,
- call_instruction->base.scope, call_instruction->base.source_node,
- fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr, casted_new_stack);
+ IrInstruction *result_loc = ir_resolve_result_loc(ira, call_instruction->result_loc, return_type);
+ IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref,
+ call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack, result_loc);
new_call_instruction->value.type = return_type;
- ir_add_alloca(ira, new_call_instruction, return_type);
return ir_finish_anal(ira, new_call_instruction);
}
-static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) {
+static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) {
IrInstruction *fn_ref = call_instruction->fn_ref->child;
if (type_is_invalid(fn_ref->value.type))
return ira->codegen->invalid_instruction;
@@ -23304,6 +23488,9 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
case IrInstructionIdResizeSlice:
case IrInstructionIdLoadPtrGen:
case IrInstructionIdBitCastGen:
+ case IrInstructionIdCallGen:
+ case IrInstructionIdReturnPtr:
+ case IrInstructionIdAllocaGen:
zig_unreachable();
case IrInstructionIdReturn:
@@ -23326,8 +23513,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction);
case IrInstructionIdFieldPtr:
return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction);
- case IrInstructionIdCall:
- return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction);
+ case IrInstructionIdCallSrc:
+ return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction);
case IrInstructionIdBr:
return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction);
case IrInstructionIdCondBr:
@@ -23580,13 +23767,15 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction);
case IrInstructionIdUndeclaredIdent:
return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction);
+ case IrInstructionIdAllocaSrc:
+ return nullptr;
}
zig_unreachable();
}
static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *old_instruction) {
IrInstruction *new_instruction = ir_analyze_instruction_nocast(ira, old_instruction);
- ir_assert(new_instruction->value.type != nullptr, old_instruction);
+ ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction);
old_instruction->child = new_instruction;
return new_instruction;
}
@@ -23637,13 +23826,15 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
}
IrInstruction *new_instruction = ir_analyze_instruction(ira, old_instruction);
- if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) {
- return ira->codegen->builtin_types.entry_invalid;
- }
+ if (new_instruction != nullptr) {
+ if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) {
+ return ira->codegen->builtin_types.entry_invalid;
+ }
- // unreachable instructions do their own control flow.
- if (new_instruction->value.type->id == ZigTypeIdUnreachable)
- continue;
+ // unreachable instructions do their own control flow.
+ if (new_instruction->value.type->id == ZigTypeIdUnreachable)
+ continue;
+ }
ira->instruction_index += 1;
}
@@ -23668,7 +23859,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdDeclVarSrc:
case IrInstructionIdDeclVarGen:
case IrInstructionIdStorePtr:
- case IrInstructionIdCall:
+ case IrInstructionIdCallSrc:
+ case IrInstructionIdCallGen:
case IrInstructionIdReturn:
case IrInstructionIdUnreachable:
case IrInstructionIdSetCold:
@@ -23731,6 +23923,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdFieldPtr:
case IrInstructionIdElemPtr:
case IrInstructionIdVarPtr:
+ case IrInstructionIdReturnPtr:
case IrInstructionIdTypeOf:
case IrInstructionIdToPtrType:
case IrInstructionIdPtrTypeChild:
@@ -23818,6 +24011,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdVectorToArray:
case IrInstructionIdArrayToVector:
case IrInstructionIdHasDecl:
+ case IrInstructionIdAllocaSrc:
+ case IrInstructionIdAllocaGen:
return false;
case IrInstructionIdAsm:
src/ir_print.cpp
@@ -188,7 +188,7 @@ static void ir_print_decl_var_src(IrPrint *irp, IrInstructionDeclVarSrc *decl_va
fprintf(irp->f, " ");
}
fprintf(irp->f, "= ");
- ir_print_other_instruction(irp, decl_var_instruction->init_value);
+ ir_print_other_instruction(irp, decl_var_instruction->ptr);
if (decl_var_instruction->var->is_comptime != nullptr) {
fprintf(irp->f, " // comptime = ");
ir_print_other_instruction(irp, decl_var_instruction->var->is_comptime);
@@ -201,7 +201,29 @@ static void ir_print_cast(IrPrint *irp, IrInstructionCast *cast_instruction) {
fprintf(irp->f, " to %s", buf_ptr(&cast_instruction->dest_type->name));
}
-static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {
+static void ir_print_result_loc_var(IrPrint *irp, ResultLocVar *result_loc_var) {
+ fprintf(irp->f, "var(");
+ ir_print_other_instruction(irp, result_loc_var->base.source_instruction);
+ fprintf(irp->f, ")");
+}
+
+static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
+ switch (result_loc->id) {
+ case ResultLocIdInvalid:
+ zig_unreachable();
+ case ResultLocIdNone:
+ fprintf(irp->f, "none");
+ return;
+ case ResultLocIdReturn:
+ fprintf(irp->f, "return");
+ return;
+ case ResultLocIdVar:
+ return ir_print_result_loc_var(irp, (ResultLocVar *)result_loc);
+ }
+ zig_unreachable();
+}
+
+static void ir_print_call_src(IrPrint *irp, IrInstructionCallSrc *call_instruction) {
if (call_instruction->is_async) {
fprintf(irp->f, "async");
if (call_instruction->async_allocator != nullptr) {
@@ -224,7 +246,35 @@ static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {
fprintf(irp->f, ", ");
ir_print_other_instruction(irp, arg);
}
- fprintf(irp->f, ")");
+ fprintf(irp->f, ")result=");
+ ir_print_result_loc(irp, call_instruction->result_loc);
+}
+
+static void ir_print_call_gen(IrPrint *irp, IrInstructionCallGen *call_instruction) {
+ if (call_instruction->is_async) {
+ fprintf(irp->f, "async");
+ if (call_instruction->async_allocator != nullptr) {
+ fprintf(irp->f, "<");
+ ir_print_other_instruction(irp, call_instruction->async_allocator);
+ fprintf(irp->f, ">");
+ }
+ fprintf(irp->f, " ");
+ }
+ if (call_instruction->fn_entry) {
+ fprintf(irp->f, "%s", buf_ptr(&call_instruction->fn_entry->symbol_name));
+ } else {
+ assert(call_instruction->fn_ref);
+ ir_print_other_instruction(irp, call_instruction->fn_ref);
+ }
+ fprintf(irp->f, "(");
+ for (size_t i = 0; i < call_instruction->arg_count; i += 1) {
+ IrInstruction *arg = call_instruction->args[i];
+ if (i != 0)
+ fprintf(irp->f, ", ");
+ ir_print_other_instruction(irp, arg);
+ }
+ fprintf(irp->f, ")result=");
+ ir_print_other_instruction(irp, call_instruction->result_loc);
}
static void ir_print_cond_br(IrPrint *irp, IrInstructionCondBr *cond_br_instruction) {
@@ -331,6 +381,10 @@ static void ir_print_var_ptr(IrPrint *irp, IrInstructionVarPtr *instruction) {
fprintf(irp->f, "&%s", buf_ptr(&instruction->var->name));
}
+static void ir_print_return_ptr(IrPrint *irp, IrInstructionReturnPtr *instruction) {
+ fprintf(irp->f, "@ReturnPtr");
+}
+
static void ir_print_load_ptr(IrPrint *irp, IrInstructionLoadPtr *instruction) {
ir_print_other_instruction(irp, instruction->ptr);
fprintf(irp->f, ".*");
@@ -1064,6 +1118,16 @@ static void ir_print_resize_slice(IrPrint *irp, IrInstructionResizeSlice *instru
fprintf(irp->f, ")");
}
+static void ir_print_alloca_src(IrPrint *irp, IrInstructionAllocaSrc *instruction) {
+ fprintf(irp->f, "Alloca(align=");
+ ir_print_other_instruction(irp, instruction->align);
+ fprintf(irp->f, ",name=%s)", instruction->name_hint);
+}
+
+static void ir_print_alloca_gen(IrPrint *irp, IrInstructionAllocaGen *instruction) {
+ fprintf(irp->f, "Alloca(align=%" PRIu32 ",name=%s)", instruction->align, instruction->name_hint);
+}
+
static void ir_print_int_to_err(IrPrint *irp, IrInstructionIntToErr *instruction) {
fprintf(irp->f, "inttoerr ");
ir_print_other_instruction(irp, instruction->target);
@@ -1446,7 +1510,7 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va
fprintf(irp->f, "%s %s: %s align(%u) = ", var_or_const, name, buf_ptr(&var->var_type->name),
var->align_bytes);
- ir_print_other_instruction(irp, decl_var_instruction->init_value);
+ ir_print_other_instruction(irp, decl_var_instruction->var_ptr);
if (decl_var_instruction->var->is_comptime != nullptr) {
fprintf(irp->f, " // comptime = ");
ir_print_other_instruction(irp, decl_var_instruction->var->is_comptime);
@@ -1485,8 +1549,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdCast:
ir_print_cast(irp, (IrInstructionCast *)instruction);
break;
- case IrInstructionIdCall:
- ir_print_call(irp, (IrInstructionCall *)instruction);
+ case IrInstructionIdCallSrc:
+ ir_print_call_src(irp, (IrInstructionCallSrc *)instruction);
+ break;
+ case IrInstructionIdCallGen:
+ ir_print_call_gen(irp, (IrInstructionCallGen *)instruction);
break;
case IrInstructionIdUnOp:
ir_print_un_op(irp, (IrInstructionUnOp *)instruction);
@@ -1521,6 +1588,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdVarPtr:
ir_print_var_ptr(irp, (IrInstructionVarPtr *)instruction);
break;
+ case IrInstructionIdReturnPtr:
+ ir_print_return_ptr(irp, (IrInstructionReturnPtr *)instruction);
+ break;
case IrInstructionIdLoadPtr:
ir_print_load_ptr(irp, (IrInstructionLoadPtr *)instruction);
break;
@@ -1938,6 +2008,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdUndeclaredIdent:
ir_print_undeclared_ident(irp, (IrInstructionUndeclaredIdent *)instruction);
break;
+ case IrInstructionIdAllocaSrc:
+ ir_print_alloca_src(irp, (IrInstructionAllocaSrc *)instruction);
+ break;
+ case IrInstructionIdAllocaGen:
+ ir_print_alloca_gen(irp, (IrInstructionAllocaGen *)instruction);
+ break;
}
fprintf(irp->f, "\n");
}
BRANCH_TODO
@@ -0,0 +1,10 @@
+Scratch pad for stuff to do before merging master
+=================================================
+
+look at all the ir_gen_node ir_gen_node_extra calls and make sure result locations are properly propagated
+
+migrate all the alloca_list to alloca_gen_list
+
+migrate ir_build_var_decl_src to use ir_build_alloca_src and explicitly initialize
+
+inferred comptime
CMakeLists.txt
@@ -6728,6 +6728,7 @@ add_custom_command(
"-Doutput-dir=${CMAKE_BINARY_DIR}"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
DEPENDS
+ zig0
"${CMAKE_SOURCE_DIR}/src-self-hosted/dep_tokenizer.zig"
"${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig"
"${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig"