diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-01-29 23:33:12 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-01-29 23:33:12 -0500 |
| commit | a95dce15ae4bd95cfd2266da51ba860cc6524a1b (patch) | |
| tree | e761ecb74f37ff699d2e1f09d122811b101826e4 /src/ir.cpp | |
| parent | 800ead2810fa573a7e94979e707a14d4e066ef77 (diff) | |
| parent | 7ebc624a15c5a01d6bee8eaf9c7487b30ed1904c (diff) | |
| download | zig-a95dce15ae4bd95cfd2266da51ba860cc6524a1b.tar.gz zig-a95dce15ae4bd95cfd2266da51ba860cc6524a1b.zip | |
Merge remote-tracking branch 'origin/master' into llvm10
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 14443 |
1 files changed, 7719 insertions, 6724 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index db1faac37c..ef3426d111 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17,31 +17,33 @@ #include <errno.h> -struct IrExecContext { - ZigList<ZigValue *> mem_slot_list; +struct IrBuilderSrc { + CodeGen *codegen; + IrExecutableSrc *exec; + IrBasicBlockSrc *current_basic_block; + AstNode *main_block_node; }; -struct IrBuilder { +struct IrBuilderGen { CodeGen *codegen; - IrExecutable *exec; - IrBasicBlock *current_basic_block; - AstNode *main_block_node; + IrExecutableGen *exec; + IrBasicBlockGen *current_basic_block; }; struct IrAnalyze { CodeGen *codegen; - IrBuilder old_irb; - IrBuilder new_irb; - IrExecContext exec_context; + IrBuilderSrc old_irb; + IrBuilderGen new_irb; size_t old_bb_index; size_t instruction_index; ZigType *explicit_return_type; AstNode *explicit_return_type_source_node; - ZigList<IrInstruction *> src_implicit_return_type_list; + ZigList<IrInstGen *> src_implicit_return_type_list; ZigList<IrSuspendPosition> resume_stack; - IrBasicBlock *const_predecessor_bb; + IrBasicBlockSrc *const_predecessor_bb; size_t ref_count; size_t break_debug_id; // for debugging purposes + IrInstGen *return_ptr; // For the purpose of using in a debugger void dump(); @@ -206,412 +208,538 @@ struct DbgIrBreakPoint { DbgIrBreakPoint dbg_ir_breakpoints_buf[20]; size_t dbg_ir_breakpoints_count = 0; -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 IrInstSrc *ir_gen_node(IrBuilderSrc *irb, AstNode *node, Scope *scope); +static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *scope, LVal lval, ResultLoc *result_loc); -static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type); -static IrInstruction *ir_implicit_cast2(IrAnalyze *ira, IrInstruction *value_source_instr, - IrInstruction *value, ZigType *expected_type); -static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr, +static IrInstGen *ir_implicit_cast(IrAnalyze *ira, IrInstGen *value, ZigType *expected_type); +static IrInstGen *ir_implicit_cast2(IrAnalyze *ira, IrInst *value_source_instr, + IrInstGen *value, ZigType *expected_type); +static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst *source_instr, IrInstGen *ptr, ResultLoc *result_loc); -static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg); -static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, - IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing); -static void ir_assert(bool ok, IrInstruction *source_instruction); -static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var); -static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op); -static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval, ResultLoc *result_loc); -static IrInstruction *ir_expr_wrap(IrBuilder *irb, Scope *scope, IrInstruction *inst, ResultLoc *result_loc); +static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutableSrc *exec, AstNode *source_node, Buf *msg); +static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, + IrInst* source_instr, IrInstGen *container_ptr, IrInst *container_ptr_src, + ZigType *container_type, bool initializing); +static void ir_assert(bool ok, IrInst* source_instruction); +static void ir_assert_gen(bool ok, IrInstGen *source_instruction); +static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *var); +static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op); +static IrInstSrc *ir_lval_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *value, LVal lval, ResultLoc *result_loc); +static IrInstSrc *ir_expr_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *inst, ResultLoc *result_loc); static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align); static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align); static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ZigValue *val); static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val); static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, ZigValue *out_val, ZigValue *ptr_val); -static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, - ZigType *dest_type, IrInstruction *dest_type_src, bool safety_check_on); -static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed); +static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr, + IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on); +static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed undef_allowed); static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); -static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, +static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, ZigType *ptr_type); -static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, +static IrInstGen *ir_analyze_bit_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, ZigType *dest_type); -static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, - ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, - bool non_null_comptime, bool allow_discard); -static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, - ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, - bool non_null_comptime, bool allow_discard); -static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *base_ptr, bool safety_check_on, bool initializing); -static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *base_ptr, bool safety_check_on, bool initializing); -static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *base_ptr, bool initializing); -static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const); -static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, +static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_instr, + ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime, bool allow_discard); +static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr, + ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime, bool allow_discard); +static IrInstGen *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *base_ptr, bool safety_check_on, bool initializing); +static IrInstGen *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *base_ptr, bool safety_check_on, bool initializing); +static IrInstGen *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *base_ptr, bool initializing); +static IrInstGen *ir_analyze_store_ptr(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *ptr, IrInstGen *uncasted_value, bool allow_write_through_const); +static IrInstSrc *ir_gen_union_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *union_type, IrInstSrc *field_name, AstNode *expr_node, LVal lval, ResultLoc *parent_result_loc); static void ir_reset_result(ResultLoc *result_loc); -static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, +static Buf *get_anon_type_name(CodeGen *codegen, IrExecutableSrc *exec, const char *kind_name, Scope *scope, AstNode *source_node, Buf *out_bare_name); -static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type, +static ResultLocCast *ir_build_cast_result_loc(IrBuilderSrc *irb, IrInstSrc *dest_type, ResultLoc *parent_result_loc); -static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, - TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing); -static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, - IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type); +static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_instr, + TypeStructField *field, IrInstGen *struct_ptr, ZigType *struct_type, bool initializing); +static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, + IrInst* source_instr, IrInstGen *container_ptr, ZigType *container_type); static ResultLoc *no_result_loc(void); -static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value); +static IrInstGen *ir_analyze_test_non_null(IrAnalyze *ira, IrInst *source_inst, IrInstGen *value); +static IrInstGen *ir_error_dependency_loop(IrAnalyze *ira, IrInst *source_instr); -static void destroy_instruction(IrInstruction *inst) { +static void destroy_instruction_src(IrInstSrc *inst) { #ifdef ZIG_ENABLE_MEM_PROFILE - const char *name = ir_instruction_type_str(inst->id); + const char *name = ir_inst_src_type_str(inst->id); #else const char *name = nullptr; #endif switch (inst->id) { - case IrInstructionIdInvalid: + case IrInstSrcIdInvalid: zig_unreachable(); - case IrInstructionIdReturn: - return destroy(reinterpret_cast<IrInstructionReturn *>(inst), name); - case IrInstructionIdConst: - return destroy(reinterpret_cast<IrInstructionConst *>(inst), name); - case IrInstructionIdBinOp: - return destroy(reinterpret_cast<IrInstructionBinOp *>(inst), name); - case IrInstructionIdMergeErrSets: - return destroy(reinterpret_cast<IrInstructionMergeErrSets *>(inst), name); - case IrInstructionIdDeclVarSrc: - return destroy(reinterpret_cast<IrInstructionDeclVarSrc *>(inst), name); - case IrInstructionIdCast: - return destroy(reinterpret_cast<IrInstructionCast *>(inst), name); - case IrInstructionIdCallSrc: - return destroy(reinterpret_cast<IrInstructionCallSrc *>(inst), name); - case IrInstructionIdCallSrcArgs: - return destroy(reinterpret_cast<IrInstructionCallSrcArgs *>(inst), name); - case IrInstructionIdCallExtra: - return destroy(reinterpret_cast<IrInstructionCallExtra *>(inst), name); - case IrInstructionIdCallGen: - return destroy(reinterpret_cast<IrInstructionCallGen *>(inst), name); - case IrInstructionIdUnOp: - return destroy(reinterpret_cast<IrInstructionUnOp *>(inst), name); - case IrInstructionIdCondBr: - return destroy(reinterpret_cast<IrInstructionCondBr *>(inst), name); - case IrInstructionIdBr: - return destroy(reinterpret_cast<IrInstructionBr *>(inst), name); - case IrInstructionIdPhi: - return destroy(reinterpret_cast<IrInstructionPhi *>(inst), name); - case IrInstructionIdContainerInitList: - return destroy(reinterpret_cast<IrInstructionContainerInitList *>(inst), name); - case IrInstructionIdContainerInitFields: - return destroy(reinterpret_cast<IrInstructionContainerInitFields *>(inst), name); - case IrInstructionIdUnreachable: - return destroy(reinterpret_cast<IrInstructionUnreachable *>(inst), name); - case IrInstructionIdElemPtr: - return destroy(reinterpret_cast<IrInstructionElemPtr *>(inst), name); - case IrInstructionIdVarPtr: - return destroy(reinterpret_cast<IrInstructionVarPtr *>(inst), name); - case IrInstructionIdReturnPtr: - return destroy(reinterpret_cast<IrInstructionReturnPtr *>(inst), name); - case IrInstructionIdLoadPtr: - return destroy(reinterpret_cast<IrInstructionLoadPtr *>(inst), name); - case IrInstructionIdLoadPtrGen: - return destroy(reinterpret_cast<IrInstructionLoadPtrGen *>(inst), name); - case IrInstructionIdStorePtr: - return destroy(reinterpret_cast<IrInstructionStorePtr *>(inst), name); - case IrInstructionIdVectorStoreElem: - return destroy(reinterpret_cast<IrInstructionVectorStoreElem *>(inst), name); - case IrInstructionIdTypeOf: - return destroy(reinterpret_cast<IrInstructionTypeOf *>(inst), name); - case IrInstructionIdFieldPtr: - return destroy(reinterpret_cast<IrInstructionFieldPtr *>(inst), name); - case IrInstructionIdStructFieldPtr: - return destroy(reinterpret_cast<IrInstructionStructFieldPtr *>(inst), name); - case IrInstructionIdUnionFieldPtr: - return destroy(reinterpret_cast<IrInstructionUnionFieldPtr *>(inst), name); - case IrInstructionIdSetCold: - return destroy(reinterpret_cast<IrInstructionSetCold *>(inst), name); - case IrInstructionIdSetRuntimeSafety: - return destroy(reinterpret_cast<IrInstructionSetRuntimeSafety *>(inst), name); - case IrInstructionIdSetFloatMode: - return destroy(reinterpret_cast<IrInstructionSetFloatMode *>(inst), name); - case IrInstructionIdArrayType: - return destroy(reinterpret_cast<IrInstructionArrayType *>(inst), name); - case IrInstructionIdSliceType: - return destroy(reinterpret_cast<IrInstructionSliceType *>(inst), name); - case IrInstructionIdAnyFrameType: - return destroy(reinterpret_cast<IrInstructionAnyFrameType *>(inst), name); - case IrInstructionIdAsmSrc: - return destroy(reinterpret_cast<IrInstructionAsmSrc *>(inst), name); - case IrInstructionIdAsmGen: - return destroy(reinterpret_cast<IrInstructionAsmGen *>(inst), name); - case IrInstructionIdSizeOf: - return destroy(reinterpret_cast<IrInstructionSizeOf *>(inst), name); - case IrInstructionIdTestNonNull: - return destroy(reinterpret_cast<IrInstructionTestNonNull *>(inst), name); - case IrInstructionIdOptionalUnwrapPtr: - return destroy(reinterpret_cast<IrInstructionOptionalUnwrapPtr *>(inst), name); - case IrInstructionIdPopCount: - return destroy(reinterpret_cast<IrInstructionPopCount *>(inst), name); - case IrInstructionIdClz: - return destroy(reinterpret_cast<IrInstructionClz *>(inst), name); - case IrInstructionIdCtz: - return destroy(reinterpret_cast<IrInstructionCtz *>(inst), name); - case IrInstructionIdBswap: - return destroy(reinterpret_cast<IrInstructionBswap *>(inst), name); - case IrInstructionIdBitReverse: - return destroy(reinterpret_cast<IrInstructionBitReverse *>(inst), name); - case IrInstructionIdSwitchBr: - return destroy(reinterpret_cast<IrInstructionSwitchBr *>(inst), name); - case IrInstructionIdSwitchVar: - return destroy(reinterpret_cast<IrInstructionSwitchVar *>(inst), name); - case IrInstructionIdSwitchElseVar: - return destroy(reinterpret_cast<IrInstructionSwitchElseVar *>(inst), name); - case IrInstructionIdSwitchTarget: - return destroy(reinterpret_cast<IrInstructionSwitchTarget *>(inst), name); - case IrInstructionIdUnionTag: - return destroy(reinterpret_cast<IrInstructionUnionTag *>(inst), name); - case IrInstructionIdImport: - return destroy(reinterpret_cast<IrInstructionImport *>(inst), name); - case IrInstructionIdRef: - return destroy(reinterpret_cast<IrInstructionRef *>(inst), name); - case IrInstructionIdRefGen: - return destroy(reinterpret_cast<IrInstructionRefGen *>(inst), name); - case IrInstructionIdCompileErr: - return destroy(reinterpret_cast<IrInstructionCompileErr *>(inst), name); - case IrInstructionIdCompileLog: - return destroy(reinterpret_cast<IrInstructionCompileLog *>(inst), name); - case IrInstructionIdErrName: - return destroy(reinterpret_cast<IrInstructionErrName *>(inst), name); - case IrInstructionIdCImport: - return destroy(reinterpret_cast<IrInstructionCImport *>(inst), name); - case IrInstructionIdCInclude: - return destroy(reinterpret_cast<IrInstructionCInclude *>(inst), name); - case IrInstructionIdCDefine: - return destroy(reinterpret_cast<IrInstructionCDefine *>(inst), name); - case IrInstructionIdCUndef: - return destroy(reinterpret_cast<IrInstructionCUndef *>(inst), name); - case IrInstructionIdEmbedFile: - return destroy(reinterpret_cast<IrInstructionEmbedFile *>(inst), name); - case IrInstructionIdCmpxchgSrc: - return destroy(reinterpret_cast<IrInstructionCmpxchgSrc *>(inst), name); - case IrInstructionIdCmpxchgGen: - return destroy(reinterpret_cast<IrInstructionCmpxchgGen *>(inst), name); - case IrInstructionIdFence: - return destroy(reinterpret_cast<IrInstructionFence *>(inst), name); - case IrInstructionIdTruncate: - return destroy(reinterpret_cast<IrInstructionTruncate *>(inst), name); - case IrInstructionIdIntCast: - return destroy(reinterpret_cast<IrInstructionIntCast *>(inst), name); - case IrInstructionIdFloatCast: - return destroy(reinterpret_cast<IrInstructionFloatCast *>(inst), name); - case IrInstructionIdErrSetCast: - return destroy(reinterpret_cast<IrInstructionErrSetCast *>(inst), name); - case IrInstructionIdFromBytes: - return destroy(reinterpret_cast<IrInstructionFromBytes *>(inst), name); - case IrInstructionIdToBytes: - return destroy(reinterpret_cast<IrInstructionToBytes *>(inst), name); - case IrInstructionIdIntToFloat: - return destroy(reinterpret_cast<IrInstructionIntToFloat *>(inst), name); - case IrInstructionIdFloatToInt: - return destroy(reinterpret_cast<IrInstructionFloatToInt *>(inst), name); - case IrInstructionIdBoolToInt: - return destroy(reinterpret_cast<IrInstructionBoolToInt *>(inst), name); - case IrInstructionIdIntType: - return destroy(reinterpret_cast<IrInstructionIntType *>(inst), name); - case IrInstructionIdVectorType: - return destroy(reinterpret_cast<IrInstructionVectorType *>(inst), name); - case IrInstructionIdShuffleVector: - return destroy(reinterpret_cast<IrInstructionShuffleVector *>(inst), name); - case IrInstructionIdSplatSrc: - return destroy(reinterpret_cast<IrInstructionSplatSrc *>(inst), name); - case IrInstructionIdSplatGen: - return destroy(reinterpret_cast<IrInstructionSplatGen *>(inst), name); - case IrInstructionIdBoolNot: - return destroy(reinterpret_cast<IrInstructionBoolNot *>(inst), name); - case IrInstructionIdMemset: - return destroy(reinterpret_cast<IrInstructionMemset *>(inst), name); - case IrInstructionIdMemcpy: - return destroy(reinterpret_cast<IrInstructionMemcpy *>(inst), name); - case IrInstructionIdSliceSrc: - return destroy(reinterpret_cast<IrInstructionSliceSrc *>(inst), name); - case IrInstructionIdSliceGen: - return destroy(reinterpret_cast<IrInstructionSliceGen *>(inst), name); - case IrInstructionIdMemberCount: - return destroy(reinterpret_cast<IrInstructionMemberCount *>(inst), name); - case IrInstructionIdMemberType: - return destroy(reinterpret_cast<IrInstructionMemberType *>(inst), name); - case IrInstructionIdMemberName: - return destroy(reinterpret_cast<IrInstructionMemberName *>(inst), name); - case IrInstructionIdBreakpoint: - return destroy(reinterpret_cast<IrInstructionBreakpoint *>(inst), name); - case IrInstructionIdReturnAddress: - return destroy(reinterpret_cast<IrInstructionReturnAddress *>(inst), name); - case IrInstructionIdFrameAddress: - return destroy(reinterpret_cast<IrInstructionFrameAddress *>(inst), name); - case IrInstructionIdFrameHandle: - return destroy(reinterpret_cast<IrInstructionFrameHandle *>(inst), name); - case IrInstructionIdFrameType: - return destroy(reinterpret_cast<IrInstructionFrameType *>(inst), name); - case IrInstructionIdFrameSizeSrc: - return destroy(reinterpret_cast<IrInstructionFrameSizeSrc *>(inst), name); - case IrInstructionIdFrameSizeGen: - return destroy(reinterpret_cast<IrInstructionFrameSizeGen *>(inst), name); - case IrInstructionIdAlignOf: - return destroy(reinterpret_cast<IrInstructionAlignOf *>(inst), name); - case IrInstructionIdOverflowOp: - return destroy(reinterpret_cast<IrInstructionOverflowOp *>(inst), name); - case IrInstructionIdTestErrSrc: - return destroy(reinterpret_cast<IrInstructionTestErrSrc *>(inst), name); - case IrInstructionIdTestErrGen: - return destroy(reinterpret_cast<IrInstructionTestErrGen *>(inst), name); - case IrInstructionIdUnwrapErrCode: - return destroy(reinterpret_cast<IrInstructionUnwrapErrCode *>(inst), name); - case IrInstructionIdUnwrapErrPayload: - return destroy(reinterpret_cast<IrInstructionUnwrapErrPayload *>(inst), name); - case IrInstructionIdOptionalWrap: - return destroy(reinterpret_cast<IrInstructionOptionalWrap *>(inst), name); - case IrInstructionIdErrWrapCode: - return destroy(reinterpret_cast<IrInstructionErrWrapCode *>(inst), name); - case IrInstructionIdErrWrapPayload: - return destroy(reinterpret_cast<IrInstructionErrWrapPayload *>(inst), name); - case IrInstructionIdFnProto: - return destroy(reinterpret_cast<IrInstructionFnProto *>(inst), name); - case IrInstructionIdTestComptime: - return destroy(reinterpret_cast<IrInstructionTestComptime *>(inst), name); - case IrInstructionIdPtrCastSrc: - return destroy(reinterpret_cast<IrInstructionPtrCastSrc *>(inst), name); - case IrInstructionIdPtrCastGen: - return destroy(reinterpret_cast<IrInstructionPtrCastGen *>(inst), name); - case IrInstructionIdBitCastSrc: - return destroy(reinterpret_cast<IrInstructionBitCastSrc *>(inst), name); - case IrInstructionIdBitCastGen: - return destroy(reinterpret_cast<IrInstructionBitCastGen *>(inst), name); - case IrInstructionIdWidenOrShorten: - return destroy(reinterpret_cast<IrInstructionWidenOrShorten *>(inst), name); - case IrInstructionIdPtrToInt: - return destroy(reinterpret_cast<IrInstructionPtrToInt *>(inst), name); - case IrInstructionIdIntToPtr: - return destroy(reinterpret_cast<IrInstructionIntToPtr *>(inst), name); - case IrInstructionIdIntToEnum: - return destroy(reinterpret_cast<IrInstructionIntToEnum *>(inst), name); - case IrInstructionIdIntToErr: - return destroy(reinterpret_cast<IrInstructionIntToErr *>(inst), name); - case IrInstructionIdErrToInt: - return destroy(reinterpret_cast<IrInstructionErrToInt *>(inst), name); - case IrInstructionIdCheckSwitchProngs: - return destroy(reinterpret_cast<IrInstructionCheckSwitchProngs *>(inst), name); - case IrInstructionIdCheckStatementIsVoid: - return destroy(reinterpret_cast<IrInstructionCheckStatementIsVoid *>(inst), name); - case IrInstructionIdTypeName: - return destroy(reinterpret_cast<IrInstructionTypeName *>(inst), name); - case IrInstructionIdTagName: - return destroy(reinterpret_cast<IrInstructionTagName *>(inst), name); - case IrInstructionIdPtrType: - return destroy(reinterpret_cast<IrInstructionPtrType *>(inst), name); - case IrInstructionIdDeclRef: - return destroy(reinterpret_cast<IrInstructionDeclRef *>(inst), name); - case IrInstructionIdPanic: - return destroy(reinterpret_cast<IrInstructionPanic *>(inst), name); - case IrInstructionIdFieldParentPtr: - return destroy(reinterpret_cast<IrInstructionFieldParentPtr *>(inst), name); - case IrInstructionIdByteOffsetOf: - return destroy(reinterpret_cast<IrInstructionByteOffsetOf *>(inst), name); - case IrInstructionIdBitOffsetOf: - return destroy(reinterpret_cast<IrInstructionBitOffsetOf *>(inst), name); - case IrInstructionIdTypeInfo: - return destroy(reinterpret_cast<IrInstructionTypeInfo *>(inst), name); - case IrInstructionIdType: - return destroy(reinterpret_cast<IrInstructionType *>(inst), name); - case IrInstructionIdHasField: - return destroy(reinterpret_cast<IrInstructionHasField *>(inst), name); - case IrInstructionIdTypeId: - return destroy(reinterpret_cast<IrInstructionTypeId *>(inst), name); - case IrInstructionIdSetEvalBranchQuota: - return destroy(reinterpret_cast<IrInstructionSetEvalBranchQuota *>(inst), name); - case IrInstructionIdAlignCast: - return destroy(reinterpret_cast<IrInstructionAlignCast *>(inst), name); - case IrInstructionIdImplicitCast: - return destroy(reinterpret_cast<IrInstructionImplicitCast *>(inst), name); - case IrInstructionIdResolveResult: - return destroy(reinterpret_cast<IrInstructionResolveResult *>(inst), name); - case IrInstructionIdResetResult: - return destroy(reinterpret_cast<IrInstructionResetResult *>(inst), name); - case IrInstructionIdOpaqueType: - return destroy(reinterpret_cast<IrInstructionOpaqueType *>(inst), name); - case IrInstructionIdSetAlignStack: - return destroy(reinterpret_cast<IrInstructionSetAlignStack *>(inst), name); - case IrInstructionIdArgType: - return destroy(reinterpret_cast<IrInstructionArgType *>(inst), name); - case IrInstructionIdTagType: - return destroy(reinterpret_cast<IrInstructionTagType *>(inst), name); - case IrInstructionIdExport: - return destroy(reinterpret_cast<IrInstructionExport *>(inst), name); - case IrInstructionIdErrorReturnTrace: - return destroy(reinterpret_cast<IrInstructionErrorReturnTrace *>(inst), name); - case IrInstructionIdErrorUnion: - return destroy(reinterpret_cast<IrInstructionErrorUnion *>(inst), name); - case IrInstructionIdAtomicRmw: - return destroy(reinterpret_cast<IrInstructionAtomicRmw *>(inst), name); - case IrInstructionIdSaveErrRetAddr: - return destroy(reinterpret_cast<IrInstructionSaveErrRetAddr *>(inst), name); - case IrInstructionIdAddImplicitReturnType: - return destroy(reinterpret_cast<IrInstructionAddImplicitReturnType *>(inst), name); - case IrInstructionIdFloatOp: - return destroy(reinterpret_cast<IrInstructionFloatOp *>(inst), name); - case IrInstructionIdMulAdd: - return destroy(reinterpret_cast<IrInstructionMulAdd *>(inst), name); - case IrInstructionIdAtomicLoad: - return destroy(reinterpret_cast<IrInstructionAtomicLoad *>(inst), name); - case IrInstructionIdAtomicStore: - return destroy(reinterpret_cast<IrInstructionAtomicStore *>(inst), name); - case IrInstructionIdEnumToInt: - return destroy(reinterpret_cast<IrInstructionEnumToInt *>(inst), name); - case IrInstructionIdCheckRuntimeScope: - return destroy(reinterpret_cast<IrInstructionCheckRuntimeScope *>(inst), name); - case IrInstructionIdDeclVarGen: - return destroy(reinterpret_cast<IrInstructionDeclVarGen *>(inst), name); - case IrInstructionIdArrayToVector: - return destroy(reinterpret_cast<IrInstructionArrayToVector *>(inst), name); - case IrInstructionIdVectorToArray: - return destroy(reinterpret_cast<IrInstructionVectorToArray *>(inst), name); - case IrInstructionIdPtrOfArrayToSlice: - return destroy(reinterpret_cast<IrInstructionPtrOfArrayToSlice *>(inst), name); - case IrInstructionIdAssertZero: - return destroy(reinterpret_cast<IrInstructionAssertZero *>(inst), name); - case IrInstructionIdAssertNonNull: - return destroy(reinterpret_cast<IrInstructionAssertNonNull *>(inst), name); - case IrInstructionIdResizeSlice: - return destroy(reinterpret_cast<IrInstructionResizeSlice *>(inst), name); - case IrInstructionIdHasDecl: - return destroy(reinterpret_cast<IrInstructionHasDecl *>(inst), name); - case IrInstructionIdUndeclaredIdent: - return destroy(reinterpret_cast<IrInstructionUndeclaredIdent *>(inst), name); - case IrInstructionIdAllocaSrc: - return destroy(reinterpret_cast<IrInstructionAllocaSrc *>(inst), name); - case IrInstructionIdAllocaGen: - return destroy(reinterpret_cast<IrInstructionAllocaGen *>(inst), name); - case IrInstructionIdEndExpr: - return destroy(reinterpret_cast<IrInstructionEndExpr *>(inst), name); - case IrInstructionIdUnionInitNamedField: - return destroy(reinterpret_cast<IrInstructionUnionInitNamedField *>(inst), name); - case IrInstructionIdSuspendBegin: - return destroy(reinterpret_cast<IrInstructionSuspendBegin *>(inst), name); - case IrInstructionIdSuspendFinish: - return destroy(reinterpret_cast<IrInstructionSuspendFinish *>(inst), name); - case IrInstructionIdResume: - return destroy(reinterpret_cast<IrInstructionResume *>(inst), name); - case IrInstructionIdAwaitSrc: - return destroy(reinterpret_cast<IrInstructionAwaitSrc *>(inst), name); - case IrInstructionIdAwaitGen: - return destroy(reinterpret_cast<IrInstructionAwaitGen *>(inst), name); - case IrInstructionIdSpillBegin: - return destroy(reinterpret_cast<IrInstructionSpillBegin *>(inst), name); - case IrInstructionIdSpillEnd: - return destroy(reinterpret_cast<IrInstructionSpillEnd *>(inst), name); - case IrInstructionIdVectorExtractElem: - return destroy(reinterpret_cast<IrInstructionVectorExtractElem *>(inst), name); + case IrInstSrcIdReturn: + return destroy(reinterpret_cast<IrInstSrcReturn *>(inst), name); + case IrInstSrcIdConst: + return destroy(reinterpret_cast<IrInstSrcConst *>(inst), name); + case IrInstSrcIdBinOp: + return destroy(reinterpret_cast<IrInstSrcBinOp *>(inst), name); + case IrInstSrcIdMergeErrSets: + return destroy(reinterpret_cast<IrInstSrcMergeErrSets *>(inst), name); + case IrInstSrcIdDeclVar: + return destroy(reinterpret_cast<IrInstSrcDeclVar *>(inst), name); + case IrInstSrcIdCall: + return destroy(reinterpret_cast<IrInstSrcCall *>(inst), name); + case IrInstSrcIdCallExtra: + return destroy(reinterpret_cast<IrInstSrcCallExtra *>(inst), name); + case IrInstSrcIdUnOp: + return destroy(reinterpret_cast<IrInstSrcUnOp *>(inst), name); + case IrInstSrcIdCondBr: + return destroy(reinterpret_cast<IrInstSrcCondBr *>(inst), name); + case IrInstSrcIdBr: + return destroy(reinterpret_cast<IrInstSrcBr *>(inst), name); + case IrInstSrcIdPhi: + return destroy(reinterpret_cast<IrInstSrcPhi *>(inst), name); + case IrInstSrcIdContainerInitList: + return destroy(reinterpret_cast<IrInstSrcContainerInitList *>(inst), name); + case IrInstSrcIdContainerInitFields: + return destroy(reinterpret_cast<IrInstSrcContainerInitFields *>(inst), name); + case IrInstSrcIdUnreachable: + return destroy(reinterpret_cast<IrInstSrcUnreachable *>(inst), name); + case IrInstSrcIdElemPtr: + return destroy(reinterpret_cast<IrInstSrcElemPtr *>(inst), name); + case IrInstSrcIdVarPtr: + return destroy(reinterpret_cast<IrInstSrcVarPtr *>(inst), name); + case IrInstSrcIdLoadPtr: + return destroy(reinterpret_cast<IrInstSrcLoadPtr *>(inst), name); + case IrInstSrcIdStorePtr: + return destroy(reinterpret_cast<IrInstSrcStorePtr *>(inst), name); + case IrInstSrcIdTypeOf: + return destroy(reinterpret_cast<IrInstSrcTypeOf *>(inst), name); + case IrInstSrcIdFieldPtr: + return destroy(reinterpret_cast<IrInstSrcFieldPtr *>(inst), name); + case IrInstSrcIdSetCold: + return destroy(reinterpret_cast<IrInstSrcSetCold *>(inst), name); + case IrInstSrcIdSetRuntimeSafety: + return destroy(reinterpret_cast<IrInstSrcSetRuntimeSafety *>(inst), name); + case IrInstSrcIdSetFloatMode: + return destroy(reinterpret_cast<IrInstSrcSetFloatMode *>(inst), name); + case IrInstSrcIdArrayType: + return destroy(reinterpret_cast<IrInstSrcArrayType *>(inst), name); + case IrInstSrcIdSliceType: + return destroy(reinterpret_cast<IrInstSrcSliceType *>(inst), name); + case IrInstSrcIdAnyFrameType: + return destroy(reinterpret_cast<IrInstSrcAnyFrameType *>(inst), name); + case IrInstSrcIdAsm: + return destroy(reinterpret_cast<IrInstSrcAsm *>(inst), name); + case IrInstSrcIdSizeOf: + return destroy(reinterpret_cast<IrInstSrcSizeOf *>(inst), name); + case IrInstSrcIdTestNonNull: + return destroy(reinterpret_cast<IrInstSrcTestNonNull *>(inst), name); + case IrInstSrcIdOptionalUnwrapPtr: + return destroy(reinterpret_cast<IrInstSrcOptionalUnwrapPtr *>(inst), name); + case IrInstSrcIdPopCount: + return destroy(reinterpret_cast<IrInstSrcPopCount *>(inst), name); + case IrInstSrcIdClz: + return destroy(reinterpret_cast<IrInstSrcClz *>(inst), name); + case IrInstSrcIdCtz: + return destroy(reinterpret_cast<IrInstSrcCtz *>(inst), name); + case IrInstSrcIdBswap: + return destroy(reinterpret_cast<IrInstSrcBswap *>(inst), name); + case IrInstSrcIdBitReverse: + return destroy(reinterpret_cast<IrInstSrcBitReverse *>(inst), name); + case IrInstSrcIdSwitchBr: + return destroy(reinterpret_cast<IrInstSrcSwitchBr *>(inst), name); + case IrInstSrcIdSwitchVar: + return destroy(reinterpret_cast<IrInstSrcSwitchVar *>(inst), name); + case IrInstSrcIdSwitchElseVar: + return destroy(reinterpret_cast<IrInstSrcSwitchElseVar *>(inst), name); + case IrInstSrcIdSwitchTarget: + return destroy(reinterpret_cast<IrInstSrcSwitchTarget *>(inst), name); + case IrInstSrcIdImport: + return destroy(reinterpret_cast<IrInstSrcImport *>(inst), name); + case IrInstSrcIdRef: + return destroy(reinterpret_cast<IrInstSrcRef *>(inst), name); + case IrInstSrcIdCompileErr: + return destroy(reinterpret_cast<IrInstSrcCompileErr *>(inst), name); + case IrInstSrcIdCompileLog: + return destroy(reinterpret_cast<IrInstSrcCompileLog *>(inst), name); + case IrInstSrcIdErrName: + return destroy(reinterpret_cast<IrInstSrcErrName *>(inst), name); + case IrInstSrcIdCImport: + return destroy(reinterpret_cast<IrInstSrcCImport *>(inst), name); + case IrInstSrcIdCInclude: + return destroy(reinterpret_cast<IrInstSrcCInclude *>(inst), name); + case IrInstSrcIdCDefine: + return destroy(reinterpret_cast<IrInstSrcCDefine *>(inst), name); + case IrInstSrcIdCUndef: + return destroy(reinterpret_cast<IrInstSrcCUndef *>(inst), name); + case IrInstSrcIdEmbedFile: + return destroy(reinterpret_cast<IrInstSrcEmbedFile *>(inst), name); + case IrInstSrcIdCmpxchg: + return destroy(reinterpret_cast<IrInstSrcCmpxchg *>(inst), name); + case IrInstSrcIdFence: + return destroy(reinterpret_cast<IrInstSrcFence *>(inst), name); + case IrInstSrcIdTruncate: + return destroy(reinterpret_cast<IrInstSrcTruncate *>(inst), name); + case IrInstSrcIdIntCast: + return destroy(reinterpret_cast<IrInstSrcIntCast *>(inst), name); + case IrInstSrcIdFloatCast: + return destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst), name); + case IrInstSrcIdErrSetCast: + return destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst), name); + case IrInstSrcIdFromBytes: + return destroy(reinterpret_cast<IrInstSrcFromBytes *>(inst), name); + case IrInstSrcIdToBytes: + return destroy(reinterpret_cast<IrInstSrcToBytes *>(inst), name); + case IrInstSrcIdIntToFloat: + return destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst), name); + case IrInstSrcIdFloatToInt: + return destroy(reinterpret_cast<IrInstSrcFloatToInt *>(inst), name); + case IrInstSrcIdBoolToInt: + return destroy(reinterpret_cast<IrInstSrcBoolToInt *>(inst), name); + case IrInstSrcIdIntType: + return destroy(reinterpret_cast<IrInstSrcIntType *>(inst), name); + case IrInstSrcIdVectorType: + return destroy(reinterpret_cast<IrInstSrcVectorType *>(inst), name); + case IrInstSrcIdShuffleVector: + return destroy(reinterpret_cast<IrInstSrcShuffleVector *>(inst), name); + case IrInstSrcIdSplat: + return destroy(reinterpret_cast<IrInstSrcSplat *>(inst), name); + case IrInstSrcIdBoolNot: + return destroy(reinterpret_cast<IrInstSrcBoolNot *>(inst), name); + case IrInstSrcIdMemset: + return destroy(reinterpret_cast<IrInstSrcMemset *>(inst), name); + case IrInstSrcIdMemcpy: + return destroy(reinterpret_cast<IrInstSrcMemcpy *>(inst), name); + case IrInstSrcIdSlice: + return destroy(reinterpret_cast<IrInstSrcSlice *>(inst), name); + case IrInstSrcIdMemberCount: + return destroy(reinterpret_cast<IrInstSrcMemberCount *>(inst), name); + case IrInstSrcIdMemberType: + return destroy(reinterpret_cast<IrInstSrcMemberType *>(inst), name); + case IrInstSrcIdMemberName: + return destroy(reinterpret_cast<IrInstSrcMemberName *>(inst), name); + case IrInstSrcIdBreakpoint: + return destroy(reinterpret_cast<IrInstSrcBreakpoint *>(inst), name); + case IrInstSrcIdReturnAddress: + return destroy(reinterpret_cast<IrInstSrcReturnAddress *>(inst), name); + case IrInstSrcIdFrameAddress: + return destroy(reinterpret_cast<IrInstSrcFrameAddress *>(inst), name); + case IrInstSrcIdFrameHandle: + return destroy(reinterpret_cast<IrInstSrcFrameHandle *>(inst), name); + case IrInstSrcIdFrameType: + return destroy(reinterpret_cast<IrInstSrcFrameType *>(inst), name); + case IrInstSrcIdFrameSize: + return destroy(reinterpret_cast<IrInstSrcFrameSize *>(inst), name); + case IrInstSrcIdAlignOf: + return destroy(reinterpret_cast<IrInstSrcAlignOf *>(inst), name); + case IrInstSrcIdOverflowOp: + return destroy(reinterpret_cast<IrInstSrcOverflowOp *>(inst), name); + case IrInstSrcIdTestErr: + return destroy(reinterpret_cast<IrInstSrcTestErr *>(inst), name); + case IrInstSrcIdUnwrapErrCode: + return destroy(reinterpret_cast<IrInstSrcUnwrapErrCode *>(inst), name); + case IrInstSrcIdUnwrapErrPayload: + return destroy(reinterpret_cast<IrInstSrcUnwrapErrPayload *>(inst), name); + case IrInstSrcIdFnProto: + return destroy(reinterpret_cast<IrInstSrcFnProto *>(inst), name); + case IrInstSrcIdTestComptime: + return destroy(reinterpret_cast<IrInstSrcTestComptime *>(inst), name); + case IrInstSrcIdPtrCast: + return destroy(reinterpret_cast<IrInstSrcPtrCast *>(inst), name); + case IrInstSrcIdBitCast: + return destroy(reinterpret_cast<IrInstSrcBitCast *>(inst), name); + case IrInstSrcIdPtrToInt: + return destroy(reinterpret_cast<IrInstSrcPtrToInt *>(inst), name); + case IrInstSrcIdIntToPtr: + return destroy(reinterpret_cast<IrInstSrcIntToPtr *>(inst), name); + case IrInstSrcIdIntToEnum: + return destroy(reinterpret_cast<IrInstSrcIntToEnum *>(inst), name); + case IrInstSrcIdIntToErr: + return destroy(reinterpret_cast<IrInstSrcIntToErr *>(inst), name); + case IrInstSrcIdErrToInt: + return destroy(reinterpret_cast<IrInstSrcErrToInt *>(inst), name); + case IrInstSrcIdCheckSwitchProngs: + return destroy(reinterpret_cast<IrInstSrcCheckSwitchProngs *>(inst), name); + case IrInstSrcIdCheckStatementIsVoid: + return destroy(reinterpret_cast<IrInstSrcCheckStatementIsVoid *>(inst), name); + case IrInstSrcIdTypeName: + return destroy(reinterpret_cast<IrInstSrcTypeName *>(inst), name); + case IrInstSrcIdTagName: + return destroy(reinterpret_cast<IrInstSrcTagName *>(inst), name); + case IrInstSrcIdPtrType: + return destroy(reinterpret_cast<IrInstSrcPtrType *>(inst), name); + case IrInstSrcIdDeclRef: + return destroy(reinterpret_cast<IrInstSrcDeclRef *>(inst), name); + case IrInstSrcIdPanic: + return destroy(reinterpret_cast<IrInstSrcPanic *>(inst), name); + case IrInstSrcIdFieldParentPtr: + return destroy(reinterpret_cast<IrInstSrcFieldParentPtr *>(inst), name); + case IrInstSrcIdByteOffsetOf: + return destroy(reinterpret_cast<IrInstSrcByteOffsetOf *>(inst), name); + case IrInstSrcIdBitOffsetOf: + return destroy(reinterpret_cast<IrInstSrcBitOffsetOf *>(inst), name); + case IrInstSrcIdTypeInfo: + return destroy(reinterpret_cast<IrInstSrcTypeInfo *>(inst), name); + case IrInstSrcIdType: + return destroy(reinterpret_cast<IrInstSrcType *>(inst), name); + case IrInstSrcIdHasField: + return destroy(reinterpret_cast<IrInstSrcHasField *>(inst), name); + case IrInstSrcIdTypeId: + return destroy(reinterpret_cast<IrInstSrcTypeId *>(inst), name); + case IrInstSrcIdSetEvalBranchQuota: + return destroy(reinterpret_cast<IrInstSrcSetEvalBranchQuota *>(inst), name); + case IrInstSrcIdAlignCast: + return destroy(reinterpret_cast<IrInstSrcAlignCast *>(inst), name); + case IrInstSrcIdImplicitCast: + return destroy(reinterpret_cast<IrInstSrcImplicitCast *>(inst), name); + case IrInstSrcIdResolveResult: + return destroy(reinterpret_cast<IrInstSrcResolveResult *>(inst), name); + case IrInstSrcIdResetResult: + return destroy(reinterpret_cast<IrInstSrcResetResult *>(inst), name); + case IrInstSrcIdOpaqueType: + return destroy(reinterpret_cast<IrInstSrcOpaqueType *>(inst), name); + case IrInstSrcIdSetAlignStack: + return destroy(reinterpret_cast<IrInstSrcSetAlignStack *>(inst), name); + case IrInstSrcIdArgType: + return destroy(reinterpret_cast<IrInstSrcArgType *>(inst), name); + case IrInstSrcIdTagType: + return destroy(reinterpret_cast<IrInstSrcTagType *>(inst), name); + case IrInstSrcIdExport: + return destroy(reinterpret_cast<IrInstSrcExport *>(inst), name); + case IrInstSrcIdErrorReturnTrace: + return destroy(reinterpret_cast<IrInstSrcErrorReturnTrace *>(inst), name); + case IrInstSrcIdErrorUnion: + return destroy(reinterpret_cast<IrInstSrcErrorUnion *>(inst), name); + case IrInstSrcIdAtomicRmw: + return destroy(reinterpret_cast<IrInstSrcAtomicRmw *>(inst), name); + case IrInstSrcIdSaveErrRetAddr: + return destroy(reinterpret_cast<IrInstSrcSaveErrRetAddr *>(inst), name); + case IrInstSrcIdAddImplicitReturnType: + return destroy(reinterpret_cast<IrInstSrcAddImplicitReturnType *>(inst), name); + case IrInstSrcIdFloatOp: + return destroy(reinterpret_cast<IrInstSrcFloatOp *>(inst), name); + case IrInstSrcIdMulAdd: + return destroy(reinterpret_cast<IrInstSrcMulAdd *>(inst), name); + case IrInstSrcIdAtomicLoad: + return destroy(reinterpret_cast<IrInstSrcAtomicLoad *>(inst), name); + case IrInstSrcIdAtomicStore: + return destroy(reinterpret_cast<IrInstSrcAtomicStore *>(inst), name); + case IrInstSrcIdEnumToInt: + return destroy(reinterpret_cast<IrInstSrcEnumToInt *>(inst), name); + case IrInstSrcIdCheckRuntimeScope: + return destroy(reinterpret_cast<IrInstSrcCheckRuntimeScope *>(inst), name); + case IrInstSrcIdHasDecl: + return destroy(reinterpret_cast<IrInstSrcHasDecl *>(inst), name); + case IrInstSrcIdUndeclaredIdent: + return destroy(reinterpret_cast<IrInstSrcUndeclaredIdent *>(inst), name); + case IrInstSrcIdAlloca: + return destroy(reinterpret_cast<IrInstSrcAlloca *>(inst), name); + case IrInstSrcIdEndExpr: + return destroy(reinterpret_cast<IrInstSrcEndExpr *>(inst), name); + case IrInstSrcIdUnionInitNamedField: + return destroy(reinterpret_cast<IrInstSrcUnionInitNamedField *>(inst), name); + case IrInstSrcIdSuspendBegin: + return destroy(reinterpret_cast<IrInstSrcSuspendBegin *>(inst), name); + case IrInstSrcIdSuspendFinish: + return destroy(reinterpret_cast<IrInstSrcSuspendFinish *>(inst), name); + case IrInstSrcIdResume: + return destroy(reinterpret_cast<IrInstSrcResume *>(inst), name); + case IrInstSrcIdAwait: + return destroy(reinterpret_cast<IrInstSrcAwait *>(inst), name); + case IrInstSrcIdSpillBegin: + return destroy(reinterpret_cast<IrInstSrcSpillBegin *>(inst), name); + case IrInstSrcIdSpillEnd: + return destroy(reinterpret_cast<IrInstSrcSpillEnd *>(inst), name); + case IrInstSrcIdCallArgs: + return destroy(reinterpret_cast<IrInstSrcCallArgs *>(inst), name); + } + zig_unreachable(); +} + +void destroy_instruction_gen(IrInstGen *inst) { +#ifdef ZIG_ENABLE_MEM_PROFILE + const char *name = ir_inst_gen_type_str(inst->id); +#else + const char *name = nullptr; +#endif + switch (inst->id) { + case IrInstGenIdInvalid: + zig_unreachable(); + case IrInstGenIdReturn: + return destroy(reinterpret_cast<IrInstGenReturn *>(inst), name); + case IrInstGenIdConst: + return destroy(reinterpret_cast<IrInstGenConst *>(inst), name); + case IrInstGenIdBinOp: + return destroy(reinterpret_cast<IrInstGenBinOp *>(inst), name); + case IrInstGenIdCast: + return destroy(reinterpret_cast<IrInstGenCast *>(inst), name); + case IrInstGenIdCall: + return destroy(reinterpret_cast<IrInstGenCall *>(inst), name); + case IrInstGenIdCondBr: + return destroy(reinterpret_cast<IrInstGenCondBr *>(inst), name); + case IrInstGenIdBr: + return destroy(reinterpret_cast<IrInstGenBr *>(inst), name); + case IrInstGenIdPhi: + return destroy(reinterpret_cast<IrInstGenPhi *>(inst), name); + case IrInstGenIdUnreachable: + return destroy(reinterpret_cast<IrInstGenUnreachable *>(inst), name); + case IrInstGenIdElemPtr: + return destroy(reinterpret_cast<IrInstGenElemPtr *>(inst), name); + case IrInstGenIdVarPtr: + return destroy(reinterpret_cast<IrInstGenVarPtr *>(inst), name); + case IrInstGenIdReturnPtr: + return destroy(reinterpret_cast<IrInstGenReturnPtr *>(inst), name); + case IrInstGenIdLoadPtr: + return destroy(reinterpret_cast<IrInstGenLoadPtr *>(inst), name); + case IrInstGenIdStorePtr: + return destroy(reinterpret_cast<IrInstGenStorePtr *>(inst), name); + case IrInstGenIdVectorStoreElem: + return destroy(reinterpret_cast<IrInstGenVectorStoreElem *>(inst), name); + case IrInstGenIdStructFieldPtr: + return destroy(reinterpret_cast<IrInstGenStructFieldPtr *>(inst), name); + case IrInstGenIdUnionFieldPtr: + return destroy(reinterpret_cast<IrInstGenUnionFieldPtr *>(inst), name); + case IrInstGenIdAsm: + return destroy(reinterpret_cast<IrInstGenAsm *>(inst), name); + case IrInstGenIdTestNonNull: + return destroy(reinterpret_cast<IrInstGenTestNonNull *>(inst), name); + case IrInstGenIdOptionalUnwrapPtr: + return destroy(reinterpret_cast<IrInstGenOptionalUnwrapPtr *>(inst), name); + case IrInstGenIdPopCount: + return destroy(reinterpret_cast<IrInstGenPopCount *>(inst), name); + case IrInstGenIdClz: + return destroy(reinterpret_cast<IrInstGenClz *>(inst), name); + case IrInstGenIdCtz: + return destroy(reinterpret_cast<IrInstGenCtz *>(inst), name); + case IrInstGenIdBswap: + return destroy(reinterpret_cast<IrInstGenBswap *>(inst), name); + case IrInstGenIdBitReverse: + return destroy(reinterpret_cast<IrInstGenBitReverse *>(inst), name); + case IrInstGenIdSwitchBr: + return destroy(reinterpret_cast<IrInstGenSwitchBr *>(inst), name); + case IrInstGenIdUnionTag: + return destroy(reinterpret_cast<IrInstGenUnionTag *>(inst), name); + case IrInstGenIdRef: + return destroy(reinterpret_cast<IrInstGenRef *>(inst), name); + case IrInstGenIdErrName: + return destroy(reinterpret_cast<IrInstGenErrName *>(inst), name); + case IrInstGenIdCmpxchg: + return destroy(reinterpret_cast<IrInstGenCmpxchg *>(inst), name); + case IrInstGenIdFence: + return destroy(reinterpret_cast<IrInstGenFence *>(inst), name); + case IrInstGenIdTruncate: + return destroy(reinterpret_cast<IrInstGenTruncate *>(inst), name); + case IrInstGenIdShuffleVector: + return destroy(reinterpret_cast<IrInstGenShuffleVector *>(inst), name); + case IrInstGenIdSplat: + return destroy(reinterpret_cast<IrInstGenSplat *>(inst), name); + case IrInstGenIdBoolNot: + return destroy(reinterpret_cast<IrInstGenBoolNot *>(inst), name); + case IrInstGenIdMemset: + return destroy(reinterpret_cast<IrInstGenMemset *>(inst), name); + case IrInstGenIdMemcpy: + return destroy(reinterpret_cast<IrInstGenMemcpy *>(inst), name); + case IrInstGenIdSlice: + return destroy(reinterpret_cast<IrInstGenSlice *>(inst), name); + case IrInstGenIdBreakpoint: + return destroy(reinterpret_cast<IrInstGenBreakpoint *>(inst), name); + case IrInstGenIdReturnAddress: + return destroy(reinterpret_cast<IrInstGenReturnAddress *>(inst), name); + case IrInstGenIdFrameAddress: + return destroy(reinterpret_cast<IrInstGenFrameAddress *>(inst), name); + case IrInstGenIdFrameHandle: + return destroy(reinterpret_cast<IrInstGenFrameHandle *>(inst), name); + case IrInstGenIdFrameSize: + return destroy(reinterpret_cast<IrInstGenFrameSize *>(inst), name); + case IrInstGenIdOverflowOp: + return destroy(reinterpret_cast<IrInstGenOverflowOp *>(inst), name); + case IrInstGenIdTestErr: + return destroy(reinterpret_cast<IrInstGenTestErr *>(inst), name); + case IrInstGenIdUnwrapErrCode: + return destroy(reinterpret_cast<IrInstGenUnwrapErrCode *>(inst), name); + case IrInstGenIdUnwrapErrPayload: + return destroy(reinterpret_cast<IrInstGenUnwrapErrPayload *>(inst), name); + case IrInstGenIdOptionalWrap: + return destroy(reinterpret_cast<IrInstGenOptionalWrap *>(inst), name); + case IrInstGenIdErrWrapCode: + return destroy(reinterpret_cast<IrInstGenErrWrapCode *>(inst), name); + case IrInstGenIdErrWrapPayload: + return destroy(reinterpret_cast<IrInstGenErrWrapPayload *>(inst), name); + case IrInstGenIdPtrCast: + return destroy(reinterpret_cast<IrInstGenPtrCast *>(inst), name); + case IrInstGenIdBitCast: + return destroy(reinterpret_cast<IrInstGenBitCast *>(inst), name); + case IrInstGenIdWidenOrShorten: + return destroy(reinterpret_cast<IrInstGenWidenOrShorten *>(inst), name); + case IrInstGenIdPtrToInt: + return destroy(reinterpret_cast<IrInstGenPtrToInt *>(inst), name); + case IrInstGenIdIntToPtr: + return destroy(reinterpret_cast<IrInstGenIntToPtr *>(inst), name); + case IrInstGenIdIntToEnum: + return destroy(reinterpret_cast<IrInstGenIntToEnum *>(inst), name); + case IrInstGenIdIntToErr: + return destroy(reinterpret_cast<IrInstGenIntToErr *>(inst), name); + case IrInstGenIdErrToInt: + return destroy(reinterpret_cast<IrInstGenErrToInt *>(inst), name); + case IrInstGenIdTagName: + return destroy(reinterpret_cast<IrInstGenTagName *>(inst), name); + case IrInstGenIdPanic: + return destroy(reinterpret_cast<IrInstGenPanic *>(inst), name); + case IrInstGenIdFieldParentPtr: + return destroy(reinterpret_cast<IrInstGenFieldParentPtr *>(inst), name); + case IrInstGenIdAlignCast: + return destroy(reinterpret_cast<IrInstGenAlignCast *>(inst), name); + case IrInstGenIdErrorReturnTrace: + return destroy(reinterpret_cast<IrInstGenErrorReturnTrace *>(inst), name); + case IrInstGenIdAtomicRmw: + return destroy(reinterpret_cast<IrInstGenAtomicRmw *>(inst), name); + case IrInstGenIdSaveErrRetAddr: + return destroy(reinterpret_cast<IrInstGenSaveErrRetAddr *>(inst), name); + case IrInstGenIdFloatOp: + return destroy(reinterpret_cast<IrInstGenFloatOp *>(inst), name); + case IrInstGenIdMulAdd: + return destroy(reinterpret_cast<IrInstGenMulAdd *>(inst), name); + case IrInstGenIdAtomicLoad: + return destroy(reinterpret_cast<IrInstGenAtomicLoad *>(inst), name); + case IrInstGenIdAtomicStore: + return destroy(reinterpret_cast<IrInstGenAtomicStore *>(inst), name); + case IrInstGenIdDeclVar: + return destroy(reinterpret_cast<IrInstGenDeclVar *>(inst), name); + case IrInstGenIdArrayToVector: + return destroy(reinterpret_cast<IrInstGenArrayToVector *>(inst), name); + case IrInstGenIdVectorToArray: + return destroy(reinterpret_cast<IrInstGenVectorToArray *>(inst), name); + case IrInstGenIdPtrOfArrayToSlice: + return destroy(reinterpret_cast<IrInstGenPtrOfArrayToSlice *>(inst), name); + case IrInstGenIdAssertZero: + return destroy(reinterpret_cast<IrInstGenAssertZero *>(inst), name); + case IrInstGenIdAssertNonNull: + return destroy(reinterpret_cast<IrInstGenAssertNonNull *>(inst), name); + case IrInstGenIdResizeSlice: + return destroy(reinterpret_cast<IrInstGenResizeSlice *>(inst), name); + case IrInstGenIdAlloca: + return destroy(reinterpret_cast<IrInstGenAlloca *>(inst), name); + case IrInstGenIdSuspendBegin: + return destroy(reinterpret_cast<IrInstGenSuspendBegin *>(inst), name); + case IrInstGenIdSuspendFinish: + return destroy(reinterpret_cast<IrInstGenSuspendFinish *>(inst), name); + case IrInstGenIdResume: + return destroy(reinterpret_cast<IrInstGenResume *>(inst), name); + case IrInstGenIdAwait: + return destroy(reinterpret_cast<IrInstGenAwait *>(inst), name); + case IrInstGenIdSpillBegin: + return destroy(reinterpret_cast<IrInstGenSpillBegin *>(inst), name); + case IrInstGenIdSpillEnd: + return destroy(reinterpret_cast<IrInstGenSpillEnd *>(inst), name); + case IrInstGenIdVectorExtractElem: + return destroy(reinterpret_cast<IrInstGenVectorExtractElem *>(inst), name); + case IrInstGenIdBinaryNot: + return destroy(reinterpret_cast<IrInstGenBinaryNot *>(inst), name); + case IrInstGenIdNegation: + return destroy(reinterpret_cast<IrInstGenNegation *>(inst), name); + case IrInstGenIdNegationWrapping: + return destroy(reinterpret_cast<IrInstGenNegationWrapping *>(inst), name); } zig_unreachable(); } @@ -627,20 +755,19 @@ static void ira_deref(IrAnalyze *ira) { assert(ira->ref_count != 0); for (size_t bb_i = 0; bb_i < ira->old_irb.exec->basic_block_list.length; bb_i += 1) { - IrBasicBlock *pass1_bb = ira->old_irb.exec->basic_block_list.items[bb_i]; + IrBasicBlockSrc *pass1_bb = ira->old_irb.exec->basic_block_list.items[bb_i]; for (size_t inst_i = 0; inst_i < pass1_bb->instruction_list.length; inst_i += 1) { - IrInstruction *pass1_inst = pass1_bb->instruction_list.items[inst_i]; - destroy_instruction(pass1_inst); + IrInstSrc *pass1_inst = pass1_bb->instruction_list.items[inst_i]; + destroy_instruction_src(pass1_inst); } - destroy(pass1_bb, "IrBasicBlock"); + destroy(pass1_bb, "IrBasicBlockSrc"); } ira->old_irb.exec->basic_block_list.deinit(); ira->old_irb.exec->tld_list.deinit(); // cannot destroy here because of var->owner_exec - //destroy(ira->old_irb.exec, "IrExecutablePass1"); + //destroy(ira->old_irb.exec, "IrExecutableSrc"); ira->src_implicit_return_type_list.deinit(); ira->resume_stack.deinit(); - ira->exec_context.mem_slot_list.deinit(); destroy(ira, "IrAnalyze"); } @@ -754,7 +881,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte case ZigTypeIdComptimeFloat: case ZigTypeIdComptimeInt: case ZigTypeIdEnumLiteral: - case ZigTypeIdPointer: case ZigTypeIdUndefined: case ZigTypeIdNull: case ZigTypeIdBoundFn: @@ -763,6 +889,8 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte case ZigTypeIdAnyFrame: case ZigTypeIdFn: return true; + case ZigTypeIdPointer: + return expected->data.pointer.inferred_struct_field == actual->data.pointer.inferred_struct_field; case ZigTypeIdFloat: return expected->data.floating.bit_count == actual->data.floating.bit_count; case ZigTypeIdInt: @@ -785,7 +913,7 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte zig_unreachable(); } -static bool ir_should_inline(IrExecutable *exec, Scope *scope) { +static bool ir_should_inline(IrExecutableSrc *exec, Scope *scope) { if (exec->is_inline) return true; @@ -801,29 +929,35 @@ static bool ir_should_inline(IrExecutable *exec, Scope *scope) { return false; } -static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) { +static void ir_instruction_append(IrBasicBlockSrc *basic_block, IrInstSrc *instruction) { assert(basic_block); assert(instruction); basic_block->instruction_list.append(instruction); } -static size_t exec_next_debug_id(IrExecutable *exec) { +static void ir_inst_gen_append(IrBasicBlockGen *basic_block, IrInstGen *instruction) { + assert(basic_block); + assert(instruction); + basic_block->instruction_list.append(instruction); +} + +static size_t exec_next_debug_id(IrExecutableSrc *exec) { size_t result = exec->next_debug_id; exec->next_debug_id += 1; return result; } -static size_t exec_next_mem_slot(IrExecutable *exec) { - size_t result = exec->mem_slot_count; - exec->mem_slot_count += 1; +static size_t exec_next_debug_id_gen(IrExecutableGen *exec) { + size_t result = exec->next_debug_id; + exec->next_debug_id += 1; return result; } -static ZigFn *exec_fn_entry(IrExecutable *exec) { +static ZigFn *exec_fn_entry(IrExecutableSrc *exec) { return exec->fn_entry; } -static Buf *exec_c_import_buf(IrExecutable *exec) { +static Buf *exec_c_import_buf(IrExecutableSrc *exec) { return exec->c_import_buf; } @@ -831,1002 +965,1343 @@ static bool value_is_comptime(ZigValue *const_val) { return const_val->special != ConstValSpecialRuntime; } -static bool instr_is_comptime(IrInstruction *instruction) { +static bool instr_is_comptime(IrInstGen *instruction) { return value_is_comptime(instruction->value); } -static bool instr_is_unreachable(IrInstruction *instruction) { - return instruction->value->type && instruction->value->type->id == ZigTypeIdUnreachable; +static bool instr_is_unreachable(IrInstSrc *instruction) { + return instruction->is_noreturn; } -static void ir_link_new_bb(IrBasicBlock *new_bb, IrBasicBlock *old_bb) { - new_bb->other = old_bb; - old_bb->other = new_bb; +static void ir_link_new_bb(IrBasicBlockGen *new_bb, IrBasicBlockSrc *old_bb) { + new_bb->parent = old_bb; + old_bb->child = new_bb; } -static void ir_ref_bb(IrBasicBlock *bb) { +static void ir_ref_bb(IrBasicBlockSrc *bb) { bb->ref_count += 1; } -static void ir_ref_instruction(IrInstruction *instruction, IrBasicBlock *cur_bb) { - assert(instruction->id != IrInstructionIdInvalid); - instruction->ref_count += 1; - if (instruction->owner_bb != cur_bb && !instr_is_comptime(instruction)) +static void ir_ref_bb_gen(IrBasicBlockGen *bb) { + bb->ref_count += 1; +} + +static void ir_ref_instruction(IrInstSrc *instruction, IrBasicBlockSrc *cur_bb) { + assert(instruction->id != IrInstSrcIdInvalid); + instruction->base.ref_count += 1; + if (instruction->owner_bb != cur_bb && !instr_is_unreachable(instruction) + && instruction->id != IrInstSrcIdConst) + { ir_ref_bb(instruction->owner_bb); + } +} + +static void ir_ref_inst_gen(IrInstGen *instruction, IrBasicBlockGen *cur_bb) { + assert(instruction->id != IrInstGenIdInvalid); + instruction->base.ref_count += 1; + if (instruction->owner_bb != cur_bb && !instr_is_comptime(instruction)) + ir_ref_bb_gen(instruction->owner_bb); } static void ir_ref_var(ZigVar *var) { var->ref_count += 1; } +static void create_result_ptr(CodeGen *codegen, ZigType *expected_type, + ZigValue **out_result, ZigValue **out_result_ptr) +{ + ZigValue *result = create_const_vals(1); + ZigValue *result_ptr = create_const_vals(1); + result->special = ConstValSpecialUndef; + result->type = expected_type; + result_ptr->special = ConstValSpecialStatic; + result_ptr->type = get_pointer_to_type(codegen, result->type, false); + result_ptr->data.x_ptr.mut = ConstPtrMutComptimeVar; + result_ptr->data.x_ptr.special = ConstPtrSpecialRef; + result_ptr->data.x_ptr.data.ref.pointee = result; + + *out_result = result; + *out_result_ptr = result_ptr; +} + ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) { - ZigValue *result = ir_eval_const_value(ira->codegen, scope, node, ira->codegen->builtin_types.entry_type, - ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr, - node, nullptr, ira->new_irb.exec, nullptr, UndefBad); + Error err; + ZigValue *result; + ZigValue *result_ptr; + create_result_ptr(ira->codegen, ira->codegen->builtin_types.entry_type, &result, &result_ptr); + + if ((err = ir_eval_const_value(ira->codegen, scope, node, result_ptr, + ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, + nullptr, nullptr, node, nullptr, ira->new_irb.exec, nullptr, UndefBad))) + { + return ira->codegen->builtin_types.entry_invalid; + } if (type_is_invalid(result->type)) return ira->codegen->builtin_types.entry_invalid; assert(result->special != ConstValSpecialRuntime); - return result->data.x_type; + ZigType *res_type = result->data.x_type; + + destroy(result_ptr, "ZigValue"); + destroy(result, "ZigValue"); + + return res_type; } -static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const char *name_hint) { - IrBasicBlock *result = allocate<IrBasicBlock>(1, "IrBasicBlock"); +static IrBasicBlockSrc *ir_create_basic_block(IrBuilderSrc *irb, Scope *scope, const char *name_hint) { + IrBasicBlockSrc *result = allocate<IrBasicBlockSrc>(1, "IrBasicBlockSrc"); result->scope = scope; result->name_hint = name_hint; result->debug_id = exec_next_debug_id(irb->exec); - result->index = SIZE_MAX; // set later + result->index = UINT32_MAX; // set later + return result; +} + +static IrBasicBlockGen *ir_create_basic_block_gen(IrAnalyze *ira, Scope *scope, const char *name_hint) { + IrBasicBlockGen *result = allocate<IrBasicBlockGen>(1, "IrBasicBlockGen"); + result->scope = scope; + result->name_hint = name_hint; + result->debug_id = exec_next_debug_id_gen(ira->new_irb.exec); + result->index = UINT32_MAX; // set later return result; } -static IrBasicBlock *ir_build_bb_from(IrBuilder *irb, IrBasicBlock *other_bb) { - IrBasicBlock *new_bb = ir_create_basic_block(irb, other_bb->scope, other_bb->name_hint); +static IrBasicBlockGen *ir_build_bb_from(IrAnalyze *ira, IrBasicBlockSrc *other_bb) { + IrBasicBlockGen *new_bb = ir_create_basic_block_gen(ira, other_bb->scope, other_bb->name_hint); ir_link_new_bb(new_bb, other_bb); return new_bb; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVarSrc *) { - return IrInstructionIdDeclVarSrc; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclVar *) { + return IrInstSrcIdDeclVar; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcBr *) { + return IrInstSrcIdBr; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCondBr *) { + return IrInstSrcIdCondBr; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchBr *) { + return IrInstSrcIdSwitchBr; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchVar *) { + return IrInstSrcIdSwitchVar; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchElseVar *) { + return IrInstSrcIdSwitchElseVar; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchTarget *) { + return IrInstSrcIdSwitchTarget; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcPhi *) { + return IrInstSrcIdPhi; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnOp *) { + return IrInstSrcIdUnOp; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcBinOp *) { + return IrInstSrcIdBinOp; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcMergeErrSets *) { + return IrInstSrcIdMergeErrSets; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcLoadPtr *) { + return IrInstSrcIdLoadPtr; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcStorePtr *) { + return IrInstSrcIdStorePtr; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldPtr *) { + return IrInstSrcIdFieldPtr; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcElemPtr *) { + return IrInstSrcIdElemPtr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVarGen *) { - return IrInstructionIdDeclVarGen; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcVarPtr *) { + return IrInstSrcIdVarPtr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCondBr *) { - return IrInstructionIdCondBr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCall *) { + return IrInstSrcIdCall; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionBr *) { - return IrInstructionIdBr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallArgs *) { + return IrInstSrcIdCallArgs; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchBr *) { - return IrInstructionIdSwitchBr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallExtra *) { + return IrInstSrcIdCallExtra; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchVar *) { - return IrInstructionIdSwitchVar; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcConst *) { + return IrInstSrcIdConst; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchElseVar *) { - return IrInstructionIdSwitchElseVar; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturn *) { + return IrInstSrcIdReturn; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchTarget *) { - return IrInstructionIdSwitchTarget; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitList *) { + return IrInstSrcIdContainerInitList; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionPhi *) { - return IrInstructionIdPhi; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitFields *) { + return IrInstSrcIdContainerInitFields; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionUnOp *) { - return IrInstructionIdUnOp; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnreachable *) { + return IrInstSrcIdUnreachable; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionBinOp *) { - return IrInstructionIdBinOp; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeOf *) { + return IrInstSrcIdTypeOf; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionMergeErrSets *) { - return IrInstructionIdMergeErrSets; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetCold *) { + return IrInstSrcIdSetCold; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionExport *) { - return IrInstructionIdExport; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetRuntimeSafety *) { + return IrInstSrcIdSetRuntimeSafety; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) { - return IrInstructionIdLoadPtr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetFloatMode *) { + return IrInstSrcIdSetFloatMode; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtrGen *) { - return IrInstructionIdLoadPtrGen; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcArrayType *) { + return IrInstSrcIdArrayType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionStorePtr *) { - return IrInstructionIdStorePtr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcAnyFrameType *) { + return IrInstSrcIdAnyFrameType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorStoreElem *) { - return IrInstructionIdVectorStoreElem; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSliceType *) { + return IrInstSrcIdSliceType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldPtr *) { - return IrInstructionIdFieldPtr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcAsm *) { + return IrInstSrcIdAsm; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr *) { - return IrInstructionIdStructFieldPtr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSizeOf *) { + return IrInstSrcIdSizeOf; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionFieldPtr *) { - return IrInstructionIdUnionFieldPtr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestNonNull *) { + return IrInstSrcIdTestNonNull; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) { - return IrInstructionIdElemPtr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcOptionalUnwrapPtr *) { + return IrInstSrcIdOptionalUnwrapPtr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) { - return IrInstructionIdVarPtr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcClz *) { + return IrInstSrcIdClz; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnPtr *) { - return IrInstructionIdReturnPtr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCtz *) { + return IrInstSrcIdCtz; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCallSrc *) { - return IrInstructionIdCallSrc; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcPopCount *) { + return IrInstSrcIdPopCount; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCallSrcArgs *) { - return IrInstructionIdCallSrcArgs; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcBswap *) { + return IrInstSrcIdBswap; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCallExtra *) { - return IrInstructionIdCallExtra; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitReverse *) { + return IrInstSrcIdBitReverse; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCallGen *) { - return IrInstructionIdCallGen; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcImport *) { + return IrInstSrcIdImport; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) { - return IrInstructionIdConst; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCImport *) { + return IrInstSrcIdCImport; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionReturn *) { - return IrInstructionIdReturn; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCInclude *) { + return IrInstSrcIdCInclude; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCast *) { - return IrInstructionIdCast; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCDefine *) { + return IrInstSrcIdCDefine; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionResizeSlice *) { - return IrInstructionIdResizeSlice; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCUndef *) { + return IrInstSrcIdCUndef; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitList *) { - return IrInstructionIdContainerInitList; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcRef *) { + return IrInstSrcIdRef; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitFields *) { - return IrInstructionIdContainerInitFields; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileErr *) { + return IrInstSrcIdCompileErr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionUnreachable *) { - return IrInstructionIdUnreachable; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileLog *) { + return IrInstSrcIdCompileLog; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeOf *) { - return IrInstructionIdTypeOf; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrName *) { + return IrInstSrcIdErrName; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) { - return IrInstructionIdSetCold; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcEmbedFile *) { + return IrInstSrcIdEmbedFile; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSetRuntimeSafety *) { - return IrInstructionIdSetRuntimeSafety; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCmpxchg *) { + return IrInstSrcIdCmpxchg; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFloatMode *) { - return IrInstructionIdSetFloatMode; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcFence *) { + return IrInstSrcIdFence; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) { - return IrInstructionIdArrayType; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcTruncate *) { + return IrInstSrcIdTruncate; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAnyFrameType *) { - return IrInstructionIdAnyFrameType; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntCast *) { + return IrInstSrcIdIntCast; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) { - return IrInstructionIdSliceType; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatCast *) { + return IrInstSrcIdFloatCast; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAsmSrc *) { - return IrInstructionIdAsmSrc; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToFloat *) { + return IrInstSrcIdIntToFloat; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAsmGen *) { - return IrInstructionIdAsmGen; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatToInt *) { + return IrInstSrcIdFloatToInt; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSizeOf *) { - return IrInstructionIdSizeOf; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolToInt *) { + return IrInstSrcIdBoolToInt; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionTestNonNull *) { - return IrInstructionIdTestNonNull; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntType *) { + return IrInstSrcIdIntType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionOptionalUnwrapPtr *) { - return IrInstructionIdOptionalUnwrapPtr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcVectorType *) { + return IrInstSrcIdVectorType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionClz *) { - return IrInstructionIdClz; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcShuffleVector *) { + return IrInstSrcIdShuffleVector; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCtz *) { - return IrInstructionIdCtz; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSplat *) { + return IrInstSrcIdSplat; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) { - return IrInstructionIdPopCount; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolNot *) { + return IrInstSrcIdBoolNot; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) { - return IrInstructionIdBswap; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemset *) { + return IrInstSrcIdMemset; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) { - return IrInstructionIdBitReverse; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemcpy *) { + return IrInstSrcIdMemcpy; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) { - return IrInstructionIdUnionTag; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSlice *) { + return IrInstSrcIdSlice; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) { - return IrInstructionIdImport; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemberCount *) { + return IrInstSrcIdMemberCount; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCImport *) { - return IrInstructionIdCImport; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemberType *) { + return IrInstSrcIdMemberType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCInclude *) { - return IrInstructionIdCInclude; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemberName *) { + return IrInstSrcIdMemberName; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCDefine *) { - return IrInstructionIdCDefine; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcBreakpoint *) { + return IrInstSrcIdBreakpoint; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCUndef *) { - return IrInstructionIdCUndef; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturnAddress *) { + return IrInstSrcIdReturnAddress; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) { - return IrInstructionIdRef; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameAddress *) { + return IrInstSrcIdFrameAddress; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionRefGen *) { - return IrInstructionIdRefGen; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameHandle *) { + return IrInstSrcIdFrameHandle; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) { - return IrInstructionIdCompileErr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameType *) { + return IrInstSrcIdFrameType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileLog *) { - return IrInstructionIdCompileLog; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameSize *) { + return IrInstSrcIdFrameSize; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionErrName *) { - return IrInstructionIdErrName; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignOf *) { + return IrInstSrcIdAlignOf; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionEmbedFile *) { - return IrInstructionIdEmbedFile; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcOverflowOp *) { + return IrInstSrcIdOverflowOp; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCmpxchgSrc *) { - return IrInstructionIdCmpxchgSrc; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestErr *) { + return IrInstSrcIdTestErr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCmpxchgGen *) { - return IrInstructionIdCmpxchgGen; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcMulAdd *) { + return IrInstSrcIdMulAdd; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionFence *) { - return IrInstructionIdFence; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatOp *) { + return IrInstSrcIdFloatOp; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionTruncate *) { - return IrInstructionIdTruncate; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrCode *) { + return IrInstSrcIdUnwrapErrCode; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionIntCast *) { - return IrInstructionIdIntCast; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrPayload *) { + return IrInstSrcIdUnwrapErrPayload; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatCast *) { - return IrInstructionIdFloatCast; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcFnProto *) { + return IrInstSrcIdFnProto; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionErrSetCast *) { - return IrInstructionIdErrSetCast; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestComptime *) { + return IrInstSrcIdTestComptime; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionToBytes *) { - return IrInstructionIdToBytes; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrCast *) { + return IrInstSrcIdPtrCast; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionFromBytes *) { - return IrInstructionIdFromBytes; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitCast *) { + return IrInstSrcIdBitCast; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) { - return IrInstructionIdIntToFloat; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToPtr *) { + return IrInstSrcIdIntToPtr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatToInt *) { - return IrInstructionIdFloatToInt; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrToInt *) { + return IrInstSrcIdPtrToInt; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolToInt *) { - return IrInstructionIdBoolToInt; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToEnum *) { + return IrInstSrcIdIntToEnum; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) { - return IrInstructionIdIntType; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcEnumToInt *) { + return IrInstSrcIdEnumToInt; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorType *) { - return IrInstructionIdVectorType; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToErr *) { + return IrInstSrcIdIntToErr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionShuffleVector *) { - return IrInstructionIdShuffleVector; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrToInt *) { + return IrInstSrcIdErrToInt; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSplatSrc *) { - return IrInstructionIdSplatSrc; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckSwitchProngs *) { + return IrInstSrcIdCheckSwitchProngs; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSplatGen *) { - return IrInstructionIdSplatGen; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckStatementIsVoid *) { + return IrInstSrcIdCheckStatementIsVoid; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) { - return IrInstructionIdBoolNot; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeName *) { + return IrInstSrcIdTypeName; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionMemset *) { - return IrInstructionIdMemset; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclRef *) { + return IrInstSrcIdDeclRef; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) { - return IrInstructionIdMemcpy; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcPanic *) { + return IrInstSrcIdPanic; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceSrc *) { - return IrInstructionIdSliceSrc; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcTagName *) { + return IrInstSrcIdTagName; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceGen *) { - return IrInstructionIdSliceGen; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcTagType *) { + return IrInstSrcIdTagType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) { - return IrInstructionIdMemberCount; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldParentPtr *) { + return IrInstSrcIdFieldParentPtr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberType *) { - return IrInstructionIdMemberType; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcByteOffsetOf *) { + return IrInstSrcIdByteOffsetOf; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberName *) { - return IrInstructionIdMemberName; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitOffsetOf *) { + return IrInstSrcIdBitOffsetOf; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionBreakpoint *) { - return IrInstructionIdBreakpoint; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeInfo *) { + return IrInstSrcIdTypeInfo; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnAddress *) { - return IrInstructionIdReturnAddress; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcType *) { + return IrInstSrcIdType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameAddress *) { - return IrInstructionIdFrameAddress; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasField *) { + return IrInstSrcIdHasField; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameHandle *) { - return IrInstructionIdFrameHandle; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeId *) { + return IrInstSrcIdTypeId; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameType *) { - return IrInstructionIdFrameType; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetEvalBranchQuota *) { + return IrInstSrcIdSetEvalBranchQuota; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameSizeSrc *) { - return IrInstructionIdFrameSizeSrc; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrType *) { + return IrInstSrcIdPtrType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameSizeGen *) { - return IrInstructionIdFrameSizeGen; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignCast *) { + return IrInstSrcIdAlignCast; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignOf *) { - return IrInstructionIdAlignOf; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcImplicitCast *) { + return IrInstSrcIdImplicitCast; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) { - return IrInstructionIdOverflowOp; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcResolveResult *) { + return IrInstSrcIdResolveResult; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrSrc *) { - return IrInstructionIdTestErrSrc; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcResetResult *) { + return IrInstSrcIdResetResult; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrGen *) { - return IrInstructionIdTestErrGen; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcOpaqueType *) { + return IrInstSrcIdOpaqueType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionMulAdd *) { - return IrInstructionIdMulAdd; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetAlignStack *) { + return IrInstSrcIdSetAlignStack; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrCode *) { - return IrInstructionIdUnwrapErrCode; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcArgType *) { + return IrInstSrcIdArgType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrPayload *) { - return IrInstructionIdUnwrapErrPayload; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcExport *) { + return IrInstSrcIdExport; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionOptionalWrap *) { - return IrInstructionIdOptionalWrap; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorReturnTrace *) { + return IrInstSrcIdErrorReturnTrace; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionErrWrapPayload *) { - return IrInstructionIdErrWrapPayload; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorUnion *) { + return IrInstSrcIdErrorUnion; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionErrWrapCode *) { - return IrInstructionIdErrWrapCode; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicRmw *) { + return IrInstSrcIdAtomicRmw; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionFnProto *) { - return IrInstructionIdFnProto; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicLoad *) { + return IrInstSrcIdAtomicLoad; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionTestComptime *) { - return IrInstructionIdTestComptime; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicStore *) { + return IrInstSrcIdAtomicStore; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastSrc *) { - return IrInstructionIdPtrCastSrc; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSaveErrRetAddr *) { + return IrInstSrcIdSaveErrRetAddr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastGen *) { - return IrInstructionIdPtrCastGen; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcAddImplicitReturnType *) { + return IrInstSrcIdAddImplicitReturnType; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastSrc *) { - return IrInstructionIdBitCastSrc; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrSetCast *) { + return IrInstSrcIdErrSetCast; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) { - return IrInstructionIdBitCastGen; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcToBytes *) { + return IrInstSrcIdToBytes; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) { - return IrInstructionIdWidenOrShorten; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcFromBytes *) { + return IrInstSrcIdFromBytes; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrToInt *) { - return IrInstructionIdPtrToInt; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckRuntimeScope *) { + return IrInstSrcIdCheckRuntimeScope; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToPtr *) { - return IrInstructionIdIntToPtr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasDecl *) { + return IrInstSrcIdHasDecl; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToEnum *) { - return IrInstructionIdIntToEnum; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcUndeclaredIdent *) { + return IrInstSrcIdUndeclaredIdent; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumToInt *) { - return IrInstructionIdEnumToInt; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlloca *) { + return IrInstSrcIdAlloca; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToErr *) { - return IrInstructionIdIntToErr; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcEndExpr *) { + return IrInstSrcIdEndExpr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionErrToInt *) { - return IrInstructionIdErrToInt; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnionInitNamedField *) { + return IrInstSrcIdUnionInitNamedField; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckSwitchProngs *) { - return IrInstructionIdCheckSwitchProngs; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSuspendBegin *) { + return IrInstSrcIdSuspendBegin; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckStatementIsVoid *) { - return IrInstructionIdCheckStatementIsVoid; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSuspendFinish *) { + return IrInstSrcIdSuspendFinish; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeName *) { - return IrInstructionIdTypeName; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcAwait *) { + return IrInstSrcIdAwait; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) { - return IrInstructionIdDeclRef; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcResume *) { + return IrInstSrcIdResume; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionPanic *) { - return IrInstructionIdPanic; +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSpillBegin *) { + return IrInstSrcIdSpillBegin; +} + +static constexpr IrInstSrcId ir_inst_id(IrInstSrcSpillEnd *) { + return IrInstSrcIdSpillEnd; +} + + +static constexpr IrInstGenId ir_inst_id(IrInstGenDeclVar *) { + return IrInstGenIdDeclVar; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionTagName *) { - return IrInstructionIdTagName; +static constexpr IrInstGenId ir_inst_id(IrInstGenBr *) { + return IrInstGenIdBr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionTagType *) { - return IrInstructionIdTagType; +static constexpr IrInstGenId ir_inst_id(IrInstGenCondBr *) { + return IrInstGenIdCondBr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldParentPtr *) { - return IrInstructionIdFieldParentPtr; +static constexpr IrInstGenId ir_inst_id(IrInstGenSwitchBr *) { + return IrInstGenIdSwitchBr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionByteOffsetOf *) { - return IrInstructionIdByteOffsetOf; +static constexpr IrInstGenId ir_inst_id(IrInstGenPhi *) { + return IrInstGenIdPhi; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionBitOffsetOf *) { - return IrInstructionIdBitOffsetOf; +static constexpr IrInstGenId ir_inst_id(IrInstGenBinaryNot *) { + return IrInstGenIdBinaryNot; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) { - return IrInstructionIdTypeInfo; +static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) { + return IrInstGenIdNegation; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionType *) { - return IrInstructionIdType; +static constexpr IrInstGenId ir_inst_id(IrInstGenNegationWrapping *) { + return IrInstGenIdNegationWrapping; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionHasField *) { - return IrInstructionIdHasField; +static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) { + return IrInstGenIdBinOp; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { - return IrInstructionIdTypeId; +static constexpr IrInstGenId ir_inst_id(IrInstGenLoadPtr *) { + return IrInstGenIdLoadPtr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSetEvalBranchQuota *) { - return IrInstructionIdSetEvalBranchQuota; +static constexpr IrInstGenId ir_inst_id(IrInstGenStorePtr *) { + return IrInstGenIdStorePtr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrType *) { - return IrInstructionIdPtrType; +static constexpr IrInstGenId ir_inst_id(IrInstGenVectorStoreElem *) { + return IrInstGenIdVectorStoreElem; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) { - return IrInstructionIdAlignCast; +static constexpr IrInstGenId ir_inst_id(IrInstGenStructFieldPtr *) { + return IrInstGenIdStructFieldPtr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionImplicitCast *) { - return IrInstructionIdImplicitCast; +static constexpr IrInstGenId ir_inst_id(IrInstGenUnionFieldPtr *) { + return IrInstGenIdUnionFieldPtr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *) { - return IrInstructionIdResolveResult; +static constexpr IrInstGenId ir_inst_id(IrInstGenElemPtr *) { + return IrInstGenIdElemPtr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionResetResult *) { - return IrInstructionIdResetResult; +static constexpr IrInstGenId ir_inst_id(IrInstGenVarPtr *) { + return IrInstGenIdVarPtr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrOfArrayToSlice *) { - return IrInstructionIdPtrOfArrayToSlice; +static constexpr IrInstGenId ir_inst_id(IrInstGenReturnPtr *) { + return IrInstGenIdReturnPtr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) { - return IrInstructionIdOpaqueType; +static constexpr IrInstGenId ir_inst_id(IrInstGenCall *) { + return IrInstGenIdCall; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSetAlignStack *) { - return IrInstructionIdSetAlignStack; +static constexpr IrInstGenId ir_inst_id(IrInstGenReturn *) { + return IrInstGenIdReturn; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionArgType *) { - return IrInstructionIdArgType; +static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) { + return IrInstGenIdCast; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorReturnTrace *) { - return IrInstructionIdErrorReturnTrace; +static constexpr IrInstGenId ir_inst_id(IrInstGenResizeSlice *) { + return IrInstGenIdResizeSlice; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorUnion *) { - return IrInstructionIdErrorUnion; +static constexpr IrInstGenId ir_inst_id(IrInstGenUnreachable *) { + return IrInstGenIdUnreachable; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicRmw *) { - return IrInstructionIdAtomicRmw; +static constexpr IrInstGenId ir_inst_id(IrInstGenAsm *) { + return IrInstGenIdAsm; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicLoad *) { - return IrInstructionIdAtomicLoad; +static constexpr IrInstGenId ir_inst_id(IrInstGenTestNonNull *) { + return IrInstGenIdTestNonNull; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicStore *) { - return IrInstructionIdAtomicStore; +static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalUnwrapPtr *) { + return IrInstGenIdOptionalUnwrapPtr; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSaveErrRetAddr *) { - return IrInstructionIdSaveErrRetAddr; +static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalWrap *) { + return IrInstGenIdOptionalWrap; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAddImplicitReturnType *) { - return IrInstructionIdAddImplicitReturnType; +static constexpr IrInstGenId ir_inst_id(IrInstGenUnionTag *) { + return IrInstGenIdUnionTag; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatOp *) { - return IrInstructionIdFloatOp; +static constexpr IrInstGenId ir_inst_id(IrInstGenClz *) { + return IrInstGenIdClz; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { - return IrInstructionIdCheckRuntimeScope; +static constexpr IrInstGenId ir_inst_id(IrInstGenCtz *) { + return IrInstGenIdCtz; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorToArray *) { - return IrInstructionIdVectorToArray; +static constexpr IrInstGenId ir_inst_id(IrInstGenPopCount *) { + return IrInstGenIdPopCount; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayToVector *) { - return IrInstructionIdArrayToVector; +static constexpr IrInstGenId ir_inst_id(IrInstGenBswap *) { + return IrInstGenIdBswap; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertZero *) { - return IrInstructionIdAssertZero; +static constexpr IrInstGenId ir_inst_id(IrInstGenBitReverse *) { + return IrInstGenIdBitReverse; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) { - return IrInstructionIdAssertNonNull; +static constexpr IrInstGenId ir_inst_id(IrInstGenRef *) { + return IrInstGenIdRef; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) { - return IrInstructionIdHasDecl; +static constexpr IrInstGenId ir_inst_id(IrInstGenErrName *) { + return IrInstGenIdErrName; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent *) { - return IrInstructionIdUndeclaredIdent; +static constexpr IrInstGenId ir_inst_id(IrInstGenCmpxchg *) { + return IrInstGenIdCmpxchg; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaSrc *) { - return IrInstructionIdAllocaSrc; +static constexpr IrInstGenId ir_inst_id(IrInstGenFence *) { + return IrInstGenIdFence; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaGen *) { - return IrInstructionIdAllocaGen; +static constexpr IrInstGenId ir_inst_id(IrInstGenTruncate *) { + return IrInstGenIdTruncate; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionEndExpr *) { - return IrInstructionIdEndExpr; +static constexpr IrInstGenId ir_inst_id(IrInstGenShuffleVector *) { + return IrInstGenIdShuffleVector; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInitNamedField *) { - return IrInstructionIdUnionInitNamedField; +static constexpr IrInstGenId ir_inst_id(IrInstGenSplat *) { + return IrInstGenIdSplat; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendBegin *) { - return IrInstructionIdSuspendBegin; +static constexpr IrInstGenId ir_inst_id(IrInstGenBoolNot *) { + return IrInstGenIdBoolNot; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSuspendFinish *) { - return IrInstructionIdSuspendFinish; +static constexpr IrInstGenId ir_inst_id(IrInstGenMemset *) { + return IrInstGenIdMemset; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAwaitSrc *) { - return IrInstructionIdAwaitSrc; +static constexpr IrInstGenId ir_inst_id(IrInstGenMemcpy *) { + return IrInstGenIdMemcpy; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionAwaitGen *) { - return IrInstructionIdAwaitGen; +static constexpr IrInstGenId ir_inst_id(IrInstGenSlice *) { + return IrInstGenIdSlice; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionResume *) { - return IrInstructionIdResume; +static constexpr IrInstGenId ir_inst_id(IrInstGenBreakpoint *) { + return IrInstGenIdBreakpoint; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSpillBegin *) { - return IrInstructionIdSpillBegin; +static constexpr IrInstGenId ir_inst_id(IrInstGenReturnAddress *) { + return IrInstGenIdReturnAddress; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionSpillEnd *) { - return IrInstructionIdSpillEnd; +static constexpr IrInstGenId ir_inst_id(IrInstGenFrameAddress *) { + return IrInstGenIdFrameAddress; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorExtractElem *) { - return IrInstructionIdVectorExtractElem; +static constexpr IrInstGenId ir_inst_id(IrInstGenFrameHandle *) { + return IrInstGenIdFrameHandle; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenFrameSize *) { + return IrInstGenIdFrameSize; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenOverflowOp *) { + return IrInstGenIdOverflowOp; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenTestErr *) { + return IrInstGenIdTestErr; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenMulAdd *) { + return IrInstGenIdMulAdd; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenFloatOp *) { + return IrInstGenIdFloatOp; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrCode *) { + return IrInstGenIdUnwrapErrCode; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrPayload *) { + return IrInstGenIdUnwrapErrPayload; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapCode *) { + return IrInstGenIdErrWrapCode; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapPayload *) { + return IrInstGenIdErrWrapPayload; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenPtrCast *) { + return IrInstGenIdPtrCast; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenBitCast *) { + return IrInstGenIdBitCast; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenWidenOrShorten *) { + return IrInstGenIdWidenOrShorten; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenIntToPtr *) { + return IrInstGenIdIntToPtr; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenPtrToInt *) { + return IrInstGenIdPtrToInt; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenIntToEnum *) { + return IrInstGenIdIntToEnum; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenIntToErr *) { + return IrInstGenIdIntToErr; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenErrToInt *) { + return IrInstGenIdErrToInt; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenPanic *) { + return IrInstGenIdPanic; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenTagName *) { + return IrInstGenIdTagName; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenFieldParentPtr *) { + return IrInstGenIdFieldParentPtr; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenAlignCast *) { + return IrInstGenIdAlignCast; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenErrorReturnTrace *) { + return IrInstGenIdErrorReturnTrace; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicRmw *) { + return IrInstGenIdAtomicRmw; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicLoad *) { + return IrInstGenIdAtomicLoad; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicStore *) { + return IrInstGenIdAtomicStore; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenSaveErrRetAddr *) { + return IrInstGenIdSaveErrRetAddr; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenVectorToArray *) { + return IrInstGenIdVectorToArray; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenArrayToVector *) { + return IrInstGenIdArrayToVector; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenAssertZero *) { + return IrInstGenIdAssertZero; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenAssertNonNull *) { + return IrInstGenIdAssertNonNull; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenPtrOfArrayToSlice *) { + return IrInstGenIdPtrOfArrayToSlice; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendBegin *) { + return IrInstGenIdSuspendBegin; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendFinish *) { + return IrInstGenIdSuspendFinish; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenAwait *) { + return IrInstGenIdAwait; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenResume *) { + return IrInstGenIdResume; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenSpillBegin *) { + return IrInstGenIdSpillBegin; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenSpillEnd *) { + return IrInstGenIdSpillEnd; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenVectorExtractElem *) { + return IrInstGenIdVectorExtractElem; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenAlloca *) { + return IrInstGenIdAlloca; +} + +static constexpr IrInstGenId ir_inst_id(IrInstGenConst *) { + return IrInstGenIdConst; } template<typename T> -static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { +static T *ir_create_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { const char *name = nullptr; #ifdef ZIG_ENABLE_MEM_PROFILE T *dummy = nullptr; - name = ir_instruction_type_str(ir_instruction_id(dummy)); + name = ir_inst_src_type_str(ir_inst_id(dummy)); #endif T *special_instruction = allocate<T>(1, name); - special_instruction->base.id = ir_instruction_id(special_instruction); - special_instruction->base.scope = scope; - special_instruction->base.source_node = source_node; - special_instruction->base.debug_id = exec_next_debug_id(irb->exec); + special_instruction->base.id = ir_inst_id(special_instruction); + special_instruction->base.base.scope = scope; + special_instruction->base.base.source_node = source_node; + special_instruction->base.base.debug_id = exec_next_debug_id(irb->exec); + special_instruction->base.owner_bb = irb->current_basic_block; + return special_instruction; +} + +template<typename T> +static T *ir_create_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { + const char *name = nullptr; +#ifdef ZIG_ENABLE_MEM_PROFILE + T *dummy = nullptr; + name = ir_inst_gen_type_str(ir_inst_id(dummy)); +#endif + T *special_instruction = allocate<T>(1, name); + special_instruction->base.id = ir_inst_id(special_instruction); + special_instruction->base.base.scope = scope; + special_instruction->base.base.source_node = source_node; + special_instruction->base.base.debug_id = exec_next_debug_id_gen(irb->exec); special_instruction->base.owner_bb = irb->current_basic_block; special_instruction->base.value = allocate<ZigValue>(1, "ZigValue"); return special_instruction; } template<typename T> -static T *ir_create_instruction_noval(IrBuilder *irb, Scope *scope, AstNode *source_node) { +static T *ir_create_inst_noval(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { const char *name = nullptr; #ifdef ZIG_ENABLE_MEM_PROFILE T *dummy = nullptr; - name = ir_instruction_type_str(ir_instruction_id(dummy)); + name = ir_inst_gen_type_str(ir_inst_id(dummy)); #endif T *special_instruction = allocate<T>(1, name); - special_instruction->base.id = ir_instruction_id(special_instruction); - special_instruction->base.scope = scope; - special_instruction->base.source_node = source_node; - special_instruction->base.debug_id = exec_next_debug_id(irb->exec); + special_instruction->base.id = ir_inst_id(special_instruction); + special_instruction->base.base.scope = scope; + special_instruction->base.base.source_node = source_node; + special_instruction->base.base.debug_id = exec_next_debug_id_gen(irb->exec); special_instruction->base.owner_bb = irb->current_basic_block; return special_instruction; } template<typename T> -static T *ir_build_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { +static T *ir_build_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { T *special_instruction = ir_create_instruction<T>(irb, scope, source_node); ir_instruction_append(irb->current_basic_block, &special_instruction->base); return special_instruction; } -static IrInstruction *ir_build_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigType *dest_type, - IrInstruction *value, CastOp cast_op) +template<typename T> +static T *ir_build_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { + T *special_instruction = ir_create_inst_gen<T>(irb, scope, source_node); + ir_inst_gen_append(irb->current_basic_block, &special_instruction->base); + return special_instruction; +} + +template<typename T> +static T *ir_build_inst_noreturn(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { + T *special_instruction = ir_create_inst_noval<T>(irb, scope, source_node); + special_instruction->base.value = irb->codegen->intern.for_unreachable(); + ir_inst_gen_append(irb->current_basic_block, &special_instruction->base); + return special_instruction; +} + +template<typename T> +static T *ir_build_inst_void(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { + T *special_instruction = ir_create_inst_noval<T>(irb, scope, source_node); + special_instruction->base.value = irb->codegen->intern.for_void(); + ir_inst_gen_append(irb->current_basic_block, &special_instruction->base); + return special_instruction; +} + +IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn, + ZigType *var_type, const char *name_hint) { - IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, scope, source_node); - cast_instruction->dest_type = dest_type; - cast_instruction->value = value; - cast_instruction->cast_op = cast_op; + IrInstGenAlloca *alloca_gen = allocate<IrInstGenAlloca>(1); + alloca_gen->base.id = IrInstGenIdAlloca; + alloca_gen->base.base.source_node = source_node; + alloca_gen->base.base.scope = scope; + alloca_gen->base.value = allocate<ZigValue>(1, "ZigValue"); + alloca_gen->base.value->type = get_pointer_to_type(g, var_type, false); + alloca_gen->base.base.ref_count = 1; + alloca_gen->name_hint = name_hint; + fn->alloca_gen_list.append(alloca_gen); + return &alloca_gen->base; +} - ir_ref_instruction(value, irb->current_basic_block); +static IrInstGen *ir_build_cast(IrAnalyze *ira, IrInst *source_instr,ZigType *dest_type, + IrInstGen *value, CastOp cast_op) +{ + IrInstGenCast *inst = ir_build_inst_gen<IrInstGenCast>(&ira->new_irb, source_instr->scope, source_instr->source_node); + inst->base.value->type = dest_type; + inst->value = value; + inst->cast_op = cast_op; + + ir_ref_inst_gen(value, ira->new_irb.current_basic_block); - return &cast_instruction->base; + return &inst->base; } -static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *condition, - IrBasicBlock *then_block, IrBasicBlock *else_block, IrInstruction *is_comptime) +static IrInstSrc *ir_build_cond_br(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *condition, + IrBasicBlockSrc *then_block, IrBasicBlockSrc *else_block, IrInstSrc *is_comptime) { - IrInstructionCondBr *cond_br_instruction = ir_build_instruction<IrInstructionCondBr>(irb, scope, source_node); - cond_br_instruction->base.value->type = irb->codegen->builtin_types.entry_unreachable; - cond_br_instruction->base.value->special = ConstValSpecialStatic; - cond_br_instruction->condition = condition; - cond_br_instruction->then_block = then_block; - cond_br_instruction->else_block = else_block; - cond_br_instruction->is_comptime = is_comptime; + IrInstSrcCondBr *inst = ir_build_instruction<IrInstSrcCondBr>(irb, scope, source_node); + inst->base.is_noreturn = true; + inst->condition = condition; + inst->then_block = then_block; + inst->else_block = else_block; + inst->is_comptime = is_comptime; ir_ref_instruction(condition, irb->current_basic_block); ir_ref_bb(then_block); ir_ref_bb(else_block); if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); - return &cond_br_instruction->base; + return &inst->base; } -static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *operand) +static IrInstGen *ir_build_cond_br_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *condition, + IrBasicBlockGen *then_block, IrBasicBlockGen *else_block) { - IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node); - return_instruction->base.value->type = irb->codegen->builtin_types.entry_unreachable; - return_instruction->base.value->special = ConstValSpecialStatic; - return_instruction->operand = operand; + IrInstGenCondBr *inst = ir_build_inst_noreturn<IrInstGenCondBr>(&ira->new_irb, source_instr->scope, source_instr->source_node); + inst->condition = condition; + inst->then_block = then_block; + inst->else_block = else_block; + + ir_ref_inst_gen(condition, ira->new_irb.current_basic_block); + ir_ref_bb_gen(then_block); + ir_ref_bb_gen(else_block); + + return &inst->base; +} + +static IrInstSrc *ir_build_return_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *operand) { + IrInstSrcReturn *inst = ir_build_instruction<IrInstSrcReturn>(irb, scope, source_node); + inst->base.is_noreturn = true; + inst->operand = operand; if (operand != nullptr) ir_ref_instruction(operand, irb->current_basic_block); - return &return_instruction->base; + return &inst->base; +} + +static IrInstGen *ir_build_return_gen(IrAnalyze *ira, IrInst *source_inst, IrInstGen *operand) { + IrInstGenReturn *inst = ir_build_inst_noreturn<IrInstGenReturn>(&ira->new_irb, + source_inst->scope, source_inst->source_node); + inst->operand = operand; + + if (operand != nullptr) ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); + + return &inst->base; } -static IrInstruction *ir_build_const_void(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(irb, scope, source_node); +static IrInstSrc *ir_build_const_void(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { + IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); ir_instruction_append(irb->current_basic_block, &const_instruction->base); - const_instruction->base.value = irb->codegen->intern.for_void(); + const_instruction->value = irb->codegen->intern.for_void(); return &const_instruction->base; } -static IrInstruction *ir_build_const_undefined(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(irb, scope, source_node); +static IrInstSrc *ir_build_const_undefined(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { + IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); ir_instruction_append(irb->current_basic_block, &const_instruction->base); - const_instruction->base.value = irb->codegen->intern.for_undefined(); + const_instruction->value = irb->codegen->intern.for_undefined(); return &const_instruction->base; } -static IrInstruction *ir_build_const_uint(IrBuilder *irb, Scope *scope, AstNode *source_node, uint64_t value) { - IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); - const_instruction->base.value->type = irb->codegen->builtin_types.entry_num_lit_int; - const_instruction->base.value->special = ConstValSpecialStatic; - bigint_init_unsigned(&const_instruction->base.value->data.x_bigint, value); +static IrInstSrc *ir_build_const_uint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, uint64_t value) { + IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); + const_instruction->value = create_const_vals(1); + const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_int; + const_instruction->value->special = ConstValSpecialStatic; + bigint_init_unsigned(&const_instruction->value->data.x_bigint, value); return &const_instruction->base; } -static IrInstruction *ir_build_const_bigint(IrBuilder *irb, Scope *scope, AstNode *source_node, BigInt *bigint) { - IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); - const_instruction->base.value->type = irb->codegen->builtin_types.entry_num_lit_int; - const_instruction->base.value->special = ConstValSpecialStatic; - bigint_init_bigint(&const_instruction->base.value->data.x_bigint, bigint); +static IrInstSrc *ir_build_const_bigint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigInt *bigint) { + IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); + const_instruction->value = create_const_vals(1); + const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_int; + const_instruction->value->special = ConstValSpecialStatic; + bigint_init_bigint(&const_instruction->value->data.x_bigint, bigint); return &const_instruction->base; } -static IrInstruction *ir_build_const_bigfloat(IrBuilder *irb, Scope *scope, AstNode *source_node, BigFloat *bigfloat) { - IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); - const_instruction->base.value->type = irb->codegen->builtin_types.entry_num_lit_float; - const_instruction->base.value->special = ConstValSpecialStatic; - bigfloat_init_bigfloat(&const_instruction->base.value->data.x_bigfloat, bigfloat); +static IrInstSrc *ir_build_const_bigfloat(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigFloat *bigfloat) { + IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); + const_instruction->value = create_const_vals(1); + const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_float; + const_instruction->value->special = ConstValSpecialStatic; + bigfloat_init_bigfloat(&const_instruction->value->data.x_bigfloat, bigfloat); return &const_instruction->base; } -static IrInstruction *ir_build_const_null(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(irb, scope, source_node); +static IrInstSrc *ir_build_const_null(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { + IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); ir_instruction_append(irb->current_basic_block, &const_instruction->base); - const_instruction->base.value = irb->codegen->intern.for_null(); + const_instruction->value = irb->codegen->intern.for_null(); return &const_instruction->base; } -static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode *source_node, uint64_t value) { - IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); - const_instruction->base.value->type = irb->codegen->builtin_types.entry_usize; - const_instruction->base.value->special = ConstValSpecialStatic; - bigint_init_unsigned(&const_instruction->base.value->data.x_bigint, value); +static IrInstSrc *ir_build_const_usize(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, uint64_t value) { + IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); + const_instruction->value = create_const_vals(1); + const_instruction->value->type = irb->codegen->builtin_types.entry_usize; + const_instruction->value->special = ConstValSpecialStatic; + bigint_init_unsigned(&const_instruction->value->data.x_bigint, value); return &const_instruction->base; } -static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, +static IrInstSrc *ir_create_const_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigType *type_entry) { - IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); - const_instruction->base.value->type = irb->codegen->builtin_types.entry_type; - const_instruction->base.value->special = ConstValSpecialStatic; - const_instruction->base.value->data.x_type = type_entry; + IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); + const_instruction->value = create_const_vals(1); + const_instruction->value->type = irb->codegen->builtin_types.entry_type; + const_instruction->value->special = ConstValSpecialStatic; + const_instruction->value->data.x_type = type_entry; return &const_instruction->base; } -static IrInstruction *ir_build_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, +static IrInstSrc *ir_build_const_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigType *type_entry) { - IrInstruction *instruction = ir_create_const_type(irb, scope, source_node, type_entry); + IrInstSrc *instruction = ir_create_const_type(irb, scope, source_node, type_entry); ir_instruction_append(irb->current_basic_block, instruction); return instruction; } -static IrInstruction *ir_create_const_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigFn *fn_entry) { - IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); - const_instruction->base.value->type = fn_entry->type_entry; - const_instruction->base.value->special = ConstValSpecialStatic; - const_instruction->base.value->data.x_ptr.data.fn.fn_entry = fn_entry; - const_instruction->base.value->data.x_ptr.mut = ConstPtrMutComptimeConst; - const_instruction->base.value->data.x_ptr.special = ConstPtrSpecialFunction; - return &const_instruction->base; -} - -static IrInstruction *ir_build_const_import(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigType *import) { - IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); - const_instruction->base.value->type = irb->codegen->builtin_types.entry_type; - const_instruction->base.value->special = ConstValSpecialStatic; - const_instruction->base.value->data.x_type = import; +static IrInstSrc *ir_build_const_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigType *import) { + IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); + const_instruction->value = create_const_vals(1); + const_instruction->value->type = irb->codegen->builtin_types.entry_type; + const_instruction->value->special = ConstValSpecialStatic; + const_instruction->value->data.x_type = import; return &const_instruction->base; } -static IrInstruction *ir_build_const_bool(IrBuilder *irb, Scope *scope, AstNode *source_node, bool value) { - IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); - const_instruction->base.value->type = irb->codegen->builtin_types.entry_bool; - const_instruction->base.value->special = ConstValSpecialStatic; - const_instruction->base.value->data.x_bool = value; +static IrInstSrc *ir_build_const_bool(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, bool value) { + IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); + const_instruction->value = create_const_vals(1); + const_instruction->value->type = irb->codegen->builtin_types.entry_bool; + const_instruction->value->special = ConstValSpecialStatic; + const_instruction->value->data.x_bool = value; return &const_instruction->base; } -static IrInstruction *ir_build_const_enum_literal(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *name) { - IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); - const_instruction->base.value->type = irb->codegen->builtin_types.entry_enum_literal; - const_instruction->base.value->special = ConstValSpecialStatic; - const_instruction->base.value->data.x_enum_literal = name; - return &const_instruction->base; -} - -static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, - ZigFn *fn_entry, IrInstruction *first_arg) -{ - IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); - const_instruction->base.value->type = get_bound_fn_type(irb->codegen, fn_entry); - const_instruction->base.value->special = ConstValSpecialStatic; - const_instruction->base.value->data.x_bound_fn.fn = fn_entry; - const_instruction->base.value->data.x_bound_fn.first_arg = first_arg; +static IrInstSrc *ir_build_const_enum_literal(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *name) { + IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); + const_instruction->value = create_const_vals(1); + const_instruction->value->type = irb->codegen->builtin_types.entry_enum_literal; + const_instruction->value->special = ConstValSpecialStatic; + const_instruction->value->data.x_enum_literal = name; return &const_instruction->base; } -static IrInstruction *ir_create_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { - IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); - init_const_str_lit(irb->codegen, const_instruction->base.value, str); +static IrInstSrc *ir_create_const_str_lit(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *str) { + IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); + const_instruction->value = create_const_vals(1); + init_const_str_lit(irb->codegen, const_instruction->value, str); return &const_instruction->base; } -static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { - IrInstruction *instruction = ir_create_const_str_lit(irb, scope, source_node, str); +static IrInstSrc *ir_build_const_str_lit(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *str) { + IrInstSrc *instruction = ir_create_const_str_lit(irb, scope, source_node, str); ir_instruction_append(irb->current_basic_block, instruction); return instruction; } -static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, - IrInstruction *op1, IrInstruction *op2, bool safety_check_on) +static IrInstSrc *ir_build_bin_op(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, + IrInstSrc *op1, IrInstSrc *op2, bool safety_check_on) { - IrInstructionBinOp *bin_op_instruction = ir_build_instruction<IrInstructionBinOp>(irb, scope, source_node); - bin_op_instruction->op_id = op_id; - bin_op_instruction->op1 = op1; - bin_op_instruction->op2 = op2; - bin_op_instruction->safety_check_on = safety_check_on; + IrInstSrcBinOp *inst = ir_build_instruction<IrInstSrcBinOp>(irb, scope, source_node); + inst->op_id = op_id; + inst->op1 = op1; + inst->op2 = op2; + inst->safety_check_on = safety_check_on; ir_ref_instruction(op1, irb->current_basic_block); ir_ref_instruction(op2, irb->current_basic_block); - return &bin_op_instruction->base; + return &inst->base; } -static IrInstruction *ir_build_bin_op_gen(IrAnalyze *ira, IrInstruction *source_instr, ZigType *res_type, - IrBinOp op_id, IrInstruction *op1, IrInstruction *op2, bool safety_check_on) +static IrInstGen *ir_build_bin_op_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *res_type, + IrBinOp op_id, IrInstGen *op1, IrInstGen *op2, bool safety_check_on) { - IrInstructionBinOp *bin_op_instruction = ir_build_instruction<IrInstructionBinOp>(&ira->new_irb, + IrInstGenBinOp *inst = ir_build_inst_gen<IrInstGenBinOp>(&ira->new_irb, source_instr->scope, source_instr->source_node); - bin_op_instruction->base.value->type = res_type; - bin_op_instruction->op_id = op_id; - bin_op_instruction->op1 = op1; - bin_op_instruction->op2 = op2; - bin_op_instruction->safety_check_on = safety_check_on; + inst->base.value->type = res_type; + inst->op_id = op_id; + inst->op1 = op1; + inst->op2 = op2; + inst->safety_check_on = safety_check_on; - ir_ref_instruction(op1, ira->new_irb.current_basic_block); - ir_ref_instruction(op2, ira->new_irb.current_basic_block); + ir_ref_inst_gen(op1, ira->new_irb.current_basic_block); + ir_ref_inst_gen(op2, ira->new_irb.current_basic_block); - return &bin_op_instruction->base; + return &inst->base; } -static IrInstruction *ir_build_merge_err_sets(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *op1, IrInstruction *op2, Buf *type_name) +static IrInstSrc *ir_build_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *op1, IrInstSrc *op2, Buf *type_name) { - IrInstructionMergeErrSets *merge_err_sets_instruction = ir_build_instruction<IrInstructionMergeErrSets>(irb, scope, source_node); - merge_err_sets_instruction->op1 = op1; - merge_err_sets_instruction->op2 = op2; - merge_err_sets_instruction->type_name = type_name; + IrInstSrcMergeErrSets *inst = ir_build_instruction<IrInstSrcMergeErrSets>(irb, scope, source_node); + inst->op1 = op1; + inst->op2 = op2; + inst->type_name = type_name; ir_ref_instruction(op1, irb->current_basic_block); ir_ref_instruction(op2, irb->current_basic_block); - return &merge_err_sets_instruction->base; + return &inst->base; } -static IrInstruction *ir_build_var_ptr_x(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, +static IrInstSrc *ir_build_var_ptr_x(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var, ScopeFnDef *crossed_fndef_scope) { - IrInstructionVarPtr *instruction = ir_build_instruction<IrInstructionVarPtr>(irb, scope, source_node); + IrInstSrcVarPtr *instruction = ir_build_instruction<IrInstSrcVarPtr>(irb, scope, source_node); instruction->var = var; instruction->crossed_fndef_scope = crossed_fndef_scope; @@ -1835,22 +2310,30 @@ static IrInstruction *ir_build_var_ptr_x(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } -static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var) { +static IrInstSrc *ir_build_var_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var) { 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); +static IrInstGen *ir_build_var_ptr_gen(IrAnalyze *ira, IrInst *source_instr, ZigVar *var) { + IrInstGenVarPtr *instruction = ir_build_inst_gen<IrInstGenVarPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node); + instruction->var = var; + + ir_ref_var(var); + + return &instruction->base; +} + +static IrInstGen *ir_build_return_ptr(IrAnalyze *ira, Scope *scope, AstNode *source_node, ZigType *ty) { + IrInstGenReturnPtr *instruction = ir_build_inst_gen<IrInstGenReturnPtr>(&ira->new_irb, scope, 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, +static IrInstSrc *ir_build_elem_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *array_ptr, IrInstSrc *elem_index, bool safety_check_on, PtrLen ptr_len, AstNode *init_array_type_source_node) { - IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node); + IrInstSrcElemPtr *instruction = ir_build_instruction<IrInstSrcElemPtr>(irb, scope, source_node); instruction->array_ptr = array_ptr; instruction->elem_index = elem_index; instruction->safety_check_on = safety_check_on; @@ -1863,10 +2346,25 @@ static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *container_ptr, IrInstruction *field_name_expr, bool initializing) +static IrInstGen *ir_build_elem_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, + IrInstGen *array_ptr, IrInstGen *elem_index, bool safety_check_on, ZigType *return_type) +{ + IrInstGenElemPtr *instruction = ir_build_inst_gen<IrInstGenElemPtr>(&ira->new_irb, scope, source_node); + instruction->base.value->type = return_type; + instruction->array_ptr = array_ptr; + instruction->elem_index = elem_index; + instruction->safety_check_on = safety_check_on; + + ir_ref_inst_gen(array_ptr, ira->new_irb.current_basic_block); + ir_ref_inst_gen(elem_index, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_field_ptr_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *container_ptr, IrInstSrc *field_name_expr, bool initializing) { - IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); + IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(irb, scope, source_node); instruction->container_ptr = container_ptr; instruction->field_name_buffer = nullptr; instruction->field_name_expr = field_name_expr; @@ -1878,10 +2376,10 @@ static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scop return &instruction->base; } -static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *container_ptr, Buf *field_name, bool initializing) +static IrInstSrc *ir_build_field_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *container_ptr, Buf *field_name, bool initializing) { - IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); + IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(irb, scope, source_node); instruction->container_ptr = container_ptr; instruction->field_name_buffer = field_name; instruction->field_name_expr = nullptr; @@ -1892,10 +2390,10 @@ static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } -static IrInstruction *ir_build_has_field(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *container_type, IrInstruction *field_name) +static IrInstSrc *ir_build_has_field(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *container_type, IrInstSrc *field_name) { - IrInstructionHasField *instruction = ir_build_instruction<IrInstructionHasField>(irb, scope, source_node); + IrInstSrcHasField *instruction = ir_build_instruction<IrInstSrcHasField>(irb, scope, source_node); instruction->container_type = container_type; instruction->field_name = field_name; @@ -1905,36 +2403,39 @@ static IrInstruction *ir_build_has_field(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } -static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *struct_ptr, TypeStructField *field) +static IrInstGen *ir_build_struct_field_ptr(IrAnalyze *ira, IrInst *source_instr, + IrInstGen *struct_ptr, TypeStructField *field, ZigType *ptr_type) { - IrInstructionStructFieldPtr *instruction = ir_build_instruction<IrInstructionStructFieldPtr>(irb, scope, source_node); - instruction->struct_ptr = struct_ptr; - instruction->field = field; + IrInstGenStructFieldPtr *inst = ir_build_inst_gen<IrInstGenStructFieldPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node); + inst->base.value->type = ptr_type; + inst->struct_ptr = struct_ptr; + inst->field = field; - ir_ref_instruction(struct_ptr, irb->current_basic_block); + ir_ref_inst_gen(struct_ptr, ira->new_irb.current_basic_block); - return &instruction->base; + return &inst->base; } -static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing) +static IrInstGen *ir_build_union_field_ptr(IrAnalyze *ira, IrInst *source_instr, + IrInstGen *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing, ZigType *ptr_type) { - IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node); - instruction->initializing = initializing; - instruction->safety_check_on = safety_check_on; - instruction->union_ptr = union_ptr; - instruction->field = field; + IrInstGenUnionFieldPtr *inst = ir_build_inst_gen<IrInstGenUnionFieldPtr>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + inst->base.value->type = ptr_type; + inst->initializing = initializing; + inst->safety_check_on = safety_check_on; + inst->union_ptr = union_ptr; + inst->field = field; - ir_ref_instruction(union_ptr, irb->current_basic_block); + ir_ref_inst_gen(union_ptr, ira->new_irb.current_basic_block); - return &instruction->base; + return &inst->base; } -static IrInstruction *ir_build_call_extra(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *options, IrInstruction *fn_ref, IrInstruction *args, ResultLoc *result_loc) +static IrInstSrc *ir_build_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc *args, ResultLoc *result_loc) { - IrInstructionCallExtra *call_instruction = ir_build_instruction<IrInstructionCallExtra>(irb, scope, source_node); + IrInstSrcCallExtra *call_instruction = ir_build_instruction<IrInstSrcCallExtra>(irb, scope, source_node); call_instruction->options = options; call_instruction->fn_ref = fn_ref; call_instruction->args = args; @@ -1947,11 +2448,11 @@ static IrInstruction *ir_build_call_extra(IrBuilder *irb, Scope *scope, AstNode return &call_instruction->base; } -static IrInstruction *ir_build_call_src_args(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *options, IrInstruction *fn_ref, IrInstruction **args_ptr, size_t args_len, +static IrInstSrc *ir_build_call_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc **args_ptr, size_t args_len, ResultLoc *result_loc) { - IrInstructionCallSrcArgs *call_instruction = ir_build_instruction<IrInstructionCallSrcArgs>(irb, scope, source_node); + IrInstSrcCallArgs *call_instruction = ir_build_instruction<IrInstSrcCallArgs>(irb, scope, source_node); call_instruction->options = options; call_instruction->fn_ref = fn_ref; call_instruction->args_ptr = args_ptr; @@ -1966,12 +2467,12 @@ static IrInstruction *ir_build_call_src_args(IrBuilder *irb, Scope *scope, AstNo return &call_instruction->base; } -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, - IrInstruction *ret_ptr, CallModifier modifier, bool is_async_call_builtin, - IrInstruction *new_stack, ResultLoc *result_loc) +static IrInstSrc *ir_build_call_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + ZigFn *fn_entry, IrInstSrc *fn_ref, size_t arg_count, IrInstSrc **args, + IrInstSrc *ret_ptr, CallModifier modifier, bool is_async_call_builtin, + IrInstSrc *new_stack, ResultLoc *result_loc) { - IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node); + IrInstSrcCall *call_instruction = ir_build_instruction<IrInstSrcCall>(irb, scope, source_node); call_instruction->fn_entry = fn_entry; call_instruction->fn_ref = fn_ref; call_instruction->args = args; @@ -1991,12 +2492,12 @@ static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *s return &call_instruction->base; } -static IrInstructionCallGen *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction, - ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, - CallModifier modifier, IrInstruction *new_stack, bool is_async_call_builtin, - IrInstruction *result_loc, ZigType *return_type) +static IrInstGenCall *ir_build_call_gen(IrAnalyze *ira, IrInst *source_instruction, + ZigFn *fn_entry, IrInstGen *fn_ref, size_t arg_count, IrInstGen **args, + CallModifier modifier, IrInstGen *new_stack, bool is_async_call_builtin, + IrInstGen *result_loc, ZigType *return_type) { - IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb, + IrInstGenCall *call_instruction = ir_build_inst_gen<IrInstGenCall>(&ira->new_irb, source_instruction->scope, source_instruction->source_node); call_instruction->base.value->type = return_type; call_instruction->fn_entry = fn_entry; @@ -2008,23 +2509,23 @@ static IrInstructionCallGen *ir_build_call_gen(IrAnalyze *ira, IrInstruction *so 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); + if (fn_ref != nullptr) ir_ref_inst_gen(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 (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); + ir_ref_inst_gen(args[i], ira->new_irb.current_basic_block); + if (new_stack != nullptr) ir_ref_inst_gen(new_stack, ira->new_irb.current_basic_block); + if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); return call_instruction; } -static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node, - size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values, +static IrInstSrc *ir_build_phi(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + size_t incoming_count, IrBasicBlockSrc **incoming_blocks, IrInstSrc **incoming_values, ResultLocPeerParent *peer_parent) { assert(incoming_count != 0); assert(incoming_count != SIZE_MAX); - IrInstructionPhi *phi_instruction = ir_build_instruction<IrInstructionPhi>(irb, scope, source_node); + IrInstSrcPhi *phi_instruction = ir_build_instruction<IrInstSrcPhi>(irb, scope, source_node); phi_instruction->incoming_count = incoming_count; phi_instruction->incoming_blocks = incoming_blocks; phi_instruction->incoming_values = incoming_values; @@ -2038,56 +2539,77 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source return &phi_instruction->base; } -static IrInstruction *ir_create_br(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrBasicBlock *dest_block, IrInstruction *is_comptime) +static IrInstGen *ir_build_phi_gen(IrAnalyze *ira, IrInst *source_instr, size_t incoming_count, + IrBasicBlockGen **incoming_blocks, IrInstGen **incoming_values, ZigType *result_type) { - IrInstructionBr *br_instruction = ir_create_instruction<IrInstructionBr>(irb, scope, source_node); - br_instruction->base.value->type = irb->codegen->builtin_types.entry_unreachable; - br_instruction->base.value->special = ConstValSpecialStatic; - br_instruction->dest_block = dest_block; - br_instruction->is_comptime = is_comptime; + assert(incoming_count != 0); + assert(incoming_count != SIZE_MAX); + + IrInstGenPhi *phi_instruction = ir_build_inst_gen<IrInstGenPhi>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + phi_instruction->base.value->type = result_type; + phi_instruction->incoming_count = incoming_count; + phi_instruction->incoming_blocks = incoming_blocks; + phi_instruction->incoming_values = incoming_values; + + for (size_t i = 0; i < incoming_count; i += 1) { + ir_ref_bb_gen(incoming_blocks[i]); + ir_ref_inst_gen(incoming_values[i], ira->new_irb.current_basic_block); + } + + return &phi_instruction->base; +} + +static IrInstSrc *ir_build_br(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrBasicBlockSrc *dest_block, IrInstSrc *is_comptime) +{ + IrInstSrcBr *inst = ir_build_instruction<IrInstSrcBr>(irb, scope, source_node); + inst->base.is_noreturn = true; + inst->dest_block = dest_block; + inst->is_comptime = is_comptime; ir_ref_bb(dest_block); if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); - return &br_instruction->base; + return &inst->base; } -static IrInstruction *ir_build_br(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrBasicBlock *dest_block, IrInstruction *is_comptime) -{ - IrInstruction *instruction = ir_create_br(irb, scope, source_node, dest_block, is_comptime); - ir_instruction_append(irb->current_basic_block, instruction); - return instruction; +static IrInstGen *ir_build_br_gen(IrAnalyze *ira, IrInst *source_instr, IrBasicBlockGen *dest_block) { + IrInstGenBr *inst = ir_build_inst_noreturn<IrInstGenBr>(&ira->new_irb, source_instr->scope, source_instr->source_node); + inst->dest_block = dest_block; + + ir_ref_bb_gen(dest_block); + + return &inst->base; } -static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *child_type, bool is_const, bool is_volatile, PtrLen ptr_len, - IrInstruction *sentinel, IrInstruction *align_value, +static IrInstSrc *ir_build_ptr_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *child_type, bool is_const, bool is_volatile, PtrLen ptr_len, + IrInstSrc *sentinel, IrInstSrc *align_value, uint32_t bit_offset_start, uint32_t host_int_bytes, bool is_allow_zero) { - IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node); - ptr_type_of_instruction->sentinel = sentinel; - ptr_type_of_instruction->align_value = align_value; - ptr_type_of_instruction->child_type = child_type; - ptr_type_of_instruction->is_const = is_const; - ptr_type_of_instruction->is_volatile = is_volatile; - ptr_type_of_instruction->ptr_len = ptr_len; - ptr_type_of_instruction->bit_offset_start = bit_offset_start; - ptr_type_of_instruction->host_int_bytes = host_int_bytes; - ptr_type_of_instruction->is_allow_zero = is_allow_zero; + IrInstSrcPtrType *inst = ir_build_instruction<IrInstSrcPtrType>(irb, scope, source_node); + inst->sentinel = sentinel; + inst->align_value = align_value; + inst->child_type = child_type; + inst->is_const = is_const; + inst->is_volatile = is_volatile; + inst->ptr_len = ptr_len; + inst->bit_offset_start = bit_offset_start; + inst->host_int_bytes = host_int_bytes; + inst->is_allow_zero = is_allow_zero; if (sentinel) ir_ref_instruction(sentinel, irb->current_basic_block); if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); ir_ref_instruction(child_type, irb->current_basic_block); - return &ptr_type_of_instruction->base; + return &inst->base; } -static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, - IrInstruction *value, LVal lval, ResultLoc *result_loc) +static IrInstSrc *ir_build_un_op_lval(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, + IrInstSrc *value, LVal lval, ResultLoc *result_loc) { - IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node); + IrInstSrcUnOp *instruction = ir_build_instruction<IrInstSrcUnOp>(irb, scope, source_node); instruction->op_id = op_id; instruction->value = value; instruction->lval = lval; @@ -2098,18 +2620,55 @@ static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, - IrInstruction *value) +static IrInstSrc *ir_build_un_op(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, + IrInstSrc *value) { return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr); } -static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node, - size_t item_count, IrInstruction **elem_result_loc_list, IrInstruction *result_loc, +static IrInstGen *ir_build_negation(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, ZigType *expr_type) { + IrInstGenNegation *instruction = ir_build_inst_gen<IrInstGenNegation>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = expr_type; + instruction->operand = operand; + + ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstGen *ir_build_negation_wrapping(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, + ZigType *expr_type) +{ + IrInstGenNegationWrapping *instruction = ir_build_inst_gen<IrInstGenNegationWrapping>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = expr_type; + instruction->operand = operand; + + ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstGen *ir_build_binary_not(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, + ZigType *expr_type) +{ + IrInstGenBinaryNot *instruction = ir_build_inst_gen<IrInstGenBinaryNot>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = expr_type; + instruction->operand = operand; + + ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_container_init_list(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + size_t item_count, IrInstSrc **elem_result_loc_list, IrInstSrc *result_loc, AstNode *init_array_type_source_node) { - IrInstructionContainerInitList *container_init_list_instruction = - ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node); + IrInstSrcContainerInitList *container_init_list_instruction = + ir_build_instruction<IrInstSrcContainerInitList>(irb, scope, source_node); container_init_list_instruction->item_count = item_count; container_init_list_instruction->elem_result_loc_list = elem_result_loc_list; container_init_list_instruction->result_loc = result_loc; @@ -2123,11 +2682,11 @@ static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, return &container_init_list_instruction->base; } -static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node, - size_t field_count, IrInstructionContainerInitFieldsField *fields, IrInstruction *result_loc) +static IrInstSrc *ir_build_container_init_fields(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + size_t field_count, IrInstSrcContainerInitFieldsField *fields, IrInstSrc *result_loc) { - IrInstructionContainerInitFields *container_init_fields_instruction = - ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node); + IrInstSrcContainerInitFields *container_init_fields_instruction = + ir_build_instruction<IrInstSrcContainerInitFields>(irb, scope, source_node); container_init_fields_instruction->field_count = field_count; container_init_fields_instruction->fields = fields; container_init_fields_instruction->result_loc = result_loc; @@ -2140,20 +2699,21 @@ static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scop return &container_init_fields_instruction->base; } -static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionUnreachable *unreachable_instruction = - ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node); - unreachable_instruction->base.value->special = ConstValSpecialStatic; - unreachable_instruction->base.value->type = irb->codegen->builtin_types.entry_unreachable; - return &unreachable_instruction->base; +static IrInstSrc *ir_build_unreachable(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { + IrInstSrcUnreachable *inst = ir_build_instruction<IrInstSrcUnreachable>(irb, scope, source_node); + inst->base.is_noreturn = true; + return &inst->base; +} + +static IrInstGen *ir_build_unreachable_gen(IrAnalyze *ira, IrInst *source_instr) { + IrInstGenUnreachable *inst = ir_build_inst_noreturn<IrInstGenUnreachable>(&ira->new_irb, source_instr->scope, source_instr->source_node); + return &inst->base; } -static IrInstructionStorePtr *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *ptr, IrInstruction *value) +static IrInstSrcStorePtr *ir_build_store_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *ptr, IrInstSrc *value) { - IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node); - instruction->base.value->special = ConstValSpecialStatic; - instruction->base.value->type = irb->codegen->builtin_types.entry_void; + IrInstSrcStorePtr *instruction = ir_build_instruction<IrInstSrcStorePtr>(irb, scope, source_node); instruction->ptr = ptr; instruction->value = value; @@ -2163,76 +2723,83 @@ static IrInstructionStorePtr *ir_build_store_ptr(IrBuilder *irb, Scope *scope, A return instruction; } -static IrInstruction *ir_build_vector_store_elem(IrAnalyze *ira, IrInstruction *source_instruction, - IrInstruction *vector_ptr, IrInstruction *index, IrInstruction *value) +static IrInstGen *ir_build_store_ptr_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *ptr, IrInstGen *value) { + IrInstGenStorePtr *instruction = ir_build_inst_void<IrInstGenStorePtr>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->ptr = ptr; + instruction->value = value; + + ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); + ir_ref_inst_gen(value, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstGen *ir_build_vector_store_elem(IrAnalyze *ira, IrInst *src_inst, + IrInstGen *vector_ptr, IrInstGen *index, IrInstGen *value) { - IrInstructionVectorStoreElem *inst = ir_build_instruction<IrInstructionVectorStoreElem>( - &ira->new_irb, source_instruction->scope, source_instruction->source_node); - inst->base.value->type = ira->codegen->builtin_types.entry_void; + IrInstGenVectorStoreElem *inst = ir_build_inst_void<IrInstGenVectorStoreElem>( + &ira->new_irb, src_inst->scope, src_inst->source_node); inst->vector_ptr = vector_ptr; inst->index = index; inst->value = value; - ir_ref_instruction(vector_ptr, ira->new_irb.current_basic_block); - ir_ref_instruction(index, ira->new_irb.current_basic_block); - ir_ref_instruction(value, ira->new_irb.current_basic_block); + ir_ref_inst_gen(vector_ptr, ira->new_irb.current_basic_block); + ir_ref_inst_gen(index, ira->new_irb.current_basic_block); + ir_ref_inst_gen(value, ira->new_irb.current_basic_block); return &inst->base; } -static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node, - ZigVar *var, IrInstruction *align_value, IrInstruction *ptr) +static IrInstSrc *ir_build_var_decl_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + ZigVar *var, IrInstSrc *align_value, IrInstSrc *ptr) { - IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node); - decl_var_instruction->base.value->special = ConstValSpecialStatic; - decl_var_instruction->base.value->type = irb->codegen->builtin_types.entry_void; - decl_var_instruction->var = var; - decl_var_instruction->align_value = align_value; - decl_var_instruction->ptr = ptr; + IrInstSrcDeclVar *inst = ir_build_instruction<IrInstSrcDeclVar>(irb, scope, source_node); + inst->var = var; + inst->align_value = align_value; + inst->ptr = ptr; if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); ir_ref_instruction(ptr, irb->current_basic_block); - return &decl_var_instruction->base; + return &inst->base; } -static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction, - ZigVar *var, IrInstruction *var_ptr) +static IrInstGen *ir_build_var_decl_gen(IrAnalyze *ira, IrInst *source_instruction, + ZigVar *var, IrInstGen *var_ptr) { - IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb, + IrInstGenDeclVar *inst = ir_build_inst_gen<IrInstGenDeclVar>(&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->var_ptr = var_ptr; + inst->base.value->special = ConstValSpecialStatic; + inst->base.value->type = ira->codegen->builtin_types.entry_void; + inst->var = var; + inst->var_ptr = var_ptr; - ir_ref_instruction(var_ptr, ira->new_irb.current_basic_block); + ir_ref_inst_gen(var_ptr, ira->new_irb.current_basic_block); - return &decl_var_instruction->base; + return &inst->base; } -static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction, - IrInstruction *operand, ZigType *ty, IrInstruction *result_loc) +static IrInstGen *ir_build_resize_slice(IrAnalyze *ira, IrInst *source_instruction, + IrInstGen *operand, ZigType *ty, IrInstGen *result_loc) { - IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb, + IrInstGenResizeSlice *instruction = ir_build_inst_gen<IrInstGenResizeSlice>(&ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = ty; instruction->operand = operand; instruction->result_loc = result_loc; - ir_ref_instruction(operand, ira->new_irb.current_basic_block); - if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); + ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); + if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_export(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *target, IrInstruction *options) +static IrInstSrc *ir_build_export(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *target, IrInstSrc *options) { - IrInstructionExport *export_instruction = ir_build_instruction<IrInstructionExport>( + IrInstSrcExport *export_instruction = ir_build_instruction<IrInstSrcExport>( irb, scope, source_node); - export_instruction->base.value->special = ConstValSpecialStatic; - export_instruction->base.value->type = irb->codegen->builtin_types.entry_void; export_instruction->target = target; export_instruction->options = options; @@ -2242,8 +2809,8 @@ static IrInstruction *ir_build_export(IrBuilder *irb, Scope *scope, AstNode *sou return &export_instruction->base; } -static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { - IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, scope, source_node); +static IrInstSrc *ir_build_load_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *ptr) { + IrInstSrcLoadPtr *instruction = ir_build_instruction<IrInstSrcLoadPtr>(irb, scope, source_node); instruction->ptr = ptr; ir_ref_instruction(ptr, irb->current_basic_block); @@ -2251,8 +2818,23 @@ static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { - IrInstructionTypeOf *instruction = ir_build_instruction<IrInstructionTypeOf>(irb, scope, source_node); +static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instruction, + IrInstGen *ptr, ZigType *ty, IrInstGen *result_loc) +{ + IrInstGenLoadPtr *instruction = ir_build_inst_gen<IrInstGenLoadPtr>( + &ira->new_irb, source_instruction->scope, source_instruction->source_node); + instruction->base.value->type = ty; + instruction->ptr = ptr; + instruction->result_loc = result_loc; + + ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); + if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_typeof(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { + IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node); instruction->value = value; ir_ref_instruction(value, irb->current_basic_block); @@ -2260,8 +2842,8 @@ static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *sou return &instruction->base; } -static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) { - IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node); +static IrInstSrc *ir_build_set_cold(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_cold) { + IrInstSrcSetCold *instruction = ir_build_instruction<IrInstSrcSetCold>(irb, scope, source_node); instruction->is_cold = is_cold; ir_ref_instruction(is_cold, irb->current_basic_block); @@ -2269,21 +2851,21 @@ static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_set_runtime_safety(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *safety_on) +static IrInstSrc *ir_build_set_runtime_safety(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *safety_on) { - IrInstructionSetRuntimeSafety *instruction = ir_build_instruction<IrInstructionSetRuntimeSafety>(irb, scope, source_node); - instruction->safety_on = safety_on; + IrInstSrcSetRuntimeSafety *inst = ir_build_instruction<IrInstSrcSetRuntimeSafety>(irb, scope, source_node); + inst->safety_on = safety_on; ir_ref_instruction(safety_on, irb->current_basic_block); - return &instruction->base; + return &inst->base; } -static IrInstruction *ir_build_set_float_mode(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *mode_value) +static IrInstSrc *ir_build_set_float_mode(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *mode_value) { - IrInstructionSetFloatMode *instruction = ir_build_instruction<IrInstructionSetFloatMode>(irb, scope, source_node); + IrInstSrcSetFloatMode *instruction = ir_build_instruction<IrInstSrcSetFloatMode>(irb, scope, source_node); instruction->mode_value = mode_value; ir_ref_instruction(mode_value, irb->current_basic_block); @@ -2291,10 +2873,10 @@ static IrInstruction *ir_build_set_float_mode(IrBuilder *irb, Scope *scope, AstN return &instruction->base; } -static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *size, - IrInstruction *sentinel, IrInstruction *child_type) +static IrInstSrc *ir_build_array_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *size, + IrInstSrc *sentinel, IrInstSrc *child_type) { - IrInstructionArrayType *instruction = ir_build_instruction<IrInstructionArrayType>(irb, scope, source_node); + IrInstSrcArrayType *instruction = ir_build_instruction<IrInstSrcArrayType>(irb, scope, source_node); instruction->size = size; instruction->sentinel = sentinel; instruction->child_type = child_type; @@ -2306,10 +2888,10 @@ static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_anyframe_type(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *payload_type) +static IrInstSrc *ir_build_anyframe_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *payload_type) { - IrInstructionAnyFrameType *instruction = ir_build_instruction<IrInstructionAnyFrameType>(irb, scope, source_node); + IrInstSrcAnyFrameType *instruction = ir_build_instruction<IrInstSrcAnyFrameType>(irb, scope, source_node); instruction->payload_type = payload_type; if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block); @@ -2317,11 +2899,11 @@ static IrInstruction *ir_build_anyframe_type(IrBuilder *irb, Scope *scope, AstNo return &instruction->base; } -static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *child_type, bool is_const, bool is_volatile, - IrInstruction *sentinel, IrInstruction *align_value, bool is_allow_zero) +static IrInstSrc *ir_build_slice_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *child_type, bool is_const, bool is_volatile, + IrInstSrc *sentinel, IrInstSrc *align_value, bool is_allow_zero) { - IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, scope, source_node); + IrInstSrcSliceType *instruction = ir_build_instruction<IrInstSrcSliceType>(irb, scope, source_node); instruction->is_const = is_const; instruction->is_volatile = is_volatile; instruction->child_type = child_type; @@ -2336,11 +2918,11 @@ static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_asm_src(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *asm_template, IrInstruction **input_list, IrInstruction **output_types, +static IrInstSrc *ir_build_asm_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *asm_template, IrInstSrc **input_list, IrInstSrc **output_types, ZigVar **output_vars, size_t return_count, bool has_side_effects, bool is_global) { - IrInstructionAsmSrc *instruction = ir_build_instruction<IrInstructionAsmSrc>(irb, scope, source_node); + IrInstSrcAsm *instruction = ir_build_instruction<IrInstSrcAsm>(irb, scope, source_node); instruction->asm_template = asm_template; instruction->input_list = input_list; instruction->output_types = output_types; @@ -2351,24 +2933,25 @@ static IrInstruction *ir_build_asm_src(IrBuilder *irb, Scope *scope, AstNode *so assert(source_node->type == NodeTypeAsmExpr); for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) { - IrInstruction *output_type = output_types[i]; + IrInstSrc *output_type = output_types[i]; if (output_type) ir_ref_instruction(output_type, irb->current_basic_block); } for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) { - IrInstruction *input_value = input_list[i]; + IrInstSrc *input_value = input_list[i]; ir_ref_instruction(input_value, irb->current_basic_block); } return &instruction->base; } -static IrInstruction *ir_build_asm_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, +static IrInstGen *ir_build_asm_gen(IrAnalyze *ira, IrInst *source_instr, Buf *asm_template, AsmToken *token_list, size_t token_list_len, - IrInstruction **input_list, IrInstruction **output_types, ZigVar **output_vars, size_t return_count, - bool has_side_effects) + IrInstGen **input_list, IrInstGen **output_types, ZigVar **output_vars, size_t return_count, + bool has_side_effects, ZigType *return_type) { - IrInstructionAsmGen *instruction = ir_build_instruction<IrInstructionAsmGen>(&ira->new_irb, scope, source_node); + IrInstGenAsm *instruction = ir_build_inst_gen<IrInstGenAsm>(&ira->new_irb, source_instr->scope, source_instr->source_node); + instruction->base.value->type = return_type; instruction->asm_template = asm_template; instruction->token_list = token_list; instruction->token_list_len = token_list_len; @@ -2378,22 +2961,24 @@ static IrInstruction *ir_build_asm_gen(IrAnalyze *ira, Scope *scope, AstNode *so instruction->return_count = return_count; instruction->has_side_effects = has_side_effects; - assert(source_node->type == NodeTypeAsmExpr); - for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) { - IrInstruction *output_type = output_types[i]; - if (output_type) ir_ref_instruction(output_type, ira->new_irb.current_basic_block); + assert(source_instr->source_node->type == NodeTypeAsmExpr); + for (size_t i = 0; i < source_instr->source_node->data.asm_expr.output_list.length; i += 1) { + IrInstGen *output_type = output_types[i]; + if (output_type) ir_ref_inst_gen(output_type, ira->new_irb.current_basic_block); } - for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) { - IrInstruction *input_value = input_list[i]; - ir_ref_instruction(input_value, ira->new_irb.current_basic_block); + for (size_t i = 0; i < source_instr->source_node->data.asm_expr.input_list.length; i += 1) { + IrInstGen *input_value = input_list[i]; + ir_ref_inst_gen(input_value, ira->new_irb.current_basic_block); } return &instruction->base; } -static IrInstruction *ir_build_size_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value, bool bit_size) { - IrInstructionSizeOf *instruction = ir_build_instruction<IrInstructionSizeOf>(irb, scope, source_node); +static IrInstSrc *ir_build_size_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value, + bool bit_size) +{ + IrInstSrcSizeOf *instruction = ir_build_instruction<IrInstSrcSizeOf>(irb, scope, source_node); instruction->type_value = type_value; instruction->bit_size = bit_size; @@ -2402,8 +2987,10 @@ static IrInstruction *ir_build_size_of(IrBuilder *irb, Scope *scope, AstNode *so return &instruction->base; } -static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { - IrInstructionTestNonNull *instruction = ir_build_instruction<IrInstructionTestNonNull>(irb, scope, source_node); +static IrInstSrc *ir_build_test_non_null_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *value) +{ + IrInstSrcTestNonNull *instruction = ir_build_instruction<IrInstSrcTestNonNull>(irb, scope, source_node); instruction->value = value; ir_ref_instruction(value, irb->current_basic_block); @@ -2411,10 +2998,21 @@ static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNod return &instruction->base; } -static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *base_ptr, bool safety_check_on, bool initializing) +static IrInstGen *ir_build_test_non_null_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) { + IrInstGenTestNonNull *inst = ir_build_inst_gen<IrInstGenTestNonNull>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + inst->base.value->type = ira->codegen->builtin_types.entry_bool; + inst->value = value; + + ir_ref_inst_gen(value, ira->new_irb.current_basic_block); + + return &inst->base; +} + +static IrInstSrc *ir_build_optional_unwrap_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *base_ptr, bool safety_check_on, bool initializing) { - IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node); + IrInstSrcOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstSrcOptionalUnwrapPtr>(irb, scope, source_node); instruction->base_ptr = base_ptr; instruction->safety_check_on = safety_check_on; instruction->initializing = initializing; @@ -2424,113 +3022,198 @@ static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, return &instruction->base; } -static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_ty, - IrInstruction *operand, IrInstruction *result_loc) +static IrInstGen *ir_build_optional_unwrap_ptr_gen(IrAnalyze *ira, IrInst *source_instr, + IrInstGen *base_ptr, bool safety_check_on, bool initializing, ZigType *result_type) { - IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>( + IrInstGenOptionalUnwrapPtr *inst = ir_build_inst_gen<IrInstGenOptionalUnwrapPtr>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + inst->base.value->type = result_type; + inst->base_ptr = base_ptr; + inst->safety_check_on = safety_check_on; + inst->initializing = initializing; + + ir_ref_inst_gen(base_ptr, ira->new_irb.current_basic_block); + + return &inst->base; +} + +static IrInstGen *ir_build_optional_wrap(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_ty, + IrInstGen *operand, IrInstGen *result_loc) +{ + IrInstGenOptionalWrap *instruction = ir_build_inst_gen<IrInstGenOptionalWrap>( &ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = result_ty; instruction->operand = operand; instruction->result_loc = result_loc; - ir_ref_instruction(operand, ira->new_irb.current_basic_block); - if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); + ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); + if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instruction, - ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) +static IrInstGen *ir_build_err_wrap_payload(IrAnalyze *ira, IrInst *source_instruction, + ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc) { - IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>( + IrInstGenErrWrapPayload *instruction = ir_build_inst_gen<IrInstGenErrWrapPayload>( &ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = result_type; instruction->operand = operand; instruction->result_loc = result_loc; - ir_ref_instruction(operand, ira->new_irb.current_basic_block); - if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); + ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); + if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instruction, - ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) +static IrInstGen *ir_build_err_wrap_code(IrAnalyze *ira, IrInst *source_instruction, + ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc) { - IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>( + IrInstGenErrWrapCode *instruction = ir_build_inst_gen<IrInstGenErrWrapCode>( &ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = result_type; instruction->operand = operand; instruction->result_loc = result_loc; - ir_ref_instruction(operand, ira->new_irb.current_basic_block); - if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); + ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); + if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { - IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, scope, source_node); +static IrInstSrc *ir_build_clz(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, + IrInstSrc *op) +{ + IrInstSrcClz *instruction = ir_build_instruction<IrInstSrcClz>(irb, scope, source_node); instruction->type = type; instruction->op = op; - if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); + ir_ref_instruction(type, irb->current_basic_block); ir_ref_instruction(op, irb->current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { - IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, scope, source_node); +static IrInstGen *ir_build_clz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) { + IrInstGenClz *instruction = ir_build_inst_gen<IrInstGenClz>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = result_type; + instruction->op = op; + + ir_ref_inst_gen(op, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_ctz(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, + IrInstSrc *op) +{ + IrInstSrcCtz *instruction = ir_build_instruction<IrInstSrcCtz>(irb, scope, source_node); instruction->type = type; instruction->op = op; - if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); + ir_ref_instruction(type, irb->current_basic_block); ir_ref_instruction(op, irb->current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { - IrInstructionPopCount *instruction = ir_build_instruction<IrInstructionPopCount>(irb, scope, source_node); +static IrInstGen *ir_build_ctz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) { + IrInstGenCtz *instruction = ir_build_inst_gen<IrInstGenCtz>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = result_type; + instruction->op = op; + + ir_ref_inst_gen(op, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_pop_count(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, + IrInstSrc *op) +{ + IrInstSrcPopCount *instruction = ir_build_instruction<IrInstSrcPopCount>(irb, scope, source_node); instruction->type = type; instruction->op = op; - if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); + ir_ref_instruction(type, irb->current_basic_block); ir_ref_instruction(op, irb->current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { - IrInstructionBswap *instruction = ir_build_instruction<IrInstructionBswap>(irb, scope, source_node); +static IrInstGen *ir_build_pop_count_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, + IrInstGen *op) +{ + IrInstGenPopCount *instruction = ir_build_inst_gen<IrInstGenPopCount>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = result_type; + instruction->op = op; + + ir_ref_inst_gen(op, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_bswap(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, + IrInstSrc *op) +{ + IrInstSrcBswap *instruction = ir_build_instruction<IrInstSrcBswap>(irb, scope, source_node); instruction->type = type; instruction->op = op; - if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); + ir_ref_instruction(type, irb->current_basic_block); ir_ref_instruction(op, irb->current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_bit_reverse(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { - IrInstructionBitReverse *instruction = ir_build_instruction<IrInstructionBitReverse>(irb, scope, source_node); +static IrInstGen *ir_build_bswap_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *op_type, + IrInstGen *op) +{ + IrInstGenBswap *instruction = ir_build_inst_gen<IrInstGenBswap>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = op_type; + instruction->op = op; + + ir_ref_inst_gen(op, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_bit_reverse(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, + IrInstSrc *op) +{ + IrInstSrcBitReverse *instruction = ir_build_instruction<IrInstSrcBitReverse>(irb, scope, source_node); instruction->type = type; instruction->op = op; - if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); + ir_ref_instruction(type, irb->current_basic_block); ir_ref_instruction(op, irb->current_basic_block); return &instruction->base; } -static IrInstructionSwitchBr *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value, - IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime, - IrInstruction *switch_prongs_void) +static IrInstGen *ir_build_bit_reverse_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *int_type, + IrInstGen *op) { - IrInstructionSwitchBr *instruction = ir_build_instruction<IrInstructionSwitchBr>(irb, scope, source_node); - instruction->base.value->type = irb->codegen->builtin_types.entry_unreachable; - instruction->base.value->special = ConstValSpecialStatic; + IrInstGenBitReverse *instruction = ir_build_inst_gen<IrInstGenBitReverse>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = int_type; + instruction->op = op; + + ir_ref_inst_gen(op, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrcSwitchBr *ir_build_switch_br_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *target_value, IrBasicBlockSrc *else_block, size_t case_count, IrInstSrcSwitchBrCase *cases, + IrInstSrc *is_comptime, IrInstSrc *switch_prongs_void) +{ + IrInstSrcSwitchBr *instruction = ir_build_instruction<IrInstSrcSwitchBr>(irb, scope, source_node); + instruction->base.is_noreturn = true; instruction->target_value = target_value; instruction->else_block = else_block; instruction->case_count = case_count; @@ -2539,9 +3222,9 @@ static IrInstructionSwitchBr *ir_build_switch_br(IrBuilder *irb, Scope *scope, A instruction->switch_prongs_void = switch_prongs_void; ir_ref_instruction(target_value, irb->current_basic_block); - if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); + ir_ref_instruction(is_comptime, irb->current_basic_block); ir_ref_bb(else_block); - if (switch_prongs_void) ir_ref_instruction(switch_prongs_void, irb->current_basic_block); + ir_ref_instruction(switch_prongs_void, irb->current_basic_block); for (size_t i = 0; i < case_count; i += 1) { ir_ref_instruction(cases[i].value, irb->current_basic_block); @@ -2551,10 +3234,31 @@ static IrInstructionSwitchBr *ir_build_switch_br(IrBuilder *irb, Scope *scope, A return instruction; } -static IrInstruction *ir_build_switch_target(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *target_value_ptr) +static IrInstGenSwitchBr *ir_build_switch_br_gen(IrAnalyze *ira, IrInst *source_instr, + IrInstGen *target_value, IrBasicBlockGen *else_block, size_t case_count, IrInstGenSwitchBrCase *cases) { - IrInstructionSwitchTarget *instruction = ir_build_instruction<IrInstructionSwitchTarget>(irb, scope, source_node); + IrInstGenSwitchBr *instruction = ir_build_inst_noreturn<IrInstGenSwitchBr>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->target_value = target_value; + instruction->else_block = else_block; + instruction->case_count = case_count; + instruction->cases = cases; + + ir_ref_inst_gen(target_value, ira->new_irb.current_basic_block); + ir_ref_bb_gen(else_block); + + for (size_t i = 0; i < case_count; i += 1) { + ir_ref_inst_gen(cases[i].value, ira->new_irb.current_basic_block); + ir_ref_bb_gen(cases[i].block); + } + + return instruction; +} + +static IrInstSrc *ir_build_switch_target(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *target_value_ptr) +{ + IrInstSrcSwitchTarget *instruction = ir_build_instruction<IrInstSrcSwitchTarget>(irb, scope, source_node); instruction->target_value_ptr = target_value_ptr; ir_ref_instruction(target_value_ptr, irb->current_basic_block); @@ -2562,10 +3266,10 @@ static IrInstruction *ir_build_switch_target(IrBuilder *irb, Scope *scope, AstNo return &instruction->base; } -static IrInstruction *ir_build_switch_var(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *target_value_ptr, IrInstruction **prongs_ptr, size_t prongs_len) +static IrInstSrc *ir_build_switch_var(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *target_value_ptr, IrInstSrc **prongs_ptr, size_t prongs_len) { - IrInstructionSwitchVar *instruction = ir_build_instruction<IrInstructionSwitchVar>(irb, scope, source_node); + IrInstSrcSwitchVar *instruction = ir_build_instruction<IrInstSrcSwitchVar>(irb, scope, source_node); instruction->target_value_ptr = target_value_ptr; instruction->prongs_ptr = prongs_ptr; instruction->prongs_len = prongs_len; @@ -2579,10 +3283,10 @@ static IrInstruction *ir_build_switch_var(IrBuilder *irb, Scope *scope, AstNode } // For this instruction the switch_br must be set later. -static IrInstructionSwitchElseVar *ir_build_switch_else_var(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *target_value_ptr) +static IrInstSrcSwitchElseVar *ir_build_switch_else_var(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *target_value_ptr) { - IrInstructionSwitchElseVar *instruction = ir_build_instruction<IrInstructionSwitchElseVar>(irb, scope, source_node); + IrInstSrcSwitchElseVar *instruction = ir_build_instruction<IrInstSrcSwitchElseVar>(irb, scope, source_node); instruction->target_value_ptr = target_value_ptr; ir_ref_instruction(target_value_ptr, irb->current_basic_block); @@ -2590,17 +3294,21 @@ static IrInstructionSwitchElseVar *ir_build_switch_else_var(IrBuilder *irb, Scop return instruction; } -static IrInstruction *ir_build_union_tag(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { - IrInstructionUnionTag *instruction = ir_build_instruction<IrInstructionUnionTag>(irb, scope, source_node); +static IrInstGen *ir_build_union_tag(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, + ZigType *tag_type) +{ + IrInstGenUnionTag *instruction = ir_build_inst_gen<IrInstGenUnionTag>(&ira->new_irb, + source_instr->scope, source_instr->source_node); instruction->value = value; + instruction->base.value->type = tag_type; - ir_ref_instruction(value, irb->current_basic_block); + ir_ref_inst_gen(value, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_import(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { - IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, scope, source_node); +static IrInstSrc *ir_build_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { + IrInstSrcImport *instruction = ir_build_instruction<IrInstSrcImport>(irb, scope, source_node); instruction->name = name; ir_ref_instruction(name, irb->current_basic_block); @@ -2608,10 +3316,10 @@ static IrInstruction *ir_build_import(IrBuilder *irb, Scope *scope, AstNode *sou return &instruction->base; } -static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value, +static IrInstSrc *ir_build_ref_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value, bool is_const, bool is_volatile) { - IrInstructionRef *instruction = ir_build_instruction<IrInstructionRef>(irb, scope, source_node); + IrInstSrcRef *instruction = ir_build_instruction<IrInstSrcRef>(irb, scope, source_node); instruction->value = value; instruction->is_const = is_const; instruction->is_volatile = is_volatile; @@ -2621,23 +3329,23 @@ static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source return &instruction->base; } -static IrInstruction *ir_build_ref_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, - IrInstruction *operand, IrInstruction *result_loc) +static IrInstGen *ir_build_ref_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type, + IrInstGen *operand, IrInstGen *result_loc) { - IrInstructionRefGen *instruction = ir_build_instruction<IrInstructionRefGen>(&ira->new_irb, + IrInstGenRef *instruction = ir_build_inst_gen<IrInstGenRef>(&ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = result_type; instruction->operand = operand; instruction->result_loc = result_loc; - ir_ref_instruction(operand, ira->new_irb.current_basic_block); - if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); + ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); + if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { - IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node); +static IrInstSrc *ir_build_compile_err(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *msg) { + IrInstSrcCompileErr *instruction = ir_build_instruction<IrInstSrcCompileErr>(irb, scope, source_node); instruction->msg = msg; ir_ref_instruction(msg, irb->current_basic_block); @@ -2645,10 +3353,10 @@ static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_compile_log(IrBuilder *irb, Scope *scope, AstNode *source_node, - size_t msg_count, IrInstruction **msg_list) +static IrInstSrc *ir_build_compile_log(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + size_t msg_count, IrInstSrc **msg_list) { - IrInstructionCompileLog *instruction = ir_build_instruction<IrInstructionCompileLog>(irb, scope, source_node); + IrInstSrcCompileLog *instruction = ir_build_instruction<IrInstSrcCompileLog>(irb, scope, source_node); instruction->msg_count = msg_count; instruction->msg_list = msg_list; @@ -2659,8 +3367,8 @@ static IrInstruction *ir_build_compile_log(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_err_name(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { - IrInstructionErrName *instruction = ir_build_instruction<IrInstructionErrName>(irb, scope, source_node); +static IrInstSrc *ir_build_err_name(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { + IrInstSrcErrName *instruction = ir_build_instruction<IrInstSrcErrName>(irb, scope, source_node); instruction->value = value; ir_ref_instruction(value, irb->current_basic_block); @@ -2668,13 +3376,26 @@ static IrInstruction *ir_build_err_name(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_c_import(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionCImport *instruction = ir_build_instruction<IrInstructionCImport>(irb, scope, source_node); +static IrInstGen *ir_build_err_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, + ZigType *str_type) +{ + IrInstGenErrName *instruction = ir_build_inst_gen<IrInstGenErrName>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = str_type; + instruction->value = value; + + ir_ref_inst_gen(value, ira->new_irb.current_basic_block); + return &instruction->base; } -static IrInstruction *ir_build_c_include(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { - IrInstructionCInclude *instruction = ir_build_instruction<IrInstructionCInclude>(irb, scope, source_node); +static IrInstSrc *ir_build_c_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { + IrInstSrcCImport *instruction = ir_build_instruction<IrInstSrcCImport>(irb, scope, source_node); + return &instruction->base; +} + +static IrInstSrc *ir_build_c_include(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { + IrInstSrcCInclude *instruction = ir_build_instruction<IrInstSrcCInclude>(irb, scope, source_node); instruction->name = name; ir_ref_instruction(name, irb->current_basic_block); @@ -2682,8 +3403,8 @@ static IrInstruction *ir_build_c_include(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } -static IrInstruction *ir_build_c_define(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name, IrInstruction *value) { - IrInstructionCDefine *instruction = ir_build_instruction<IrInstructionCDefine>(irb, scope, source_node); +static IrInstSrc *ir_build_c_define(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name, IrInstSrc *value) { + IrInstSrcCDefine *instruction = ir_build_instruction<IrInstSrcCDefine>(irb, scope, source_node); instruction->name = name; instruction->value = value; @@ -2693,8 +3414,8 @@ static IrInstruction *ir_build_c_define(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_c_undef(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { - IrInstructionCUndef *instruction = ir_build_instruction<IrInstructionCUndef>(irb, scope, source_node); +static IrInstSrc *ir_build_c_undef(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { + IrInstSrcCUndef *instruction = ir_build_instruction<IrInstSrcCUndef>(irb, scope, source_node); instruction->name = name; ir_ref_instruction(name, irb->current_basic_block); @@ -2702,8 +3423,8 @@ static IrInstruction *ir_build_c_undef(IrBuilder *irb, Scope *scope, AstNode *so return &instruction->base; } -static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { - IrInstructionEmbedFile *instruction = ir_build_instruction<IrInstructionEmbedFile>(irb, scope, source_node); +static IrInstSrc *ir_build_embed_file(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { + IrInstSrcEmbedFile *instruction = ir_build_instruction<IrInstSrcEmbedFile>(irb, scope, source_node); instruction->name = name; ir_ref_instruction(name, irb->current_basic_block); @@ -2711,11 +3432,11 @@ static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, - IrInstruction *success_order_value, IrInstruction *failure_order_value, bool is_weak, ResultLoc *result_loc) +static IrInstSrc *ir_build_cmpxchg_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *type_value, IrInstSrc *ptr, IrInstSrc *cmp_value, IrInstSrc *new_value, + IrInstSrc *success_order_value, IrInstSrc *failure_order_value, bool is_weak, ResultLoc *result_loc) { - IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node); + IrInstSrcCmpxchg *instruction = ir_build_instruction<IrInstSrcCmpxchg>(irb, scope, source_node); instruction->type_value = type_value; instruction->ptr = ptr; instruction->cmp_value = cmp_value; @@ -2735,11 +3456,11 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, - IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, - AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstruction *result_loc) +static IrInstGen *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type, + IrInstGen *ptr, IrInstGen *cmp_value, IrInstGen *new_value, + AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstGen *result_loc) { - IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb, + IrInstGenCmpxchg *instruction = ir_build_inst_gen<IrInstGenCmpxchg>(&ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = result_type; instruction->ptr = ptr; @@ -2750,26 +3471,35 @@ static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source instruction->is_weak = is_weak; instruction->result_loc = result_loc; - ir_ref_instruction(ptr, ira->new_irb.current_basic_block); - ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block); - ir_ref_instruction(new_value, ira->new_irb.current_basic_block); - if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); + ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); + ir_ref_inst_gen(cmp_value, ira->new_irb.current_basic_block); + ir_ref_inst_gen(new_value, ira->new_irb.current_basic_block); + if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_fence(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *order_value, AtomicOrder order) { - IrInstructionFence *instruction = ir_build_instruction<IrInstructionFence>(irb, scope, source_node); - instruction->order_value = order_value; +static IrInstSrc *ir_build_fence(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *order) { + IrInstSrcFence *instruction = ir_build_instruction<IrInstSrcFence>(irb, scope, source_node); instruction->order = order; - ir_ref_instruction(order_value, irb->current_basic_block); + ir_ref_instruction(order, irb->current_basic_block); + + return &instruction->base; +} + +static IrInstGen *ir_build_fence_gen(IrAnalyze *ira, IrInst *source_instr, AtomicOrder order) { + IrInstGenFence *instruction = ir_build_inst_void<IrInstGenFence>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->order = order; return &instruction->base; } -static IrInstruction *ir_build_truncate(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { - IrInstructionTruncate *instruction = ir_build_instruction<IrInstructionTruncate>(irb, scope, source_node); +static IrInstSrc *ir_build_truncate(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *dest_type, IrInstSrc *target) +{ + IrInstSrcTruncate *instruction = ir_build_instruction<IrInstSrcTruncate>(irb, scope, source_node); instruction->dest_type = dest_type; instruction->target = target; @@ -2779,8 +3509,23 @@ static IrInstruction *ir_build_truncate(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_int_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { - IrInstructionIntCast *instruction = ir_build_instruction<IrInstructionIntCast>(irb, scope, source_node); +static IrInstGen *ir_build_truncate_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *dest_type, + IrInstGen *target) +{ + IrInstGenTruncate *instruction = ir_build_inst_gen<IrInstGenTruncate>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = dest_type; + instruction->target = target; + + ir_ref_inst_gen(target, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_int_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *dest_type, + IrInstSrc *target) +{ + IrInstSrcIntCast *instruction = ir_build_instruction<IrInstSrcIntCast>(irb, scope, source_node); instruction->dest_type = dest_type; instruction->target = target; @@ -2790,8 +3535,10 @@ static IrInstruction *ir_build_int_cast(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_float_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { - IrInstructionFloatCast *instruction = ir_build_instruction<IrInstructionFloatCast>(irb, scope, source_node); +static IrInstSrc *ir_build_float_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *dest_type, + IrInstSrc *target) +{ + IrInstSrcFloatCast *instruction = ir_build_instruction<IrInstSrcFloatCast>(irb, scope, source_node); instruction->dest_type = dest_type; instruction->target = target; @@ -2801,8 +3548,10 @@ static IrInstruction *ir_build_float_cast(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { - IrInstructionErrSetCast *instruction = ir_build_instruction<IrInstructionErrSetCast>(irb, scope, source_node); +static IrInstSrc *ir_build_err_set_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *dest_type, IrInstSrc *target) +{ + IrInstSrcErrSetCast *instruction = ir_build_instruction<IrInstSrcErrSetCast>(irb, scope, source_node); instruction->dest_type = dest_type; instruction->target = target; @@ -2812,10 +3561,10 @@ static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNod return &instruction->base; } -static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target, +static IrInstSrc *ir_build_to_bytes(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target, ResultLoc *result_loc) { - IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node); + IrInstSrcToBytes *instruction = ir_build_instruction<IrInstSrcToBytes>(irb, scope, source_node); instruction->target = target; instruction->result_loc = result_loc; @@ -2824,10 +3573,10 @@ static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *dest_child_type, IrInstruction *target, ResultLoc *result_loc) +static IrInstSrc *ir_build_from_bytes(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *dest_child_type, IrInstSrc *target, ResultLoc *result_loc) { - IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node); + IrInstSrcFromBytes *instruction = ir_build_instruction<IrInstSrcFromBytes>(irb, scope, source_node); instruction->dest_child_type = dest_child_type; instruction->target = target; instruction->result_loc = result_loc; @@ -2838,8 +3587,10 @@ static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { - IrInstructionIntToFloat *instruction = ir_build_instruction<IrInstructionIntToFloat>(irb, scope, source_node); +static IrInstSrc *ir_build_int_to_float(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *dest_type, IrInstSrc *target) +{ + IrInstSrcIntToFloat *instruction = ir_build_instruction<IrInstSrcIntToFloat>(irb, scope, source_node); instruction->dest_type = dest_type; instruction->target = target; @@ -2849,8 +3600,10 @@ static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNod return &instruction->base; } -static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { - IrInstructionFloatToInt *instruction = ir_build_instruction<IrInstructionFloatToInt>(irb, scope, source_node); +static IrInstSrc *ir_build_float_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *dest_type, IrInstSrc *target) +{ + IrInstSrcFloatToInt *instruction = ir_build_instruction<IrInstSrcFloatToInt>(irb, scope, source_node); instruction->dest_type = dest_type; instruction->target = target; @@ -2860,8 +3613,8 @@ static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNod return &instruction->base; } -static IrInstruction *ir_build_bool_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) { - IrInstructionBoolToInt *instruction = ir_build_instruction<IrInstructionBoolToInt>(irb, scope, source_node); +static IrInstSrc *ir_build_bool_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target) { + IrInstSrcBoolToInt *instruction = ir_build_instruction<IrInstSrcBoolToInt>(irb, scope, source_node); instruction->target = target; ir_ref_instruction(target, irb->current_basic_block); @@ -2869,8 +3622,10 @@ static IrInstruction *ir_build_bool_to_int(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) { - IrInstructionIntType *instruction = ir_build_instruction<IrInstructionIntType>(irb, scope, source_node); +static IrInstSrc *ir_build_int_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_signed, + IrInstSrc *bit_count) +{ + IrInstSrcIntType *instruction = ir_build_instruction<IrInstSrcIntType>(irb, scope, source_node); instruction->is_signed = is_signed; instruction->bit_count = bit_count; @@ -2880,10 +3635,10 @@ static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_vector_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *len, - IrInstruction *elem_type) +static IrInstSrc *ir_build_vector_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *len, + IrInstSrc *elem_type) { - IrInstructionVectorType *instruction = ir_build_instruction<IrInstructionVectorType>(irb, scope, source_node); + IrInstSrcVectorType *instruction = ir_build_instruction<IrInstSrcVectorType>(irb, scope, source_node); instruction->len = len; instruction->elem_type = elem_type; @@ -2893,18 +3648,16 @@ static IrInstruction *ir_build_vector_type(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_shuffle_vector(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *scalar_type, IrInstruction *a, IrInstruction *b, IrInstruction *mask) +static IrInstSrc *ir_build_shuffle_vector(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *scalar_type, IrInstSrc *a, IrInstSrc *b, IrInstSrc *mask) { - IrInstructionShuffleVector *instruction = ir_build_instruction<IrInstructionShuffleVector>(irb, scope, source_node); + IrInstSrcShuffleVector *instruction = ir_build_instruction<IrInstSrcShuffleVector>(irb, scope, source_node); instruction->scalar_type = scalar_type; instruction->a = a; instruction->b = b; instruction->mask = mask; - if (scalar_type != nullptr) { - ir_ref_instruction(scalar_type, irb->current_basic_block); - } + if (scalar_type != nullptr) ir_ref_instruction(scalar_type, irb->current_basic_block); ir_ref_instruction(a, irb->current_basic_block); ir_ref_instruction(b, irb->current_basic_block); ir_ref_instruction(mask, irb->current_basic_block); @@ -2912,10 +3665,26 @@ static IrInstruction *ir_build_shuffle_vector(IrBuilder *irb, Scope *scope, AstN return &instruction->base; } -static IrInstruction *ir_build_splat_src(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *len, IrInstruction *scalar) +static IrInstGen *ir_build_shuffle_vector_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, + ZigType *result_type, IrInstGen *a, IrInstGen *b, IrInstGen *mask) +{ + IrInstGenShuffleVector *inst = ir_build_inst_gen<IrInstGenShuffleVector>(&ira->new_irb, scope, source_node); + inst->base.value->type = result_type; + inst->a = a; + inst->b = b; + inst->mask = mask; + + ir_ref_inst_gen(a, ira->new_irb.current_basic_block); + ir_ref_inst_gen(b, ira->new_irb.current_basic_block); + ir_ref_inst_gen(mask, ira->new_irb.current_basic_block); + + return &inst->base; +} + +static IrInstSrc *ir_build_splat_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *len, IrInstSrc *scalar) { - IrInstructionSplatSrc *instruction = ir_build_instruction<IrInstructionSplatSrc>(irb, scope, source_node); + IrInstSrcSplat *instruction = ir_build_instruction<IrInstSrcSplat>(irb, scope, source_node); instruction->len = len; instruction->scalar = scalar; @@ -2925,8 +3694,21 @@ static IrInstruction *ir_build_splat_src(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } -static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { - IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node); +static IrInstGen *ir_build_splat_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type, + IrInstGen *scalar) +{ + IrInstGenSplat *instruction = ir_build_inst_gen<IrInstGenSplat>( + &ira->new_irb, source_instruction->scope, source_instruction->source_node); + instruction->base.value->type = result_type; + instruction->scalar = scalar; + + ir_ref_inst_gen(scalar, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_bool_not(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { + IrInstSrcBoolNot *instruction = ir_build_instruction<IrInstSrcBoolNot>(irb, scope, source_node); instruction->value = value; ir_ref_instruction(value, irb->current_basic_block); @@ -2934,10 +3716,21 @@ static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_memset(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *dest_ptr, IrInstruction *byte, IrInstruction *count) +static IrInstGen *ir_build_bool_not_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) { + IrInstGenBoolNot *instruction = ir_build_inst_gen<IrInstGenBoolNot>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = ira->codegen->builtin_types.entry_bool; + instruction->value = value; + + ir_ref_inst_gen(value, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_memset_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *dest_ptr, IrInstSrc *byte, IrInstSrc *count) { - IrInstructionMemset *instruction = ir_build_instruction<IrInstructionMemset>(irb, scope, source_node); + IrInstSrcMemset *instruction = ir_build_instruction<IrInstSrcMemset>(irb, scope, source_node); instruction->dest_ptr = dest_ptr; instruction->byte = byte; instruction->count = count; @@ -2949,10 +3742,26 @@ static IrInstruction *ir_build_memset(IrBuilder *irb, Scope *scope, AstNode *sou return &instruction->base; } -static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *dest_ptr, IrInstruction *src_ptr, IrInstruction *count) +static IrInstGen *ir_build_memset_gen(IrAnalyze *ira, IrInst *source_instr, + IrInstGen *dest_ptr, IrInstGen *byte, IrInstGen *count) { - IrInstructionMemcpy *instruction = ir_build_instruction<IrInstructionMemcpy>(irb, scope, source_node); + IrInstGenMemset *instruction = ir_build_inst_void<IrInstGenMemset>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->dest_ptr = dest_ptr; + instruction->byte = byte; + instruction->count = count; + + ir_ref_inst_gen(dest_ptr, ira->new_irb.current_basic_block); + ir_ref_inst_gen(byte, ira->new_irb.current_basic_block); + ir_ref_inst_gen(count, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_memcpy_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *dest_ptr, IrInstSrc *src_ptr, IrInstSrc *count) +{ + IrInstSrcMemcpy *instruction = ir_build_instruction<IrInstSrcMemcpy>(irb, scope, source_node); instruction->dest_ptr = dest_ptr; instruction->src_ptr = src_ptr; instruction->count = count; @@ -2964,11 +3773,27 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou return &instruction->base; } -static IrInstruction *ir_build_slice_src(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *ptr, IrInstruction *start, IrInstruction *end, IrInstruction *sentinel, +static IrInstGen *ir_build_memcpy_gen(IrAnalyze *ira, IrInst *source_instr, + IrInstGen *dest_ptr, IrInstGen *src_ptr, IrInstGen *count) +{ + IrInstGenMemcpy *instruction = ir_build_inst_void<IrInstGenMemcpy>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->dest_ptr = dest_ptr; + instruction->src_ptr = src_ptr; + instruction->count = count; + + ir_ref_inst_gen(dest_ptr, ira->new_irb.current_basic_block); + ir_ref_inst_gen(src_ptr, ira->new_irb.current_basic_block); + ir_ref_inst_gen(count, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_slice_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *ptr, IrInstSrc *start, IrInstSrc *end, IrInstSrc *sentinel, bool safety_check_on, ResultLoc *result_loc) { - IrInstructionSliceSrc *instruction = ir_build_instruction<IrInstructionSliceSrc>(irb, scope, source_node); + IrInstSrcSlice *instruction = ir_build_instruction<IrInstSrcSlice>(irb, scope, source_node); instruction->ptr = ptr; instruction->start = start; instruction->end = end; @@ -2984,23 +3809,10 @@ static IrInstruction *ir_build_slice_src(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } -static IrInstruction *ir_build_splat_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type, - IrInstruction *scalar) +static IrInstGen *ir_build_slice_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *slice_type, + IrInstGen *ptr, IrInstGen *start, IrInstGen *end, bool safety_check_on, IrInstGen *result_loc) { - IrInstructionSplatGen *instruction = ir_build_instruction<IrInstructionSplatGen>( - &ira->new_irb, source_instruction->scope, source_instruction->source_node); - instruction->base.value->type = result_type; - instruction->scalar = scalar; - - ir_ref_instruction(scalar, ira->new_irb.current_basic_block); - - return &instruction->base; -} - -static IrInstruction *ir_build_slice_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *slice_type, - IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, IrInstruction *result_loc) -{ - IrInstructionSliceGen *instruction = ir_build_instruction<IrInstructionSliceGen>( + IrInstGenSlice *instruction = ir_build_inst_gen<IrInstGenSlice>( &ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = slice_type; instruction->ptr = ptr; @@ -3009,16 +3821,16 @@ static IrInstruction *ir_build_slice_gen(IrAnalyze *ira, IrInstruction *source_i instruction->safety_check_on = safety_check_on; instruction->result_loc = result_loc; - ir_ref_instruction(ptr, ira->new_irb.current_basic_block); - ir_ref_instruction(start, ira->new_irb.current_basic_block); - if (end) ir_ref_instruction(end, ira->new_irb.current_basic_block); - ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); + ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); + ir_ref_inst_gen(start, ira->new_irb.current_basic_block); + if (end) ir_ref_inst_gen(end, ira->new_irb.current_basic_block); + ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) { - IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node); +static IrInstSrc *ir_build_member_count(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *container) { + IrInstSrcMemberCount *instruction = ir_build_instruction<IrInstSrcMemberCount>(irb, scope, source_node); instruction->container = container; ir_ref_instruction(container, irb->current_basic_block); @@ -3026,10 +3838,10 @@ static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNod return &instruction->base; } -static IrInstruction *ir_build_member_type(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *container_type, IrInstruction *member_index) +static IrInstSrc *ir_build_member_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *container_type, IrInstSrc *member_index) { - IrInstructionMemberType *instruction = ir_build_instruction<IrInstructionMemberType>(irb, scope, source_node); + IrInstSrcMemberType *instruction = ir_build_instruction<IrInstSrcMemberType>(irb, scope, source_node); instruction->container_type = container_type; instruction->member_index = member_index; @@ -3039,10 +3851,10 @@ static IrInstruction *ir_build_member_type(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_member_name(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *container_type, IrInstruction *member_index) +static IrInstSrc *ir_build_member_name(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *container_type, IrInstSrc *member_index) { - IrInstructionMemberName *instruction = ir_build_instruction<IrInstructionMemberName>(irb, scope, source_node); + IrInstSrcMemberName *instruction = ir_build_instruction<IrInstSrcMemberName>(irb, scope, source_node); instruction->container_type = container_type; instruction->member_index = member_index; @@ -3052,65 +3864,88 @@ static IrInstruction *ir_build_member_name(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_breakpoint(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionBreakpoint *instruction = ir_build_instruction<IrInstructionBreakpoint>(irb, scope, source_node); +static IrInstSrc *ir_build_breakpoint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { + IrInstSrcBreakpoint *instruction = ir_build_instruction<IrInstSrcBreakpoint>(irb, scope, source_node); return &instruction->base; } -static IrInstruction *ir_build_return_address(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionReturnAddress *instruction = ir_build_instruction<IrInstructionReturnAddress>(irb, scope, source_node); +static IrInstGen *ir_build_breakpoint_gen(IrAnalyze *ira, IrInst *source_instr) { + IrInstGenBreakpoint *instruction = ir_build_inst_void<IrInstGenBreakpoint>(&ira->new_irb, + source_instr->scope, source_instr->source_node); return &instruction->base; } -static IrInstruction *ir_build_frame_address(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionFrameAddress *instruction = ir_build_instruction<IrInstructionFrameAddress>(irb, scope, source_node); +static IrInstSrc *ir_build_return_address_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { + IrInstSrcReturnAddress *instruction = ir_build_instruction<IrInstSrcReturnAddress>(irb, scope, source_node); return &instruction->base; } -static IrInstruction *ir_build_handle(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionFrameHandle *instruction = ir_build_instruction<IrInstructionFrameHandle>(irb, scope, source_node); - return &instruction->base; +static IrInstGen *ir_build_return_address_gen(IrAnalyze *ira, IrInst *source_instr) { + IrInstGenReturnAddress *inst = ir_build_inst_gen<IrInstGenReturnAddress>(&ira->new_irb, source_instr->scope, source_instr->source_node); + inst->base.value->type = ira->codegen->builtin_types.entry_usize; + return &inst->base; +} + +static IrInstSrc *ir_build_frame_address_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { + IrInstSrcFrameAddress *inst = ir_build_instruction<IrInstSrcFrameAddress>(irb, scope, source_node); + return &inst->base; +} + +static IrInstGen *ir_build_frame_address_gen(IrAnalyze *ira, IrInst *source_instr) { + IrInstGenFrameAddress *inst = ir_build_inst_gen<IrInstGenFrameAddress>(&ira->new_irb, source_instr->scope, source_instr->source_node); + inst->base.value->type = ira->codegen->builtin_types.entry_usize; + return &inst->base; +} + +static IrInstSrc *ir_build_handle_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { + IrInstSrcFrameHandle *inst = ir_build_instruction<IrInstSrcFrameHandle>(irb, scope, source_node); + return &inst->base; +} + +static IrInstGen *ir_build_handle_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *ty) { + IrInstGenFrameHandle *inst = ir_build_inst_gen<IrInstGenFrameHandle>(&ira->new_irb, source_instr->scope, source_instr->source_node); + inst->base.value->type = ty; + return &inst->base; } -static IrInstruction *ir_build_frame_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn) { - IrInstructionFrameType *instruction = ir_build_instruction<IrInstructionFrameType>(irb, scope, source_node); - instruction->fn = fn; +static IrInstSrc *ir_build_frame_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *fn) { + IrInstSrcFrameType *inst = ir_build_instruction<IrInstSrcFrameType>(irb, scope, source_node); + inst->fn = fn; ir_ref_instruction(fn, irb->current_basic_block); - return &instruction->base; + return &inst->base; } -static IrInstruction *ir_build_frame_size_src(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn) { - IrInstructionFrameSizeSrc *instruction = ir_build_instruction<IrInstructionFrameSizeSrc>(irb, scope, source_node); - instruction->fn = fn; +static IrInstSrc *ir_build_frame_size_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *fn) { + IrInstSrcFrameSize *inst = ir_build_instruction<IrInstSrcFrameSize>(irb, scope, source_node); + inst->fn = fn; ir_ref_instruction(fn, irb->current_basic_block); - return &instruction->base; + return &inst->base; } -static IrInstruction *ir_build_frame_size_gen(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn) +static IrInstGen *ir_build_frame_size_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *fn) { - IrInstructionFrameSizeGen *instruction = ir_build_instruction<IrInstructionFrameSizeGen>(irb, scope, source_node); - instruction->fn = fn; + IrInstGenFrameSize *inst = ir_build_inst_gen<IrInstGenFrameSize>(&ira->new_irb, source_instr->scope, source_instr->source_node); + inst->base.value->type = ira->codegen->builtin_types.entry_usize; + inst->fn = fn; - ir_ref_instruction(fn, irb->current_basic_block); + ir_ref_inst_gen(fn, ira->new_irb.current_basic_block); - return &instruction->base; + return &inst->base; } -static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrOverflowOp op, IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2, - IrInstruction *result_ptr, ZigType *result_ptr_type) +static IrInstSrc *ir_build_overflow_op_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrOverflowOp op, IrInstSrc *type_value, IrInstSrc *op1, IrInstSrc *op2, IrInstSrc *result_ptr) { - IrInstructionOverflowOp *instruction = ir_build_instruction<IrInstructionOverflowOp>(irb, scope, source_node); + IrInstSrcOverflowOp *instruction = ir_build_instruction<IrInstSrcOverflowOp>(irb, scope, source_node); instruction->op = op; instruction->type_value = type_value; instruction->op1 = op1; instruction->op2 = op2; instruction->result_ptr = result_ptr; - instruction->result_ptr_type = result_ptr_type; ir_ref_instruction(type_value, irb->current_basic_block); ir_ref_instruction(op1, irb->current_basic_block); @@ -3120,49 +3955,30 @@ static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } +static IrInstGen *ir_build_overflow_op_gen(IrAnalyze *ira, IrInst *source_instr, + IrOverflowOp op, IrInstGen *op1, IrInstGen *op2, IrInstGen *result_ptr, + ZigType *result_ptr_type) +{ + IrInstGenOverflowOp *instruction = ir_build_inst_gen<IrInstGenOverflowOp>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = ira->codegen->builtin_types.entry_bool; + instruction->op = op; + instruction->op1 = op1; + instruction->op2 = op2; + instruction->result_ptr = result_ptr; + instruction->result_ptr_type = result_ptr_type; -//TODO Powi, Pow, minnum, maxnum, maximum, minimum, copysign, -// lround, llround, lrint, llrint -// So far this is only non-complicated type functions. -const char *float_op_to_name(BuiltinFnId op) { - switch (op) { - case BuiltinFnIdSqrt: - return "sqrt"; - case BuiltinFnIdSin: - return "sin"; - case BuiltinFnIdCos: - return "cos"; - case BuiltinFnIdExp: - return "exp"; - case BuiltinFnIdExp2: - return "exp2"; - case BuiltinFnIdLog: - return "log"; - case BuiltinFnIdLog10: - return "log10"; - case BuiltinFnIdLog2: - return "log2"; - case BuiltinFnIdFabs: - return "fabs"; - case BuiltinFnIdFloor: - return "floor"; - case BuiltinFnIdCeil: - return "ceil"; - case BuiltinFnIdTrunc: - return "trunc"; - case BuiltinFnIdNearbyInt: - return "nearbyint"; - case BuiltinFnIdRound: - return "round"; - default: - zig_unreachable(); - } + ir_ref_inst_gen(op1, ira->new_irb.current_basic_block); + ir_ref_inst_gen(op2, ira->new_irb.current_basic_block); + ir_ref_inst_gen(result_ptr, ira->new_irb.current_basic_block); + + return &instruction->base; } -static IrInstruction *ir_build_float_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *operand, +static IrInstSrc *ir_build_float_op_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *operand, BuiltinFnId fn_id) { - IrInstructionFloatOp *instruction = ir_build_instruction<IrInstructionFloatOp>(irb, scope, source_node); + IrInstSrcFloatOp *instruction = ir_build_instruction<IrInstSrcFloatOp>(irb, scope, source_node); instruction->operand = operand; instruction->fn_id = fn_id; @@ -3171,9 +3987,24 @@ static IrInstruction *ir_build_float_op(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_mul_add(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2, IrInstruction *op3) { - IrInstructionMulAdd *instruction = ir_build_instruction<IrInstructionMulAdd>(irb, scope, source_node); +static IrInstGen *ir_build_float_op_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, + BuiltinFnId fn_id, ZigType *operand_type) +{ + IrInstGenFloatOp *instruction = ir_build_inst_gen<IrInstGenFloatOp>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = operand_type; + instruction->operand = operand; + instruction->fn_id = fn_id; + + ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_mul_add_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *type_value, IrInstSrc *op1, IrInstSrc *op2, IrInstSrc *op3) +{ + IrInstSrcMulAdd *instruction = ir_build_instruction<IrInstSrcMulAdd>(irb, scope, source_node); instruction->type_value = type_value; instruction->op1 = op1; instruction->op2 = op2; @@ -3187,8 +4018,25 @@ static IrInstruction *ir_build_mul_add(IrBuilder *irb, Scope *scope, AstNode *so return &instruction->base; } -static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { - IrInstructionAlignOf *instruction = ir_build_instruction<IrInstructionAlignOf>(irb, scope, source_node); +static IrInstGen *ir_build_mul_add_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *op1, IrInstGen *op2, + IrInstGen *op3, ZigType *expr_type) +{ + IrInstGenMulAdd *instruction = ir_build_inst_gen<IrInstGenMulAdd>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = expr_type; + instruction->op1 = op1; + instruction->op2 = op2; + instruction->op3 = op3; + + ir_ref_inst_gen(op1, ira->new_irb.current_basic_block); + ir_ref_inst_gen(op2, ira->new_irb.current_basic_block); + ir_ref_inst_gen(op3, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_align_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value) { + IrInstSrcAlignOf *instruction = ir_build_instruction<IrInstSrcAlignOf>(irb, scope, source_node); instruction->type_value = type_value; ir_ref_instruction(type_value, irb->current_basic_block); @@ -3196,10 +4044,10 @@ static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_test_err_src(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *base_ptr, bool resolve_err_set, bool base_ptr_is_payload) +static IrInstSrc *ir_build_test_err_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *base_ptr, bool resolve_err_set, bool base_ptr_is_payload) { - IrInstructionTestErrSrc *instruction = ir_build_instruction<IrInstructionTestErrSrc>(irb, scope, source_node); + IrInstSrcTestErr *instruction = ir_build_instruction<IrInstSrcTestErr>(irb, scope, source_node); instruction->base_ptr = base_ptr; instruction->resolve_err_set = resolve_err_set; instruction->base_ptr_is_payload = base_ptr_is_payload; @@ -3209,48 +4057,72 @@ static IrInstruction *ir_build_test_err_src(IrBuilder *irb, Scope *scope, AstNod return &instruction->base; } -static IrInstruction *ir_build_test_err_gen(IrAnalyze *ira, IrInstruction *source_instruction, - IrInstruction *err_union) -{ - IrInstructionTestErrGen *instruction = ir_build_instruction<IrInstructionTestErrGen>( +static IrInstGen *ir_build_test_err_gen(IrAnalyze *ira, IrInst *source_instruction, IrInstGen *err_union) { + IrInstGenTestErr *instruction = ir_build_inst_gen<IrInstGenTestErr>( &ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = ira->codegen->builtin_types.entry_bool; instruction->err_union = err_union; - ir_ref_instruction(err_union, ira->new_irb.current_basic_block); + ir_ref_inst_gen(err_union, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *err_union_ptr) +static IrInstSrc *ir_build_unwrap_err_code_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *err_union_ptr) { - IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node); - instruction->err_union_ptr = err_union_ptr; + IrInstSrcUnwrapErrCode *inst = ir_build_instruction<IrInstSrcUnwrapErrCode>(irb, scope, source_node); + inst->err_union_ptr = err_union_ptr; ir_ref_instruction(err_union_ptr, irb->current_basic_block); - return &instruction->base; + return &inst->base; } -static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *value, bool safety_check_on, bool initializing) +static IrInstGen *ir_build_unwrap_err_code_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, + IrInstGen *err_union_ptr, ZigType *result_type) { - IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); - instruction->value = value; - instruction->safety_check_on = safety_check_on; - instruction->initializing = initializing; + IrInstGenUnwrapErrCode *inst = ir_build_inst_gen<IrInstGenUnwrapErrCode>(&ira->new_irb, scope, source_node); + inst->base.value->type = result_type; + inst->err_union_ptr = err_union_ptr; + + ir_ref_inst_gen(err_union_ptr, ira->new_irb.current_basic_block); + + return &inst->base; +} + +static IrInstSrc *ir_build_unwrap_err_payload_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *value, bool safety_check_on, bool initializing) +{ + IrInstSrcUnwrapErrPayload *inst = ir_build_instruction<IrInstSrcUnwrapErrPayload>(irb, scope, source_node); + inst->value = value; + inst->safety_check_on = safety_check_on; + inst->initializing = initializing; ir_ref_instruction(value, irb->current_basic_block); - return &instruction->base; + return &inst->base; +} + +static IrInstGen *ir_build_unwrap_err_payload_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, + IrInstGen *value, bool safety_check_on, bool initializing, ZigType *result_type) +{ + IrInstGenUnwrapErrPayload *inst = ir_build_inst_gen<IrInstGenUnwrapErrPayload>(&ira->new_irb, scope, source_node); + inst->base.value->type = result_type; + inst->value = value; + inst->safety_check_on = safety_check_on; + inst->initializing = initializing; + + ir_ref_inst_gen(value, ira->new_irb.current_basic_block); + + return &inst->base; } -static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction **param_types, IrInstruction *align_value, IrInstruction *callconv_value, - IrInstruction *return_type, bool is_var_args) +static IrInstSrc *ir_build_fn_proto(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc **param_types, IrInstSrc *align_value, IrInstSrc *callconv_value, + IrInstSrc *return_type, bool is_var_args) { - IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node); + IrInstSrcFnProto *instruction = ir_build_instruction<IrInstSrcFnProto>(irb, scope, source_node); instruction->param_types = param_types; instruction->align_value = align_value; instruction->callconv_value = callconv_value; @@ -3270,8 +4142,8 @@ static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_test_comptime(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { - IrInstructionTestComptime *instruction = ir_build_instruction<IrInstructionTestComptime>(irb, scope, source_node); +static IrInstSrc *ir_build_test_comptime(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { + IrInstSrcTestComptime *instruction = ir_build_instruction<IrInstSrcTestComptime>(irb, scope, source_node); instruction->value = value; ir_ref_instruction(value, irb->current_basic_block); @@ -3279,10 +4151,10 @@ static IrInstruction *ir_build_test_comptime(IrBuilder *irb, Scope *scope, AstNo return &instruction->base; } -static IrInstruction *ir_build_ptr_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *dest_type, IrInstruction *ptr, bool safety_check_on) +static IrInstSrc *ir_build_ptr_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *dest_type, IrInstSrc *ptr, bool safety_check_on) { - IrInstructionPtrCastSrc *instruction = ir_build_instruction<IrInstructionPtrCastSrc>( + IrInstSrcPtrCast *instruction = ir_build_instruction<IrInstSrcPtrCast>( irb, scope, source_node); instruction->dest_type = dest_type; instruction->ptr = ptr; @@ -3294,39 +4166,24 @@ static IrInstruction *ir_build_ptr_cast_src(IrBuilder *irb, Scope *scope, AstNod return &instruction->base; } -static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *source_instruction, - ZigType *ptr_type, IrInstruction *ptr, bool safety_check_on) +static IrInstGen *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInst *source_instruction, + ZigType *ptr_type, IrInstGen *ptr, bool safety_check_on) { - IrInstructionPtrCastGen *instruction = ir_build_instruction<IrInstructionPtrCastGen>( + IrInstGenPtrCast *instruction = ir_build_inst_gen<IrInstGenPtrCast>( &ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = ptr_type; instruction->ptr = ptr; instruction->safety_check_on = safety_check_on; - ir_ref_instruction(ptr, ira->new_irb.current_basic_block); - - return &instruction->base; -} - -static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction, - IrInstruction *ptr, ZigType *ty, IrInstruction *result_loc) -{ - IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>( - &ira->new_irb, source_instruction->scope, source_instruction->source_node); - instruction->base.value->type = ty; - instruction->ptr = ptr; - instruction->result_loc = result_loc; - - ir_ref_instruction(ptr, ira->new_irb.current_basic_block); - if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); + ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *operand, ResultLocCast *result_loc_cast) +static IrInstSrc *ir_build_implicit_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *operand, ResultLocCast *result_loc_cast) { - IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node); + IrInstSrcImplicitCast *instruction = ir_build_instruction<IrInstSrcImplicitCast>(irb, scope, source_node); instruction->operand = operand; instruction->result_loc_cast = result_loc_cast; @@ -3335,10 +4192,10 @@ static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNo return &instruction->base; } -static IrInstruction *ir_build_bit_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *operand, ResultLocBitCast *result_loc_bit_cast) +static IrInstSrc *ir_build_bit_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *operand, ResultLocBitCast *result_loc_bit_cast) { - IrInstructionBitCastSrc *instruction = ir_build_instruction<IrInstructionBitCastSrc>(irb, scope, source_node); + IrInstSrcBitCast *instruction = ir_build_instruction<IrInstSrcBitCast>(irb, scope, source_node); instruction->operand = operand; instruction->result_loc_bit_cast = result_loc_bit_cast; @@ -3347,62 +4204,81 @@ static IrInstruction *ir_build_bit_cast_src(IrBuilder *irb, Scope *scope, AstNod return &instruction->base; } -static IrInstruction *ir_build_bit_cast_gen(IrAnalyze *ira, IrInstruction *source_instruction, - IrInstruction *operand, ZigType *ty) +static IrInstGen *ir_build_bit_cast_gen(IrAnalyze *ira, IrInst *source_instruction, + IrInstGen *operand, ZigType *ty) { - IrInstructionBitCastGen *instruction = ir_build_instruction<IrInstructionBitCastGen>( + IrInstGenBitCast *instruction = ir_build_inst_gen<IrInstGenBitCast>( &ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = ty; instruction->operand = operand; - ir_ref_instruction(operand, ira->new_irb.current_basic_block); + ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_widen_or_shorten(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *target) +static IrInstGen *ir_build_widen_or_shorten(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, + ZigType *result_type) { - IrInstructionWidenOrShorten *instruction = ir_build_instruction<IrInstructionWidenOrShorten>( - irb, scope, source_node); - instruction->target = target; + IrInstGenWidenOrShorten *inst = ir_build_inst_gen<IrInstGenWidenOrShorten>(&ira->new_irb, scope, source_node); + inst->base.value->type = result_type; + inst->target = target; - ir_ref_instruction(target, irb->current_basic_block); + ir_ref_inst_gen(target, ira->new_irb.current_basic_block); - return &instruction->base; + return &inst->base; } -static IrInstruction *ir_build_int_to_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *dest_type, IrInstruction *target) +static IrInstSrc *ir_build_int_to_ptr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *dest_type, IrInstSrc *target) { - IrInstructionIntToPtr *instruction = ir_build_instruction<IrInstructionIntToPtr>( - irb, scope, source_node); + IrInstSrcIntToPtr *instruction = ir_build_instruction<IrInstSrcIntToPtr>(irb, scope, source_node); instruction->dest_type = dest_type; instruction->target = target; - if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); + ir_ref_instruction(dest_type, irb->current_basic_block); ir_ref_instruction(target, irb->current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_ptr_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *target) +static IrInstGen *ir_build_int_to_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, + IrInstGen *target, ZigType *ptr_type) { - IrInstructionPtrToInt *instruction = ir_build_instruction<IrInstructionPtrToInt>( - irb, scope, source_node); + IrInstGenIntToPtr *instruction = ir_build_inst_gen<IrInstGenIntToPtr>(&ira->new_irb, scope, source_node); + instruction->base.value->type = ptr_type; instruction->target = target; - ir_ref_instruction(target, irb->current_basic_block); + ir_ref_inst_gen(target, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_int_to_enum(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *dest_type, IrInstruction *target) +static IrInstSrc *ir_build_ptr_to_int_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *target) { - IrInstructionIntToEnum *instruction = ir_build_instruction<IrInstructionIntToEnum>( - irb, scope, source_node); + IrInstSrcPtrToInt *inst = ir_build_instruction<IrInstSrcPtrToInt>(irb, scope, source_node); + inst->target = target; + + ir_ref_instruction(target, irb->current_basic_block); + + return &inst->base; +} + +static IrInstGen *ir_build_ptr_to_int_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target) { + IrInstGenPtrToInt *inst = ir_build_inst_gen<IrInstGenPtrToInt>(&ira->new_irb, source_instr->scope, source_instr->source_node); + inst->base.value->type = ira->codegen->builtin_types.entry_usize; + inst->target = target; + + ir_ref_inst_gen(target, ira->new_irb.current_basic_block); + + return &inst->base; +} + +static IrInstSrc *ir_build_int_to_enum_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *dest_type, IrInstSrc *target) +{ + IrInstSrcIntToEnum *instruction = ir_build_instruction<IrInstSrcIntToEnum>(irb, scope, source_node); instruction->dest_type = dest_type; instruction->target = target; @@ -3412,12 +4288,22 @@ static IrInstruction *ir_build_int_to_enum(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } +static IrInstGen *ir_build_int_to_enum_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, + ZigType *dest_type, IrInstGen *target) +{ + IrInstGenIntToEnum *instruction = ir_build_inst_gen<IrInstGenIntToEnum>(&ira->new_irb, scope, source_node); + instruction->base.value->type = dest_type; + instruction->target = target; + ir_ref_inst_gen(target, ira->new_irb.current_basic_block); -static IrInstruction *ir_build_enum_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *target) + return &instruction->base; +} + +static IrInstSrc *ir_build_enum_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *target) { - IrInstructionEnumToInt *instruction = ir_build_instruction<IrInstructionEnumToInt>( + IrInstSrcEnumToInt *instruction = ir_build_instruction<IrInstSrcEnumToInt>( irb, scope, source_node); instruction->target = target; @@ -3426,11 +4312,10 @@ static IrInstruction *ir_build_enum_to_int(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_int_to_err(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *target) +static IrInstSrc *ir_build_int_to_err_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *target) { - IrInstructionIntToErr *instruction = ir_build_instruction<IrInstructionIntToErr>( - irb, scope, source_node); + IrInstSrcIntToErr *instruction = ir_build_instruction<IrInstSrcIntToErr>(irb, scope, source_node); instruction->target = target; ir_ref_instruction(target, irb->current_basic_block); @@ -3438,10 +4323,22 @@ static IrInstruction *ir_build_int_to_err(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_err_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *target) +static IrInstGen *ir_build_int_to_err_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, + ZigType *wanted_type) { - IrInstructionErrToInt *instruction = ir_build_instruction<IrInstructionErrToInt>( + IrInstGenIntToErr *instruction = ir_build_inst_gen<IrInstGenIntToErr>(&ira->new_irb, scope, source_node); + instruction->base.value->type = wanted_type; + instruction->target = target; + + ir_ref_inst_gen(target, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_err_to_int_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *target) +{ + IrInstSrcErrToInt *instruction = ir_build_instruction<IrInstSrcErrToInt>( irb, scope, source_node); instruction->target = target; @@ -3450,11 +4347,23 @@ static IrInstruction *ir_build_err_to_int(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_check_switch_prongs(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *target_value, IrInstructionCheckSwitchProngsRange *ranges, size_t range_count, +static IrInstGen *ir_build_err_to_int_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, + ZigType *wanted_type) +{ + IrInstGenErrToInt *instruction = ir_build_inst_gen<IrInstGenErrToInt>(&ira->new_irb, scope, source_node); + instruction->base.value->type = wanted_type; + instruction->target = target; + + ir_ref_inst_gen(target, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_check_switch_prongs(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *target_value, IrInstSrcCheckSwitchProngsRange *ranges, size_t range_count, bool have_else_prong, bool have_underscore_prong) { - IrInstructionCheckSwitchProngs *instruction = ir_build_instruction<IrInstructionCheckSwitchProngs>( + IrInstSrcCheckSwitchProngs *instruction = ir_build_instruction<IrInstSrcCheckSwitchProngs>( irb, scope, source_node); instruction->target_value = target_value; instruction->ranges = ranges; @@ -3471,10 +4380,10 @@ static IrInstruction *ir_build_check_switch_prongs(IrBuilder *irb, Scope *scope, return &instruction->base; } -static IrInstruction *ir_build_check_statement_is_void(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction* statement_value) +static IrInstSrc *ir_build_check_statement_is_void(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc* statement_value) { - IrInstructionCheckStatementIsVoid *instruction = ir_build_instruction<IrInstructionCheckStatementIsVoid>( + IrInstSrcCheckStatementIsVoid *instruction = ir_build_instruction<IrInstSrcCheckStatementIsVoid>( irb, scope, source_node); instruction->statement_value = statement_value; @@ -3483,11 +4392,10 @@ static IrInstruction *ir_build_check_statement_is_void(IrBuilder *irb, Scope *sc return &instruction->base; } -static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *type_value) +static IrInstSrc *ir_build_type_name(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *type_value) { - IrInstructionTypeName *instruction = ir_build_instruction<IrInstructionTypeName>( - irb, scope, source_node); + IrInstSrcTypeName *instruction = ir_build_instruction<IrInstSrcTypeName>(irb, scope, source_node); instruction->type_value = type_value; ir_ref_instruction(type_value, irb->current_basic_block); @@ -3495,18 +4403,17 @@ static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } -static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) { - IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>(irb, scope, source_node); +static IrInstSrc *ir_build_decl_ref(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) { + IrInstSrcDeclRef *instruction = ir_build_instruction<IrInstSrcDeclRef>(irb, scope, source_node); instruction->tld = tld; instruction->lval = lval; return &instruction->base; } -static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { - IrInstructionPanic *instruction = ir_build_instruction<IrInstructionPanic>(irb, scope, source_node); - instruction->base.value->special = ConstValSpecialStatic; - instruction->base.value->type = irb->codegen->builtin_types.entry_unreachable; +static IrInstSrc *ir_build_panic_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *msg) { + IrInstSrcPanic *instruction = ir_build_instruction<IrInstSrcPanic>(irb, scope, source_node); + instruction->base.is_noreturn = true; instruction->msg = msg; ir_ref_instruction(msg, irb->current_basic_block); @@ -3514,10 +4421,18 @@ static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *sour return &instruction->base; } -static IrInstruction *ir_build_tag_name(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *target) -{ - IrInstructionTagName *instruction = ir_build_instruction<IrInstructionTagName>(irb, scope, source_node); +static IrInstGen *ir_build_panic_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *msg) { + IrInstGenPanic *instruction = ir_build_inst_noreturn<IrInstGenPanic>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->msg = msg; + + ir_ref_inst_gen(msg, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_tag_name_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target) { + IrInstSrcTagName *instruction = ir_build_instruction<IrInstSrcTagName>(irb, scope, source_node); instruction->target = target; ir_ref_instruction(target, irb->current_basic_block); @@ -3525,10 +4440,23 @@ static IrInstruction *ir_build_tag_name(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_tag_type(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *target) +static IrInstGen *ir_build_tag_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target, + ZigType *result_type) +{ + IrInstGenTagName *instruction = ir_build_inst_gen<IrInstGenTagName>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = result_type; + instruction->target = target; + + ir_ref_inst_gen(target, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_tag_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *target) { - IrInstructionTagType *instruction = ir_build_instruction<IrInstructionTagType>(irb, scope, source_node); + IrInstSrcTagType *instruction = ir_build_instruction<IrInstSrcTagType>(irb, scope, source_node); instruction->target = target; ir_ref_instruction(target, irb->current_basic_block); @@ -3536,27 +4464,40 @@ static IrInstruction *ir_build_tag_type(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_field_parent_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *type_value, IrInstruction *field_name, IrInstruction *field_ptr, TypeStructField *field) +static IrInstSrc *ir_build_field_parent_ptr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *type_value, IrInstSrc *field_name, IrInstSrc *field_ptr) { - IrInstructionFieldParentPtr *instruction = ir_build_instruction<IrInstructionFieldParentPtr>( + IrInstSrcFieldParentPtr *inst = ir_build_instruction<IrInstSrcFieldParentPtr>( irb, scope, source_node); - instruction->type_value = type_value; - instruction->field_name = field_name; - instruction->field_ptr = field_ptr; - instruction->field = field; + inst->type_value = type_value; + inst->field_name = field_name; + inst->field_ptr = field_ptr; ir_ref_instruction(type_value, irb->current_basic_block); ir_ref_instruction(field_name, irb->current_basic_block); ir_ref_instruction(field_ptr, irb->current_basic_block); - return &instruction->base; + return &inst->base; +} + +static IrInstGen *ir_build_field_parent_ptr_gen(IrAnalyze *ira, IrInst *source_instr, + IrInstGen *field_ptr, TypeStructField *field, ZigType *result_type) +{ + IrInstGenFieldParentPtr *inst = ir_build_inst_gen<IrInstGenFieldParentPtr>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + inst->base.value->type = result_type; + inst->field_ptr = field_ptr; + inst->field = field; + + ir_ref_inst_gen(field_ptr, ira->new_irb.current_basic_block); + + return &inst->base; } -static IrInstruction *ir_build_byte_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *type_value, IrInstruction *field_name) +static IrInstSrc *ir_build_byte_offset_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *type_value, IrInstSrc *field_name) { - IrInstructionByteOffsetOf *instruction = ir_build_instruction<IrInstructionByteOffsetOf>(irb, scope, source_node); + IrInstSrcByteOffsetOf *instruction = ir_build_instruction<IrInstSrcByteOffsetOf>(irb, scope, source_node); instruction->type_value = type_value; instruction->field_name = field_name; @@ -3566,10 +4507,10 @@ static IrInstruction *ir_build_byte_offset_of(IrBuilder *irb, Scope *scope, AstN return &instruction->base; } -static IrInstruction *ir_build_bit_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *type_value, IrInstruction *field_name) +static IrInstSrc *ir_build_bit_offset_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *type_value, IrInstSrc *field_name) { - IrInstructionBitOffsetOf *instruction = ir_build_instruction<IrInstructionBitOffsetOf>(irb, scope, source_node); + IrInstSrcBitOffsetOf *instruction = ir_build_instruction<IrInstSrcBitOffsetOf>(irb, scope, source_node); instruction->type_value = type_value; instruction->field_name = field_name; @@ -3579,9 +4520,8 @@ static IrInstruction *ir_build_bit_offset_of(IrBuilder *irb, Scope *scope, AstNo return &instruction->base; } -static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *type_value) { - IrInstructionTypeInfo *instruction = ir_build_instruction<IrInstructionTypeInfo>(irb, scope, source_node); +static IrInstSrc *ir_build_type_info(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value) { + IrInstSrcTypeInfo *instruction = ir_build_instruction<IrInstSrcTypeInfo>(irb, scope, source_node); instruction->type_value = type_value; ir_ref_instruction(type_value, irb->current_basic_block); @@ -3589,8 +4529,8 @@ static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } -static IrInstruction *ir_build_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_info) { - IrInstructionType *instruction = ir_build_instruction<IrInstructionType>(irb, scope, source_node); +static IrInstSrc *ir_build_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_info) { + IrInstSrcType *instruction = ir_build_instruction<IrInstSrcType>(irb, scope, source_node); instruction->type_info = type_info; ir_ref_instruction(type_info, irb->current_basic_block); @@ -3598,10 +4538,8 @@ static IrInstruction *ir_build_type(IrBuilder *irb, Scope *scope, AstNode *sourc return &instruction->base; } -static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *type_value) -{ - IrInstructionTypeId *instruction = ir_build_instruction<IrInstructionTypeId>(irb, scope, source_node); +static IrInstSrc *ir_build_type_id(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value) { + IrInstSrcTypeId *instruction = ir_build_instruction<IrInstSrcTypeId>(irb, scope, source_node); instruction->type_value = type_value; ir_ref_instruction(type_value, irb->current_basic_block); @@ -3609,10 +4547,10 @@ static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *so return &instruction->base; } -static IrInstruction *ir_build_set_eval_branch_quota(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *new_quota) +static IrInstSrc *ir_build_set_eval_branch_quota(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *new_quota) { - IrInstructionSetEvalBranchQuota *instruction = ir_build_instruction<IrInstructionSetEvalBranchQuota>(irb, scope, source_node); + IrInstSrcSetEvalBranchQuota *instruction = ir_build_instruction<IrInstSrcSetEvalBranchQuota>(irb, scope, source_node); instruction->new_quota = new_quota; ir_ref_instruction(new_quota, irb->current_basic_block); @@ -3620,23 +4558,35 @@ static IrInstruction *ir_build_set_eval_branch_quota(IrBuilder *irb, Scope *scop return &instruction->base; } -static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *align_bytes, IrInstruction *target) +static IrInstSrc *ir_build_align_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *align_bytes, IrInstSrc *target) { - IrInstructionAlignCast *instruction = ir_build_instruction<IrInstructionAlignCast>(irb, scope, source_node); + IrInstSrcAlignCast *instruction = ir_build_instruction<IrInstSrcAlignCast>(irb, scope, source_node); instruction->align_bytes = align_bytes; instruction->target = target; - if (align_bytes) ir_ref_instruction(align_bytes, irb->current_basic_block); + ir_ref_instruction(align_bytes, irb->current_basic_block); ir_ref_instruction(target, irb->current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstNode *source_node, - ResultLoc *result_loc, IrInstruction *ty) +static IrInstGen *ir_build_align_cast_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, + ZigType *result_type) +{ + IrInstGenAlignCast *instruction = ir_build_inst_gen<IrInstGenAlignCast>(&ira->new_irb, scope, source_node); + instruction->base.value->type = result_type; + instruction->target = target; + + ir_ref_inst_gen(target, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_resolve_result(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + ResultLoc *result_loc, IrInstSrc *ty) { - IrInstructionResolveResult *instruction = ir_build_instruction<IrInstructionResolveResult>(irb, scope, source_node); + IrInstSrcResolveResult *instruction = ir_build_instruction<IrInstSrcResolveResult>(irb, scope, source_node); instruction->result_loc = result_loc; instruction->ty = ty; @@ -3645,25 +4595,26 @@ static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstN return &instruction->base; } -static IrInstruction *ir_build_reset_result(IrBuilder *irb, Scope *scope, AstNode *source_node, +static IrInstSrc *ir_build_reset_result(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ResultLoc *result_loc) { - IrInstructionResetResult *instruction = ir_build_instruction<IrInstructionResetResult>(irb, scope, source_node); + IrInstSrcResetResult *instruction = ir_build_instruction<IrInstSrcResetResult>(irb, scope, source_node); instruction->result_loc = result_loc; + instruction->base.is_gen = true; return &instruction->base; } -static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node); +static IrInstSrc *ir_build_opaque_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { + IrInstSrcOpaqueType *instruction = ir_build_instruction<IrInstSrcOpaqueType>(irb, scope, source_node); return &instruction->base; } -static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *align_bytes) +static IrInstSrc *ir_build_set_align_stack(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *align_bytes) { - IrInstructionSetAlignStack *instruction = ir_build_instruction<IrInstructionSetAlignStack>(irb, scope, source_node); + IrInstSrcSetAlignStack *instruction = ir_build_instruction<IrInstSrcSetAlignStack>(irb, scope, source_node); instruction->align_bytes = align_bytes; ir_ref_instruction(align_bytes, irb->current_basic_block); @@ -3671,10 +4622,10 @@ static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, Ast return &instruction->base; } -static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *fn_type, IrInstruction *arg_index, bool allow_var) +static IrInstSrc *ir_build_arg_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *fn_type, IrInstSrc *arg_index, bool allow_var) { - IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node); + IrInstSrcArgType *instruction = ir_build_instruction<IrInstSrcArgType>(irb, scope, source_node); instruction->fn_type = fn_type; instruction->arg_index = arg_index; instruction->allow_var = allow_var; @@ -3685,17 +4636,29 @@ static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_error_return_trace(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstructionErrorReturnTrace::Optional optional) { - IrInstructionErrorReturnTrace *instruction = ir_build_instruction<IrInstructionErrorReturnTrace>(irb, scope, source_node); - instruction->optional = optional; +static IrInstSrc *ir_build_error_return_trace_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstErrorReturnTraceOptional optional) +{ + IrInstSrcErrorReturnTrace *inst = ir_build_instruction<IrInstSrcErrorReturnTrace>(irb, scope, source_node); + inst->optional = optional; - return &instruction->base; + return &inst->base; +} + +static IrInstGen *ir_build_error_return_trace_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, + IrInstErrorReturnTraceOptional optional, ZigType *result_type) +{ + IrInstGenErrorReturnTrace *inst = ir_build_inst_gen<IrInstGenErrorReturnTrace>(&ira->new_irb, scope, source_node); + inst->base.value->type = result_type; + inst->optional = optional; + + return &inst->base; } -static IrInstruction *ir_build_error_union(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *err_set, IrInstruction *payload) +static IrInstSrc *ir_build_error_union(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *err_set, IrInstSrc *payload) { - IrInstructionErrorUnion *instruction = ir_build_instruction<IrInstructionErrorUnion>(irb, scope, source_node); + IrInstSrcErrorUnion *instruction = ir_build_instruction<IrInstSrcErrorUnion>(irb, scope, source_node); instruction->err_set = err_set; instruction->payload = payload; @@ -3705,85 +4668,130 @@ static IrInstruction *ir_build_error_union(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_atomic_rmw(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *op, IrInstruction *operand, - IrInstruction *ordering, AtomicRmwOp resolved_op, AtomicOrder resolved_ordering) +static IrInstSrc *ir_build_atomic_rmw_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *op, IrInstSrc *operand, + IrInstSrc *ordering) { - IrInstructionAtomicRmw *instruction = ir_build_instruction<IrInstructionAtomicRmw>(irb, scope, source_node); + IrInstSrcAtomicRmw *instruction = ir_build_instruction<IrInstSrcAtomicRmw>(irb, scope, source_node); instruction->operand_type = operand_type; instruction->ptr = ptr; instruction->op = op; instruction->operand = operand; instruction->ordering = ordering; - instruction->resolved_op = resolved_op; - instruction->resolved_ordering = resolved_ordering; - if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); + ir_ref_instruction(operand_type, irb->current_basic_block); ir_ref_instruction(ptr, irb->current_basic_block); - if (op != nullptr) ir_ref_instruction(op, irb->current_basic_block); + ir_ref_instruction(op, irb->current_basic_block); ir_ref_instruction(operand, irb->current_basic_block); - if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); + ir_ref_instruction(ordering, irb->current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_atomic_load(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *operand_type, IrInstruction *ptr, - IrInstruction *ordering, AtomicOrder resolved_ordering) +static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr, + IrInstGen *ptr, IrInstGen *operand, AtomicRmwOp op, AtomicOrder ordering, ZigType *operand_type) { - IrInstructionAtomicLoad *instruction = ir_build_instruction<IrInstructionAtomicLoad>(irb, scope, source_node); + IrInstGenAtomicRmw *instruction = ir_build_inst_gen<IrInstGenAtomicRmw>(&ira->new_irb, source_instr->scope, source_instr->source_node); + instruction->base.value->type = operand_type; + instruction->ptr = ptr; + instruction->op = op; + instruction->operand = operand; + instruction->ordering = ordering; + + ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); + ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_atomic_load_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *ordering) +{ + IrInstSrcAtomicLoad *instruction = ir_build_instruction<IrInstSrcAtomicLoad>(irb, scope, source_node); instruction->operand_type = operand_type; instruction->ptr = ptr; instruction->ordering = ordering; - instruction->resolved_ordering = resolved_ordering; - if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); + ir_ref_instruction(operand_type, irb->current_basic_block); ir_ref_instruction(ptr, irb->current_basic_block); - if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); + ir_ref_instruction(ordering, irb->current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_atomic_store(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *value, - IrInstruction *ordering, AtomicOrder resolved_ordering) +static IrInstGen *ir_build_atomic_load_gen(IrAnalyze *ira, IrInst *source_instr, + IrInstGen *ptr, AtomicOrder ordering, ZigType *operand_type) { - IrInstructionAtomicStore *instruction = ir_build_instruction<IrInstructionAtomicStore>(irb, scope, source_node); + IrInstGenAtomicLoad *instruction = ir_build_inst_gen<IrInstGenAtomicLoad>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = operand_type; + instruction->ptr = ptr; + instruction->ordering = ordering; + + ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_atomic_store_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *value, IrInstSrc *ordering) +{ + IrInstSrcAtomicStore *instruction = ir_build_instruction<IrInstSrcAtomicStore>(irb, scope, source_node); instruction->operand_type = operand_type; instruction->ptr = ptr; instruction->value = value; instruction->ordering = ordering; - instruction->resolved_ordering = resolved_ordering; - if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); + ir_ref_instruction(operand_type, irb->current_basic_block); ir_ref_instruction(ptr, irb->current_basic_block); ir_ref_instruction(value, irb->current_basic_block); - if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); + ir_ref_instruction(ordering, irb->current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionSaveErrRetAddr *instruction = ir_build_instruction<IrInstructionSaveErrRetAddr>(irb, scope, source_node); +static IrInstGen *ir_build_atomic_store_gen(IrAnalyze *ira, IrInst *source_instr, + IrInstGen *ptr, IrInstGen *value, AtomicOrder ordering) +{ + IrInstGenAtomicStore *instruction = ir_build_inst_void<IrInstGenAtomicStore>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->ptr = ptr; + instruction->value = value; + instruction->ordering = ordering; + + ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); + ir_ref_inst_gen(value, ira->new_irb.current_basic_block); + return &instruction->base; } -static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *value, ResultLocReturn *result_loc_ret) +static IrInstSrc *ir_build_save_err_ret_addr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { + IrInstSrcSaveErrRetAddr *inst = ir_build_instruction<IrInstSrcSaveErrRetAddr>(irb, scope, source_node); + return &inst->base; +} + +static IrInstGen *ir_build_save_err_ret_addr_gen(IrAnalyze *ira, IrInst *source_instr) { + IrInstGenSaveErrRetAddr *inst = ir_build_inst_void<IrInstGenSaveErrRetAddr>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + return &inst->base; +} + +static IrInstSrc *ir_build_add_implicit_return_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *value, ResultLocReturn *result_loc_ret) { - IrInstructionAddImplicitReturnType *instruction = ir_build_instruction<IrInstructionAddImplicitReturnType>(irb, scope, source_node); - instruction->value = value; - instruction->result_loc_ret = result_loc_ret; + IrInstSrcAddImplicitReturnType *inst = ir_build_instruction<IrInstSrcAddImplicitReturnType>(irb, scope, source_node); + inst->value = value; + inst->result_loc_ret = result_loc_ret; ir_ref_instruction(value, irb->current_basic_block); - return &instruction->base; + return &inst->base; } -static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *container, IrInstruction *name) +static IrInstSrc *ir_build_has_decl(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *container, IrInstSrc *name) { - IrInstructionHasDecl *instruction = ir_build_instruction<IrInstructionHasDecl>(irb, scope, source_node); + IrInstSrcHasDecl *instruction = ir_build_instruction<IrInstSrcHasDecl>(irb, scope, source_node); instruction->container = container; instruction->name = name; @@ -3793,17 +4801,15 @@ static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_undeclared_identifier(IrBuilder *irb, Scope *scope, AstNode *source_node, - Buf *name) -{ - IrInstructionUndeclaredIdent *instruction = ir_build_instruction<IrInstructionUndeclaredIdent>(irb, scope, source_node); +static IrInstSrc *ir_build_undeclared_identifier(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *name) { + IrInstSrcUndeclaredIdent *instruction = ir_build_instruction<IrInstSrcUndeclaredIdent>(irb, scope, source_node); instruction->name = name; return &instruction->base; } -static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) { - IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node); +static IrInstSrc *ir_build_check_runtime_scope(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *scope_is_comptime, IrInstSrc *is_comptime) { + IrInstSrcCheckRuntimeScope *instruction = ir_build_instruction<IrInstSrcCheckRuntimeScope>(irb, scope, source_node); instruction->scope_is_comptime = scope_is_comptime; instruction->is_comptime = is_comptime; @@ -3813,10 +4819,10 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, return &instruction->base; } -static IrInstruction *ir_build_union_init_named_field(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *union_type, IrInstruction *field_name, IrInstruction *field_result_loc, IrInstruction *result_loc) +static IrInstSrc *ir_build_union_init_named_field(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *union_type, IrInstSrc *field_name, IrInstSrc *field_result_loc, IrInstSrc *result_loc) { - IrInstructionUnionInitNamedField *instruction = ir_build_instruction<IrInstructionUnionInitNamedField>(irb, scope, source_node); + IrInstSrcUnionInitNamedField *instruction = ir_build_instruction<IrInstSrcUnionInitNamedField>(irb, scope, source_node); instruction->union_type = union_type; instruction->field_name = field_name; instruction->field_result_loc = field_result_loc; @@ -3831,79 +4837,79 @@ static IrInstruction *ir_build_union_init_named_field(IrBuilder *irb, Scope *sco } -static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction, - ZigType *result_type, IrInstruction *vector, IrInstruction *result_loc) +static IrInstGen *ir_build_vector_to_array(IrAnalyze *ira, IrInst *source_instruction, + ZigType *result_type, IrInstGen *vector, IrInstGen *result_loc) { - IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb, + IrInstGenVectorToArray *instruction = ir_build_inst_gen<IrInstGenVectorToArray>(&ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = result_type; instruction->vector = vector; instruction->result_loc = result_loc; - ir_ref_instruction(vector, ira->new_irb.current_basic_block); - ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); + ir_ref_inst_gen(vector, ira->new_irb.current_basic_block); + ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instruction, - ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) +static IrInstGen *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInst *source_instruction, + ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc) { - IrInstructionPtrOfArrayToSlice *instruction = ir_build_instruction<IrInstructionPtrOfArrayToSlice>(&ira->new_irb, + IrInstGenPtrOfArrayToSlice *instruction = ir_build_inst_gen<IrInstGenPtrOfArrayToSlice>(&ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = result_type; instruction->operand = operand; instruction->result_loc = result_loc; - ir_ref_instruction(operand, ira->new_irb.current_basic_block); - ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); + ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); + ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_array_to_vector(IrAnalyze *ira, IrInstruction *source_instruction, - IrInstruction *array, ZigType *result_type) +static IrInstGen *ir_build_array_to_vector(IrAnalyze *ira, IrInst *source_instruction, + IrInstGen *array, ZigType *result_type) { - IrInstructionArrayToVector *instruction = ir_build_instruction<IrInstructionArrayToVector>(&ira->new_irb, + IrInstGenArrayToVector *instruction = ir_build_inst_gen<IrInstGenArrayToVector>(&ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = result_type; instruction->array = array; - ir_ref_instruction(array, ira->new_irb.current_basic_block); + ir_ref_inst_gen(array, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_assert_zero(IrAnalyze *ira, IrInstruction *source_instruction, - IrInstruction *target) +static IrInstGen *ir_build_assert_zero(IrAnalyze *ira, IrInst *source_instruction, + IrInstGen *target) { - IrInstructionAssertZero *instruction = ir_build_instruction<IrInstructionAssertZero>(&ira->new_irb, + IrInstGenAssertZero *instruction = ir_build_inst_gen<IrInstGenAssertZero>(&ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = ira->codegen->builtin_types.entry_void; instruction->target = target; - ir_ref_instruction(target, ira->new_irb.current_basic_block); + ir_ref_inst_gen(target, ira->new_irb.current_basic_block); return &instruction->base; } -static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *source_instruction, - IrInstruction *target) +static IrInstGen *ir_build_assert_non_null(IrAnalyze *ira, IrInst *source_instruction, + IrInstGen *target) { - IrInstructionAssertNonNull *instruction = ir_build_instruction<IrInstructionAssertNonNull>(&ira->new_irb, + IrInstGenAssertNonNull *instruction = ir_build_inst_gen<IrInstGenAssertNonNull>(&ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = ira->codegen->builtin_types.entry_void; instruction->target = target; - ir_ref_instruction(target, ira->new_irb.current_basic_block); + ir_ref_inst_gen(target, ira->new_irb.current_basic_block); 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) +static IrInstSrc *ir_build_alloca_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *align, const char *name_hint, IrInstSrc *is_comptime) { - IrInstructionAllocaSrc *instruction = ir_build_instruction<IrInstructionAllocaSrc>(irb, scope, source_node); + IrInstSrcAlloca *instruction = ir_build_instruction<IrInstSrcAlloca>(irb, scope, source_node); instruction->base.is_gen = true; instruction->align = align; instruction->name_hint = name_hint; @@ -3915,10 +4921,10 @@ static IrInstruction *ir_build_alloca_src(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstructionAllocaGen *ir_build_alloca_gen(IrAnalyze *ira, IrInstruction *source_instruction, +static IrInstGenAlloca *ir_build_alloca_gen(IrAnalyze *ira, IrInst *source_instruction, uint32_t align, const char *name_hint) { - IrInstructionAllocaGen *instruction = ir_create_instruction<IrInstructionAllocaGen>(&ira->new_irb, + IrInstGenAlloca *instruction = ir_create_inst_gen<IrInstGenAlloca>(&ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->align = align; instruction->name_hint = name_hint; @@ -3926,10 +4932,10 @@ static IrInstructionAllocaGen *ir_build_alloca_gen(IrAnalyze *ira, IrInstruction return instruction; } -static IrInstruction *ir_build_end_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *value, ResultLoc *result_loc) +static IrInstSrc *ir_build_end_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *value, ResultLoc *result_loc) { - IrInstructionEndExpr *instruction = ir_build_instruction<IrInstructionEndExpr>(irb, scope, source_node); + IrInstSrcEndExpr *instruction = ir_build_instruction<IrInstSrcEndExpr>(irb, scope, source_node); instruction->base.is_gen = true; instruction->value = value; instruction->result_loc = result_loc; @@ -3939,29 +4945,41 @@ static IrInstruction *ir_build_end_expr(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstructionSuspendBegin *ir_build_suspend_begin(IrBuilder *irb, Scope *scope, AstNode *source_node) { - IrInstructionSuspendBegin *instruction = ir_build_instruction<IrInstructionSuspendBegin>(irb, scope, source_node); - instruction->base.value->type = irb->codegen->builtin_types.entry_void; +static IrInstSrcSuspendBegin *ir_build_suspend_begin_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { + return ir_build_instruction<IrInstSrcSuspendBegin>(irb, scope, source_node); +} - return instruction; +static IrInstGen *ir_build_suspend_begin_gen(IrAnalyze *ira, IrInst *source_instr) { + IrInstGenSuspendBegin *inst = ir_build_inst_void<IrInstGenSuspendBegin>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + return &inst->base; } -static IrInstruction *ir_build_suspend_finish(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstructionSuspendBegin *begin) +static IrInstSrc *ir_build_suspend_finish_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrcSuspendBegin *begin) { - IrInstructionSuspendFinish *instruction = ir_build_instruction<IrInstructionSuspendFinish>(irb, scope, source_node); - instruction->base.value->type = irb->codegen->builtin_types.entry_void; - instruction->begin = begin; + IrInstSrcSuspendFinish *inst = ir_build_instruction<IrInstSrcSuspendFinish>(irb, scope, source_node); + inst->begin = begin; ir_ref_instruction(&begin->base, irb->current_basic_block); - return &instruction->base; + return &inst->base; +} + +static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSuspendBegin *begin) { + IrInstGenSuspendFinish *inst = ir_build_inst_void<IrInstGenSuspendFinish>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + inst->begin = begin; + + ir_ref_inst_gen(&begin->base, ira->new_irb.current_basic_block); + + return &inst->base; } -static IrInstruction *ir_build_await_src(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *frame, ResultLoc *result_loc) +static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *frame, ResultLoc *result_loc) { - IrInstructionAwaitSrc *instruction = ir_build_instruction<IrInstructionAwaitSrc>(irb, scope, source_node); + IrInstSrcAwait *instruction = ir_build_instruction<IrInstSrcAwait>(irb, scope, source_node); instruction->frame = frame; instruction->result_loc = result_loc; @@ -3970,24 +4988,23 @@ static IrInstruction *ir_build_await_src(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } -static IrInstructionAwaitGen *ir_build_await_gen(IrAnalyze *ira, IrInstruction *source_instruction, - IrInstruction *frame, ZigType *result_type, IrInstruction *result_loc) +static IrInstGenAwait *ir_build_await_gen(IrAnalyze *ira, IrInst *source_instruction, + IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc) { - IrInstructionAwaitGen *instruction = ir_build_instruction<IrInstructionAwaitGen>(&ira->new_irb, + IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = result_type; instruction->frame = frame; instruction->result_loc = result_loc; - ir_ref_instruction(frame, ira->new_irb.current_basic_block); - if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); + ir_ref_inst_gen(frame, ira->new_irb.current_basic_block); + if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); return instruction; } -static IrInstruction *ir_build_resume(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *frame) { - IrInstructionResume *instruction = ir_build_instruction<IrInstructionResume>(irb, scope, source_node); - instruction->base.value->type = irb->codegen->builtin_types.entry_void; +static IrInstSrc *ir_build_resume_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *frame) { + IrInstSrcResume *instruction = ir_build_instruction<IrInstSrcResume>(irb, scope, source_node); instruction->frame = frame; ir_ref_instruction(frame, irb->current_basic_block); @@ -3995,12 +5012,20 @@ static IrInstruction *ir_build_resume(IrBuilder *irb, Scope *scope, AstNode *sou return &instruction->base; } -static IrInstructionSpillBegin *ir_build_spill_begin(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *operand, SpillId spill_id) +static IrInstGen *ir_build_resume_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *frame) { + IrInstGenResume *instruction = ir_build_inst_void<IrInstGenResume>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->frame = frame; + + ir_ref_inst_gen(frame, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrcSpillBegin *ir_build_spill_begin_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *operand, SpillId spill_id) { - IrInstructionSpillBegin *instruction = ir_build_instruction<IrInstructionSpillBegin>(irb, scope, source_node); - instruction->base.value->special = ConstValSpecialStatic; - instruction->base.value->type = irb->codegen->builtin_types.entry_void; + IrInstSrcSpillBegin *instruction = ir_build_instruction<IrInstSrcSpillBegin>(irb, scope, source_node); instruction->operand = operand; instruction->spill_id = spill_id; @@ -4009,10 +5034,23 @@ static IrInstructionSpillBegin *ir_build_spill_begin(IrBuilder *irb, Scope *scop return instruction; } -static IrInstruction *ir_build_spill_end(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstructionSpillBegin *begin) +static IrInstGen *ir_build_spill_begin_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, + SpillId spill_id) { - IrInstructionSpillEnd *instruction = ir_build_instruction<IrInstructionSpillEnd>(irb, scope, source_node); + IrInstGenSpillBegin *instruction = ir_build_inst_void<IrInstGenSpillBegin>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->operand = operand; + instruction->spill_id = spill_id; + + ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstSrc *ir_build_spill_end_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrcSpillBegin *begin) +{ + IrInstSrcSpillEnd *instruction = ir_build_instruction<IrInstSrcSpillEnd>(irb, scope, source_node); instruction->begin = begin; ir_ref_instruction(&begin->base, irb->current_basic_block); @@ -4020,22 +5058,35 @@ static IrInstruction *ir_build_spill_end(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } -static IrInstruction *ir_build_vector_extract_elem(IrAnalyze *ira, IrInstruction *source_instruction, - IrInstruction *vector, IrInstruction *index) +static IrInstGen *ir_build_spill_end_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSpillBegin *begin, + ZigType *result_type) +{ + IrInstGenSpillEnd *instruction = ir_build_inst_gen<IrInstGenSpillEnd>(&ira->new_irb, + source_instr->scope, source_instr->source_node); + instruction->base.value->type = result_type; + instruction->begin = begin; + + ir_ref_inst_gen(&begin->base, ira->new_irb.current_basic_block); + + return &instruction->base; +} + +static IrInstGen *ir_build_vector_extract_elem(IrAnalyze *ira, IrInst *source_instruction, + IrInstGen *vector, IrInstGen *index) { - IrInstructionVectorExtractElem *instruction = ir_build_instruction<IrInstructionVectorExtractElem>( + IrInstGenVectorExtractElem *instruction = ir_build_inst_gen<IrInstGenVectorExtractElem>( &ira->new_irb, source_instruction->scope, source_instruction->source_node); instruction->base.value->type = vector->value->type->data.vector.elem_type; instruction->vector = vector; instruction->index = index; - ir_ref_instruction(vector, ira->new_irb.current_basic_block); - ir_ref_instruction(index, ira->new_irb.current_basic_block); + ir_ref_inst_gen(vector, ira->new_irb.current_basic_block); + ir_ref_inst_gen(index, ira->new_irb.current_basic_block); return &instruction->base; } -static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { +static void ir_count_defers(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { results[ReturnKindUnconditional] = 0; results[ReturnKindError] = 0; @@ -4072,12 +5123,12 @@ static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_sco } } -static IrInstruction *ir_mark_gen(IrInstruction *instruction) { +static IrInstSrc *ir_mark_gen(IrInstSrc *instruction) { instruction->is_gen = true; return instruction; } -static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, bool gen_error_defers) { +static bool ir_gen_defers_for_block(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_scope, bool gen_error_defers) { Scope *scope = inner_scope; bool is_noreturn = false; while (scope != outer_scope) { @@ -4094,11 +5145,9 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o { AstNode *defer_expr_node = defer_node->data.defer.expr; Scope *defer_expr_scope = defer_node->data.defer.expr_scope; - IrInstruction *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope); - if (defer_expr_value != irb->codegen->invalid_instruction) { - if (defer_expr_value->value->type != nullptr && - defer_expr_value->value->type->id == ZigTypeIdUnreachable) - { + IrInstSrc *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope); + if (defer_expr_value != irb->codegen->invalid_inst_src) { + if (defer_expr_value->is_noreturn) { is_noreturn = true; } else { ir_mark_gen(ir_build_check_statement_is_void(irb, defer_expr_scope, defer_expr_node, @@ -4130,13 +5179,17 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o return is_noreturn; } -static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { +static void ir_set_cursor_at_end_gen(IrBuilderGen *irb, IrBasicBlockGen *basic_block) { assert(basic_block); + irb->current_basic_block = basic_block; +} +static void ir_set_cursor_at_end(IrBuilderSrc *irb, IrBasicBlockSrc *basic_block) { + assert(basic_block); irb->current_basic_block = basic_block; } -static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) { +static void ir_set_cursor_at_end_and_append_block(IrBuilderSrc *irb, IrBasicBlockSrc *basic_block) { basic_block->index = irb->exec->basic_block_list.length; irb->exec->basic_block_list.append(basic_block); ir_set_cursor_at_end(irb, basic_block); @@ -4166,22 +5219,16 @@ static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { return nullptr; } -static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { +static IrInstSrc *ir_gen_return(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeReturnExpr); - ZigFn *fn_entry = exec_fn_entry(irb->exec); - if (!fn_entry) { - add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition")); - return irb->codegen->invalid_instruction; - } - ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); if (scope_defer_expr) { if (!scope_defer_expr->reported_err) { add_node_error(irb->codegen, node, buf_sprintf("cannot return from defer expression")); scope_defer_expr->reported_err = true; } - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } Scope *outer_scope = irb->exec->begin_scope; @@ -4194,15 +5241,15 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, result_loc_ret->base.id = ResultLocIdReturn; ir_build_reset_result(irb, scope, node, &result_loc_ret->base); - IrInstruction *return_value; + IrInstSrc *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_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; + if (return_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; } else { return_value = ir_build_const_void(irb, scope, node); } @@ -4215,22 +5262,22 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, if (!have_err_defers && !irb->codegen->have_err_ret_tracing) { // only generate unconditional defers ir_gen_defers_for_block(irb, scope, outer_scope, false); - IrInstruction *result = ir_build_return(irb, scope, node, return_value); + IrInstSrc *result = ir_build_return_src(irb, scope, node, return_value); result_loc_ret->base.source_instruction = result; return result; } bool should_inline = ir_should_inline(irb->exec, scope); - IrBasicBlock *err_block = ir_create_basic_block(irb, scope, "ErrRetErr"); - IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk"); + IrBasicBlockSrc *err_block = ir_create_basic_block(irb, scope, "ErrRetErr"); + IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk"); if (!have_err_defers) { ir_gen_defers_for_block(irb, scope, outer_scope, false); } - IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, return_value, false, true); + IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node, return_value, false, true); - IrInstruction *is_comptime; + IrInstSrc *is_comptime; if (should_inline) { is_comptime = ir_build_const_bool(irb, scope, node, should_inline); } else { @@ -4238,14 +5285,14 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, } ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime)); - IrBasicBlock *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt"); + IrBasicBlockSrc *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt"); ir_set_cursor_at_end_and_append_block(irb, err_block); if (have_err_defers) { ir_gen_defers_for_block(irb, scope, outer_scope, true); } if (irb->codegen->have_err_ret_tracing && !should_inline) { - ir_build_save_err_ret_addr(irb, scope, node); + ir_build_save_err_ret_addr_src(irb, scope, node); } ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); @@ -4256,21 +5303,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); - IrInstruction *result = ir_build_return(irb, scope, node, return_value); + IrInstSrc *result = ir_build_return_src(irb, scope, node, return_value); 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, nullptr); - if (err_union_ptr == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; - IrInstruction *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr, true, false); - - IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); - IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); - IrInstruction *is_comptime; + IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); + if (err_union_ptr == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; + IrInstSrc *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr, true, false); + + IrBasicBlockSrc *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); + IrBasicBlockSrc *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); + IrInstSrc *is_comptime; bool should_inline = ir_should_inline(irb->exec, scope); if (should_inline) { is_comptime = ir_build_const_bool(irb, scope, node, true); @@ -4280,10 +5327,10 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime)); ir_set_cursor_at_end_and_append_block(irb, return_block); - IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); - IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); + IrInstSrc *err_val_ptr = ir_build_unwrap_err_code_src(irb, scope, node, err_union_ptr); + IrInstSrc *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val, nullptr)); - IrInstructionSpillBegin *spill_begin = ir_build_spill_begin(irb, scope, node, err_val, + IrInstSrcSpillBegin *spill_begin = ir_build_spill_begin_src(irb, scope, node, err_val, SpillIdRetErrCode); ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1, "ResultLocReturn"); result_loc_ret->base.id = ResultLocIdReturn; @@ -4291,15 +5338,15 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, ir_build_end_expr(irb, scope, node, err_val, &result_loc_ret->base); if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) { if (irb->codegen->have_err_ret_tracing && !should_inline) { - ir_build_save_err_ret_addr(irb, scope, node); + ir_build_save_err_ret_addr_src(irb, scope, node); } - err_val = ir_build_spill_end(irb, scope, node, spill_begin); - IrInstruction *ret_inst = ir_build_return(irb, scope, node, err_val); + err_val = ir_build_spill_end_src(irb, scope, node, spill_begin); + IrInstSrc *ret_inst = ir_build_return_src(irb, scope, node, err_val); result_loc_ret->base.source_instruction = ret_inst; } ir_set_cursor_at_end_and_append_block(irb, continue_block); - IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false, false); + IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(irb, scope, node, err_union_ptr, false, false); if (lval == LValPtr) return unwrapped_ptr; else @@ -4310,19 +5357,18 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, } static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope, - Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime, + Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime, bool skip_name_check) { ZigVar *variable_entry = allocate<ZigVar>(1, "ZigVar"); variable_entry->parent_scope = parent_scope; variable_entry->shadowable = is_shadowable; - variable_entry->mem_slot_index = SIZE_MAX; variable_entry->is_comptime = is_comptime; variable_entry->src_arg_index = SIZE_MAX; variable_entry->const_value = create_const_vals(1); if (is_comptime != nullptr) { - is_comptime->ref_count += 1; + is_comptime->base.ref_count += 1; } if (name) { @@ -4372,15 +5418,14 @@ static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_s // Set name to nullptr to make the variable anonymous (not visible to programmer). // After you call this function var->child_scope has the variable in scope -static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name, - bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime) +static ZigVar *ir_create_var(IrBuilderSrc *irb, AstNode *node, Scope *scope, Buf *name, + bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime) { bool is_underscored = name ? buf_eql_str(name, "_") : false; ZigVar *var = create_local_var(irb->codegen, node, scope, (is_underscored ? nullptr : name), src_is_const, gen_is_const, (is_underscored ? true : is_shadowable), is_comptime, false); if (is_comptime != nullptr || gen_is_const) { - var->mem_slot_index = exec_next_mem_slot(irb->exec); var->owner_exec = irb->exec; } assert(var->child_scope); @@ -4396,13 +5441,13 @@ static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) { return result; } -static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node, LVal lval, +static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *block_node, LVal lval, ResultLoc *result_loc) { assert(block_node->type == NodeTypeBlock); - ZigList<IrInstruction *> incoming_values = {0}; - ZigList<IrBasicBlock *> incoming_blocks = {0}; + ZigList<IrInstSrc *> incoming_values = {0}; + ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope); @@ -4438,11 +5483,11 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode } bool is_continuation_unreachable = false; - IrInstruction *noreturn_return_value = nullptr; + IrInstSrc *noreturn_return_value = nullptr; for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { AstNode *statement_node = block_node->data.block.statements.at(i); - IrInstruction *statement_value = ir_gen_node(irb, statement_node, child_scope); + IrInstSrc *statement_value = ir_gen_node(irb, statement_node, child_scope); is_continuation_unreachable = instr_is_unreachable(statement_value); if (is_continuation_unreachable) { // keep the last noreturn statement value around in case we need to return it @@ -4450,15 +5495,15 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode } // This logic must be kept in sync with // [STMT_EXPR_TEST_THING] <--- (search this token) - if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) { + if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_inst_src) { // defer starts a new scope child_scope = statement_node->data.defer.child_scope; assert(child_scope); - } else if (statement_value->id == IrInstructionIdDeclVarSrc) { + } else if (statement_value->id == IrInstSrcIdDeclVar) { // variable declarations start a new scope - IrInstructionDeclVarSrc *decl_var_instruction = (IrInstructionDeclVarSrc *)statement_value; + IrInstSrcDeclVar *decl_var_instruction = (IrInstSrcDeclVar *)statement_value; child_scope = decl_var_instruction->var->child_scope; - } else if (statement_value != irb->codegen->invalid_instruction && !is_continuation_unreachable) { + } else if (statement_value != irb->codegen->invalid_inst_src && !is_continuation_unreachable) { // this statement's value must be void ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value)); } @@ -4474,12 +5519,12 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; } ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); - IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, + IrInstSrc *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items, scope_block->peer_parent); return ir_expr_wrap(irb, parent_scope, phi, result_loc); } else { incoming_blocks.append(irb->current_basic_block); - IrInstruction *else_expr_result = ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node)); + IrInstSrc *else_expr_result = ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node)); if (scope_block->peer_parent != nullptr) { ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent); @@ -4499,15 +5544,15 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); } - IrInstruction *result; + IrInstSrc *result; if (block_node->data.block.name != nullptr) { ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); - IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, + IrInstSrc *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items, scope_block->peer_parent); result = ir_expr_wrap(irb, parent_scope, phi, result_loc); } else { - IrInstruction *void_inst = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)); + IrInstSrc *void_inst = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)); result = ir_lval_wrap(irb, parent_scope, void_inst, lval, result_loc); } if (!is_return_from_fn) @@ -4517,31 +5562,35 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode // only generate unconditional defers ir_mark_gen(ir_build_add_implicit_return_type(irb, child_scope, block_node, result, nullptr)); + ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1, "ResultLocReturn"); + result_loc_ret->base.id = ResultLocIdReturn; + ir_build_reset_result(irb, parent_scope, block_node, &result_loc_ret->base); + ir_mark_gen(ir_build_end_expr(irb, parent_scope, block_node, result, &result_loc_ret->base)); ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); - return ir_mark_gen(ir_build_return(irb, child_scope, result->source_node, result)); + return ir_mark_gen(ir_build_return_src(irb, child_scope, result->base.source_node, result)); } -static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { +static IrInstSrc *ir_gen_bin_op_id(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrBinOp op_id) { Scope *inner_scope = scope; if (op_id == IrBinOpArrayCat || op_id == IrBinOpArrayMult) { inner_scope = create_comptime_scope(irb->codegen, node, scope); } - IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, inner_scope); - IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, inner_scope); + IrInstSrc *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, inner_scope); + IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, inner_scope); - if (op1 == irb->codegen->invalid_instruction || op2 == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + if (op1 == irb->codegen->invalid_inst_src || op2 == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; return ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); } -static IrInstruction *ir_gen_merge_err_sets(IrBuilder *irb, Scope *scope, AstNode *node) { - IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); - IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); +static IrInstSrc *ir_gen_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *node) { + IrInstSrc *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); + IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); - if (op1 == irb->codegen->invalid_instruction || op2 == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + if (op1 == irb->codegen->invalid_inst_src || op2 == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; // TODO only pass type_name when the || operator is the top level AST node in the var decl expr Buf bare_name = BUF_INIT; @@ -4550,10 +5599,10 @@ static IrInstruction *ir_gen_merge_err_sets(IrBuilder *irb, Scope *scope, AstNod return ir_build_merge_err_sets(irb, scope, node, op1, op2, type_name); } -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, nullptr); - if (lvalue == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; +static IrInstSrc *ir_gen_assign(IrBuilderSrc *irb, Scope *scope, AstNode *node) { + IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); + if (lvalue == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1, "ResultLocInstruction"); result_loc_inst->base.id = ResultLocIdInstruction; @@ -4561,49 +5610,49 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) ir_ref_instruction(lvalue, irb->current_basic_block); ir_build_reset_result(irb, scope, node, &result_loc_inst->base); - IrInstruction *rvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op2, scope, LValNone, + IrInstSrc *rvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op2, scope, LValNone, &result_loc_inst->base); - if (rvalue == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + if (rvalue == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; return ir_build_const_void(irb, scope, node); } -static IrInstruction *ir_gen_assign_merge_err_sets(IrBuilder *irb, Scope *scope, AstNode *node) { - IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); - if (lvalue == irb->codegen->invalid_instruction) +static IrInstSrc *ir_gen_assign_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *node) { + IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); + if (lvalue == irb->codegen->invalid_inst_src) return lvalue; - IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); - IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); - if (op2 == irb->codegen->invalid_instruction) + IrInstSrc *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); + IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); + if (op2 == irb->codegen->invalid_inst_src) return op2; - IrInstruction *result = ir_build_merge_err_sets(irb, scope, node, op1, op2, nullptr); + IrInstSrc *result = ir_build_merge_err_sets(irb, scope, node, op1, op2, nullptr); ir_build_store_ptr(irb, scope, node, lvalue, result); return ir_build_const_void(irb, scope, 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, nullptr); - if (lvalue == irb->codegen->invalid_instruction) +static IrInstSrc *ir_gen_assign_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrBinOp op_id) { + IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); + if (lvalue == irb->codegen->invalid_inst_src) return lvalue; - IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); - IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); - if (op2 == irb->codegen->invalid_instruction) + IrInstSrc *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); + IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); + if (op2 == irb->codegen->invalid_inst_src) return op2; - IrInstruction *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); + IrInstSrc *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); ir_build_store_ptr(irb, scope, node, lvalue, result); return ir_build_const_void(irb, scope, node); } -static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_bool_or(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeBinOpExpr); - IrInstruction *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); - if (val1 == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; - IrBasicBlock *post_val1_block = irb->current_basic_block; + IrInstSrc *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); + if (val1 == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; + IrBasicBlockSrc *post_val1_block = irb->current_basic_block; - IrInstruction *is_comptime; + IrInstSrc *is_comptime; if (ir_should_inline(irb->exec, scope)) { is_comptime = ir_build_const_bool(irb, scope, node, true); } else { @@ -4611,41 +5660,41 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node } // block for when val1 == false - IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolOrFalse"); + IrBasicBlockSrc *false_block = ir_create_basic_block(irb, scope, "BoolOrFalse"); // block for when val1 == true (don't even evaluate the second part) - IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolOrTrue"); + IrBasicBlockSrc *true_block = ir_create_basic_block(irb, scope, "BoolOrTrue"); ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); ir_set_cursor_at_end_and_append_block(irb, false_block); - IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); - if (val2 == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; - IrBasicBlock *post_val2_block = irb->current_basic_block; + IrInstSrc *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); + if (val2 == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; + IrBasicBlockSrc *post_val2_block = irb->current_basic_block; ir_build_br(irb, scope, node, true_block, is_comptime); ir_set_cursor_at_end_and_append_block(irb, true_block); - IrInstruction **incoming_values = allocate<IrInstruction *>(2, "IrInstruction *"); + IrInstSrc **incoming_values = allocate<IrInstSrc *>(2, "IrInstSrc *"); incoming_values[0] = val1; incoming_values[1] = val2; - IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *"); + IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *"); incoming_blocks[0] = post_val1_block; incoming_blocks[1] = post_val2_block; return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); } -static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_bool_and(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeBinOpExpr); - IrInstruction *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); - if (val1 == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; - IrBasicBlock *post_val1_block = irb->current_basic_block; + IrInstSrc *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); + if (val1 == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; + IrBasicBlockSrc *post_val1_block = irb->current_basic_block; - IrInstruction *is_comptime; + IrInstSrc *is_comptime; if (ir_should_inline(irb->exec, scope)) { is_comptime = ir_build_const_bool(irb, scope, node, true); } else { @@ -4653,34 +5702,34 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod } // block for when val1 == true - IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolAndTrue"); + IrBasicBlockSrc *true_block = ir_create_basic_block(irb, scope, "BoolAndTrue"); // block for when val1 == false (don't even evaluate the second part) - IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolAndFalse"); + IrBasicBlockSrc *false_block = ir_create_basic_block(irb, scope, "BoolAndFalse"); ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); ir_set_cursor_at_end_and_append_block(irb, true_block); - IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); - if (val2 == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; - IrBasicBlock *post_val2_block = irb->current_basic_block; + IrInstSrc *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); + if (val2 == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; + IrBasicBlockSrc *post_val2_block = irb->current_basic_block; ir_build_br(irb, scope, node, false_block, is_comptime); ir_set_cursor_at_end_and_append_block(irb, false_block); - IrInstruction **incoming_values = allocate<IrInstruction *>(2); + IrInstSrc **incoming_values = allocate<IrInstSrc *>(2); incoming_values[0] = val1; incoming_values[1] = val2; - IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *"); + IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *"); incoming_blocks[0] = post_val1_block; incoming_blocks[1] = post_val2_block; return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); } -static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, - IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) +static ResultLocPeerParent *ir_build_result_peers(IrBuilderSrc *irb, IrInstSrc *cond_br_inst, + IrBasicBlockSrc *end_block, ResultLoc *parent, IrInstSrc *is_comptime) { ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); peer_parent->base.id = ResultLocIdPeerParent; @@ -4690,17 +5739,17 @@ static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction peer_parent->is_comptime = is_comptime; peer_parent->parent = parent; - IrInstruction *popped_inst = irb->current_basic_block->instruction_list.pop(); - ir_assert(popped_inst == cond_br_inst, cond_br_inst); + IrInstSrc *popped_inst = irb->current_basic_block->instruction_list.pop(); + ir_assert(popped_inst == cond_br_inst, &cond_br_inst->base); - ir_build_reset_result(irb, cond_br_inst->scope, cond_br_inst->source_node, &peer_parent->base); + ir_build_reset_result(irb, cond_br_inst->base.scope, cond_br_inst->base.source_node, &peer_parent->base); irb->current_basic_block->instruction_list.append(popped_inst); return peer_parent; } -static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst, - IrBasicBlock *else_block, IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime) +static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilderSrc *irb, IrInstSrc *cond_br_inst, + IrBasicBlockSrc *else_block, IrBasicBlockSrc *end_block, ResultLoc *parent, IrInstSrc *is_comptime) { ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, parent, is_comptime); @@ -4713,7 +5762,7 @@ static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilder *irb, IrInstr return peer_parent; } -static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, +static IrInstSrc *ir_gen_orelse(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeBinOpExpr); @@ -4721,73 +5770,73 @@ 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, nullptr); - if (maybe_ptr == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); + if (maybe_ptr == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *maybe_val = ir_build_load_ptr(irb, parent_scope, node, maybe_ptr); - IrInstruction *is_non_null = ir_build_test_nonnull(irb, parent_scope, node, maybe_val); + IrInstSrc *maybe_val = ir_build_load_ptr(irb, parent_scope, node, maybe_ptr); + IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, parent_scope, node, maybe_val); - IrInstruction *is_comptime; + IrInstSrc *is_comptime; if (ir_should_inline(irb->exec, parent_scope)) { is_comptime = ir_build_const_bool(irb, parent_scope, node, true); } else { is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_non_null); } - IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); - IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); - IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); - IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); + IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); + IrBasicBlockSrc *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); + IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); + IrInstSrc *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, result_loc, is_comptime); ir_set_cursor_at_end_and_append_block(irb, null_block); - IrInstruction *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, LValNone, + IrInstSrc *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, LValNone, &peer_parent->peers.at(0)->base); - if (null_result == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; - IrBasicBlock *after_null_block = irb->current_basic_block; + if (null_result == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; + IrBasicBlockSrc *after_null_block = irb->current_basic_block; if (!instr_is_unreachable(null_result)) ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); ir_set_cursor_at_end_and_append_block(irb, ok_block); - IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false, false); - IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); + IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false, false); + IrInstSrc *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); - IrBasicBlock *after_ok_block = irb->current_basic_block; + IrBasicBlockSrc *after_ok_block = irb->current_basic_block; ir_build_br(irb, parent_scope, node, end_block, is_comptime); ir_set_cursor_at_end_and_append_block(irb, end_block); - IrInstruction **incoming_values = allocate<IrInstruction *>(2); + IrInstSrc **incoming_values = allocate<IrInstSrc *>(2); incoming_values[0] = null_result; incoming_values[1] = unwrapped_payload; - IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *"); + IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *"); incoming_blocks[0] = after_null_block; incoming_blocks[1] = after_ok_block; - IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); + IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); } -static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) { +static IrInstSrc *ir_gen_error_union(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { assert(node->type == NodeTypeBinOpExpr); AstNode *op1_node = node->data.bin_op_expr.op1; AstNode *op2_node = node->data.bin_op_expr.op2; - IrInstruction *err_set = ir_gen_node(irb, op1_node, parent_scope); - if (err_set == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *err_set = ir_gen_node(irb, op1_node, parent_scope); + if (err_set == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *payload = ir_gen_node(irb, op2_node, parent_scope); - if (payload == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *payload = ir_gen_node(irb, op2_node, parent_scope); + if (payload == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; return ir_build_error_union(irb, parent_scope, node, err_set, payload); } -static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { +static IrInstSrc *ir_gen_bin_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeBinOpExpr); BinOpType bin_op_type = node->data.bin_op_expr.bin_op; @@ -4880,30 +5929,30 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node, zig_unreachable(); } -static IrInstruction *ir_gen_int_lit(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_int_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeIntLiteral); return ir_build_const_bigint(irb, scope, node, node->data.int_literal.bigint); } -static IrInstruction *ir_gen_float_lit(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_float_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeFloatLiteral); if (node->data.float_literal.overflow) { add_node_error(irb->codegen, node, buf_sprintf("float literal out of range of any type")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } return ir_build_const_bigfloat(irb, scope, node, node->data.float_literal.bigfloat); } -static IrInstruction *ir_gen_char_lit(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_char_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeCharLiteral); return ir_build_const_uint(irb, scope, node, node->data.char_literal.value); } -static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_null_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeNullLiteral); return ir_build_const_null(irb, scope, node); @@ -4921,11 +5970,11 @@ static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); tld_var->base.resolution = TldResolutionInvalid; tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, - g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid); + g->invalid_inst_gen->value, &tld_var->base, g->builtin_types.entry_invalid); scope_decls->decl_table.put(var_name, &tld_var->base); } -static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { +static IrInstSrc *ir_gen_symbol(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { Error err; assert(node->type == NodeTypeSymbol); @@ -4933,15 +5982,16 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, if (buf_eql_str(variable_name, "_")) { if (lval == LValPtr) { - IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node); - const_instruction->base.value->type = get_pointer_to_type(irb->codegen, + IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, node); + const_instruction->value = create_const_vals(1); + const_instruction->value->type = get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_void, false); - const_instruction->base.value->special = ConstValSpecialStatic; - const_instruction->base.value->data.x_ptr.special = ConstPtrSpecialDiscard; + const_instruction->value->special = ConstValSpecialStatic; + const_instruction->value->data.x_ptr.special = ConstPtrSpecialDiscard; return &const_instruction->base; } else { add_node_error(irb->codegen, node, buf_sprintf("`_` may only be used to assign things to")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } } @@ -4951,13 +6001,13 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, add_node_error(irb->codegen, node, buf_sprintf("primitive integer type '%s' exceeds maximum bit width of 65535", buf_ptr(variable_name))); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } assert(err == ErrorPrimitiveTypeNotFound); } else { - IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_type); + IrInstSrc *value = ir_build_const_type(irb, scope, node, primitive_type); if (lval == LValPtr) { - return ir_build_ref(irb, scope, node, value, false, false); + return ir_build_ref_src(irb, scope, node, value, false, false); } else { return ir_expr_wrap(irb, scope, value, result_loc); } @@ -4966,7 +6016,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, ScopeFnDef *crossed_fndef_scope; ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope); if (var) { - IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); + IrInstSrc *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); if (lval == LValPtr) { return var_ptr; } else { @@ -4976,7 +6026,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, Tld *tld = find_decl(irb->codegen, scope, variable_name); if (tld) { - IrInstruction *decl_ref = ir_build_decl_ref(irb, scope, node, tld, lval); + IrInstSrc *decl_ref = ir_build_decl_ref(irb, scope, node, tld, lval); if (lval == LValPtr) { return decl_ref; } else { @@ -4987,50 +6037,50 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, if (get_container_scope(node->owner)->any_imports_failed) { // skip the error message since we had a failing import in this file // if an import breaks we don't need redundant undeclared identifier errors - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } return ir_build_undeclared_identifier(irb, scope, node, variable_name); } -static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, +static IrInstSrc *ir_gen_array_access(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 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, nullptr); - if (array_ref_instruction == irb->codegen->invalid_instruction) + IrInstSrc *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr); + if (array_ref_instruction == irb->codegen->invalid_inst_src) return array_ref_instruction; AstNode *subscript_node = node->data.array_access_expr.subscript; - IrInstruction *subscript_instruction = ir_gen_node(irb, subscript_node, scope); - if (subscript_instruction == irb->codegen->invalid_instruction) + IrInstSrc *subscript_instruction = ir_gen_node(irb, subscript_node, scope); + if (subscript_instruction == irb->codegen->invalid_inst_src) return subscript_instruction; - IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, + IrInstSrc *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, subscript_instruction, true, PtrLenSingle, nullptr); if (lval == LValPtr) return ptr_instruction; - IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); + IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); return ir_expr_wrap(irb, scope, load_ptr, result_loc); } -static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_field_access(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeFieldAccessExpr); 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, nullptr); - if (container_ref_instruction == irb->codegen->invalid_instruction) + IrInstSrc *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr); + if (container_ref_instruction == irb->codegen->invalid_inst_src) return container_ref_instruction; return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name, false); } -static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) { +static IrInstSrc *ir_gen_overflow_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrOverflowOp op) { assert(node->type == NodeTypeFnCallExpr); AstNode *type_node = node->data.fn_call_expr.params.at(0); @@ -5039,26 +6089,26 @@ static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode * AstNode *result_ptr_node = node->data.fn_call_expr.params.at(3); - IrInstruction *type_value = ir_gen_node(irb, type_node, scope); - if (type_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *type_value = ir_gen_node(irb, type_node, scope); + if (type_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *op1 = ir_gen_node(irb, op1_node, scope); - if (op1 == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *op1 = ir_gen_node(irb, op1_node, scope); + if (op1 == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *op2 = ir_gen_node(irb, op2_node, scope); - if (op2 == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *op2 = ir_gen_node(irb, op2_node, scope); + if (op2 == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *result_ptr = ir_gen_node(irb, result_ptr_node, scope); - if (result_ptr == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *result_ptr = ir_gen_node(irb, result_ptr_node, scope); + if (result_ptr == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr); + return ir_build_overflow_op_src(irb, scope, node, op, type_value, op1, op2, result_ptr); } -static IrInstruction *ir_gen_mul_add(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_mul_add(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeFnCallExpr); AstNode *type_node = node->data.fn_call_expr.params.at(0); @@ -5066,26 +6116,26 @@ static IrInstruction *ir_gen_mul_add(IrBuilder *irb, Scope *scope, AstNode *node AstNode *op2_node = node->data.fn_call_expr.params.at(2); AstNode *op3_node = node->data.fn_call_expr.params.at(3); - IrInstruction *type_value = ir_gen_node(irb, type_node, scope); - if (type_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *type_value = ir_gen_node(irb, type_node, scope); + if (type_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *op1 = ir_gen_node(irb, op1_node, scope); - if (op1 == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *op1 = ir_gen_node(irb, op1_node, scope); + if (op1 == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *op2 = ir_gen_node(irb, op2_node, scope); - if (op2 == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *op2 = ir_gen_node(irb, op2_node, scope); + if (op2 == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *op3 = ir_gen_node(irb, op3_node, scope); - if (op3 == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *op3 = ir_gen_node(irb, op3_node, scope); + if (op3 == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - return ir_build_mul_add(irb, scope, node, type_value, op1, op2, op3); + return ir_build_mul_add_src(irb, scope, node, type_value, op1, op2, op3); } -static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *node) { +static IrInstSrc *ir_gen_this(IrBuilderSrc *irb, Scope *orig_scope, AstNode *node) { for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) { if (it_scope->id == ScopeIdDecls) { ScopeDecls *decls_scope = (ScopeDecls *)it_scope; @@ -5100,7 +6150,7 @@ static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *no zig_unreachable(); } -static IrInstruction *ir_gen_async_call(IrBuilder *irb, Scope *scope, AstNode *await_node, AstNode *call_node, +static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *await_node, AstNode *call_node, LVal lval, ResultLoc *result_loc) { size_t arg_offset = 3; @@ -5108,71 +6158,71 @@ static IrInstruction *ir_gen_async_call(IrBuilder *irb, Scope *scope, AstNode *a add_node_error(irb->codegen, call_node, buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, arg_offset, call_node->data.fn_call_expr.params.length)); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } AstNode *bytes_node = call_node->data.fn_call_expr.params.at(0); - IrInstruction *bytes = ir_gen_node(irb, bytes_node, scope); - if (bytes == irb->codegen->invalid_instruction) + IrInstSrc *bytes = ir_gen_node(irb, bytes_node, scope); + if (bytes == irb->codegen->invalid_inst_src) return bytes; AstNode *ret_ptr_node = call_node->data.fn_call_expr.params.at(1); - IrInstruction *ret_ptr = ir_gen_node(irb, ret_ptr_node, scope); - if (ret_ptr == irb->codegen->invalid_instruction) + IrInstSrc *ret_ptr = ir_gen_node(irb, ret_ptr_node, scope); + if (ret_ptr == irb->codegen->invalid_inst_src) return ret_ptr; AstNode *fn_ref_node = call_node->data.fn_call_expr.params.at(2); - IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); - if (fn_ref == irb->codegen->invalid_instruction) + IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); + if (fn_ref == irb->codegen->invalid_inst_src) return fn_ref; size_t arg_count = call_node->data.fn_call_expr.params.length - arg_offset; - IrInstruction **args = allocate<IrInstruction*>(arg_count); + IrInstSrc **args = allocate<IrInstSrc*>(arg_count); for (size_t i = 0; i < arg_count; i += 1) { AstNode *arg_node = call_node->data.fn_call_expr.params.at(i + arg_offset); - IrInstruction *arg = ir_gen_node(irb, arg_node, scope); - if (arg == irb->codegen->invalid_instruction) + IrInstSrc *arg = ir_gen_node(irb, arg_node, scope); + if (arg == irb->codegen->invalid_inst_src) return arg; args[i] = arg; } CallModifier modifier = (await_node == nullptr) ? CallModifierAsync : CallModifierNone; bool is_async_call_builtin = true; - IrInstruction *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args, + IrInstSrc *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args, ret_ptr, modifier, is_async_call_builtin, bytes, result_loc); return ir_lval_wrap(irb, scope, call, lval, result_loc); } -static IrInstruction *ir_gen_fn_call_with_args(IrBuilder *irb, Scope *scope, AstNode *source_node, - AstNode *fn_ref_node, CallModifier modifier, IrInstruction *options, +static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + AstNode *fn_ref_node, CallModifier modifier, IrInstSrc *options, AstNode **args_ptr, size_t args_len, LVal lval, ResultLoc *result_loc) { - IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); - if (fn_ref == irb->codegen->invalid_instruction) + IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); + if (fn_ref == irb->codegen->invalid_inst_src) return fn_ref; - IrInstruction *fn_type = ir_build_typeof(irb, scope, source_node, fn_ref); + IrInstSrc *fn_type = ir_build_typeof(irb, scope, source_node, fn_ref); - IrInstruction **args = allocate<IrInstruction*>(args_len); + IrInstSrc **args = allocate<IrInstSrc*>(args_len); for (size_t i = 0; i < args_len; i += 1) { AstNode *arg_node = args_ptr[i]; - IrInstruction *arg_index = ir_build_const_usize(irb, scope, arg_node, i); - IrInstruction *arg_type = ir_build_arg_type(irb, scope, source_node, fn_type, arg_index, true); + IrInstSrc *arg_index = ir_build_const_usize(irb, scope, arg_node, i); + IrInstSrc *arg_type = ir_build_arg_type(irb, scope, source_node, fn_type, arg_index, true); ResultLoc *no_result = no_result_loc(); ir_build_reset_result(irb, scope, source_node, no_result); ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result); - IrInstruction *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base); - if (arg == irb->codegen->invalid_instruction) + IrInstSrc *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base); + if (arg == irb->codegen->invalid_inst_src) return arg; args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast); } - IrInstruction *fn_call; + IrInstSrc *fn_call; if (options != nullptr) { - fn_call = ir_build_call_src_args(irb, scope, source_node, options, fn_ref, args, args_len, result_loc); + fn_call = ir_build_call_args(irb, scope, source_node, options, fn_ref, args, args_len, result_loc); } else { fn_call = ir_build_call_src(irb, scope, source_node, nullptr, fn_ref, args_len, args, nullptr, modifier, false, nullptr, result_loc); @@ -5180,7 +6230,7 @@ static IrInstruction *ir_gen_fn_call_with_args(IrBuilder *irb, Scope *scope, Ast return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); } -static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, +static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeFnCallExpr); @@ -5192,7 +6242,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo if (!entry) { add_node_error(irb->codegen, node, buf_sprintf("invalid builtin function: '%s'", buf_ptr(name))); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } BuiltinFnEntry *builtin_fn = entry->value; @@ -5202,7 +6252,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo add_node_error(irb->codegen, node, buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, builtin_fn->param_count, actual_param_count)); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } switch (builtin_fn->id) { @@ -5213,197 +6263,197 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo Scope *sub_scope = create_typeof_scope(irb->codegen, node, scope); AstNode *arg_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg = ir_gen_node(irb, arg_node, sub_scope); - if (arg == irb->codegen->invalid_instruction) + IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope); + if (arg == irb->codegen->invalid_inst_src) return arg; - IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg); + IrInstSrc *type_of = ir_build_typeof(irb, scope, node, arg); return ir_lval_wrap(irb, scope, type_of, lval, result_loc); } case BuiltinFnIdSetCold: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); + IrInstSrc *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, set_cold, lval, result_loc); } case BuiltinFnIdSetRuntimeSafety: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); + IrInstSrc *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, set_safety, lval, result_loc); } case BuiltinFnIdSetFloatMode: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value); + IrInstSrc *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc); } case BuiltinFnIdSizeof: case BuiltinFnIdBitSizeof: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value, builtin_fn->id == BuiltinFnIdBitSizeof); + IrInstSrc *size_of = ir_build_size_of(irb, scope, node, arg0_value, builtin_fn->id == BuiltinFnIdBitSizeof); return ir_lval_wrap(irb, scope, size_of, lval, result_loc); } case BuiltinFnIdImport: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *import = ir_build_import(irb, scope, node, arg0_value); + IrInstSrc *import = ir_build_import(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, import, lval, result_loc); } case BuiltinFnIdCImport: { - IrInstruction *c_import = ir_build_c_import(irb, scope, node); + IrInstSrc *c_import = ir_build_c_import(irb, scope, node); return ir_lval_wrap(irb, scope, c_import, lval, result_loc); } case BuiltinFnIdCInclude: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; if (!exec_c_import_buf(irb->exec)) { add_node_error(irb->codegen, node, buf_sprintf("C include valid only inside C import block")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } - IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value); + IrInstSrc *c_include = ir_build_c_include(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, c_include, lval, result_loc); } case BuiltinFnIdCDefine: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; if (!exec_c_import_buf(irb->exec)) { add_node_error(irb->codegen, node, buf_sprintf("C define valid only inside C import block")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } - IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, c_define, lval, result_loc); } case BuiltinFnIdCUndef: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; if (!exec_c_import_buf(irb->exec)) { add_node_error(irb->codegen, node, buf_sprintf("C undef valid only inside C import block")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } - IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); + IrInstSrc *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, c_undef, lval, result_loc); } case BuiltinFnIdCompileErr: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); + IrInstSrc *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, compile_err, lval, result_loc); } case BuiltinFnIdCompileLog: { - IrInstruction **args = allocate<IrInstruction*>(actual_param_count); + IrInstSrc **args = allocate<IrInstSrc*>(actual_param_count); for (size_t i = 0; i < actual_param_count; i += 1) { AstNode *arg_node = node->data.fn_call_expr.params.at(i); args[i] = ir_gen_node(irb, arg_node, scope); - if (args[i] == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + if (args[i] == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; } - IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); + IrInstSrc *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); return ir_lval_wrap(irb, scope, compile_log, lval, result_loc); } case BuiltinFnIdErrName: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value); + IrInstSrc *err_name = ir_build_err_name(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, err_name, lval, result_loc); } case BuiltinFnIdEmbedFile: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); + IrInstSrc *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, embed_file, lval, result_loc); } case BuiltinFnIdCmpxchgWeak: case BuiltinFnIdCmpxchgStrong: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; AstNode *arg2_node = node->data.fn_call_expr.params.at(2); - IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); - if (arg2_value == irb->codegen->invalid_instruction) + IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); + if (arg2_value == irb->codegen->invalid_inst_src) return arg2_value; AstNode *arg3_node = node->data.fn_call_expr.params.at(3); - IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); - if (arg3_value == irb->codegen->invalid_instruction) + IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); + if (arg3_value == irb->codegen->invalid_inst_src) return arg3_value; AstNode *arg4_node = node->data.fn_call_expr.params.at(4); - IrInstruction *arg4_value = ir_gen_node(irb, arg4_node, scope); - if (arg4_value == irb->codegen->invalid_instruction) + IrInstSrc *arg4_value = ir_gen_node(irb, arg4_node, scope); + if (arg4_value == irb->codegen->invalid_inst_src) return arg4_value; AstNode *arg5_node = node->data.fn_call_expr.params.at(5); - IrInstruction *arg5_value = ir_gen_node(irb, arg5_node, scope); - if (arg5_value == irb->codegen->invalid_instruction) + IrInstSrc *arg5_value = ir_gen_node(irb, arg5_node, scope); + if (arg5_value == irb->codegen->invalid_inst_src) return arg5_value; - IrInstruction *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value, + IrInstSrc *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak), result_loc); return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc); @@ -5411,86 +6461,86 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo case BuiltinFnIdFence: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered); + IrInstSrc *fence = ir_build_fence(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, fence, lval, result_loc); } case BuiltinFnIdDivExact: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); + IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); } case BuiltinFnIdDivTrunc: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); + IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); } case BuiltinFnIdDivFloor: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); + IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); } case BuiltinFnIdRem: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); + IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); } case BuiltinFnIdMod: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); + IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); } case BuiltinFnIdSqrt: @@ -5509,406 +6559,406 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo case BuiltinFnIdRound: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *inst = ir_build_float_op(irb, scope, node, arg0_value, builtin_fn->id); + IrInstSrc *inst = ir_build_float_op_src(irb, scope, node, arg0_value, builtin_fn->id); return ir_lval_wrap(irb, scope, inst, lval, result_loc); } case BuiltinFnIdTruncate: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, truncate, lval, result_loc); } case BuiltinFnIdIntCast: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, result, lval, result_loc); } case BuiltinFnIdFloatCast: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, result, lval, result_loc); } case BuiltinFnIdErrSetCast: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, result, lval, result_loc); } case BuiltinFnIdFromBytes: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value, result_loc); + IrInstSrc *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value, result_loc); return ir_lval_wrap(irb, scope, result, lval, result_loc); } case BuiltinFnIdToBytes: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value, result_loc); + IrInstSrc *result = ir_build_to_bytes(irb, scope, node, arg0_value, result_loc); return ir_lval_wrap(irb, scope, result, lval, result_loc); } case BuiltinFnIdIntToFloat: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, result, lval, result_loc); } case BuiltinFnIdFloatToInt: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, result, lval, result_loc); } case BuiltinFnIdErrToInt: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *result = ir_build_err_to_int(irb, scope, node, arg0_value); + IrInstSrc *result = ir_build_err_to_int_src(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, result, lval, result_loc); } case BuiltinFnIdIntToErr: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *result = ir_build_int_to_err(irb, scope, node, arg0_value); + IrInstSrc *result = ir_build_int_to_err_src(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, result, lval, result_loc); } case BuiltinFnIdBoolToInt: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value); + IrInstSrc *result = ir_build_bool_to_int(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, result, lval, result_loc); } case BuiltinFnIdIntType: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, int_type, lval, result_loc); } case BuiltinFnIdVectorType: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, vector_type, lval, result_loc); } case BuiltinFnIdShuffle: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; AstNode *arg2_node = node->data.fn_call_expr.params.at(2); - IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); - if (arg2_value == irb->codegen->invalid_instruction) + IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); + if (arg2_value == irb->codegen->invalid_inst_src) return arg2_value; AstNode *arg3_node = node->data.fn_call_expr.params.at(3); - IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); - if (arg3_value == irb->codegen->invalid_instruction) + IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); + if (arg3_value == irb->codegen->invalid_inst_src) return arg3_value; - IrInstruction *shuffle_vector = ir_build_shuffle_vector(irb, scope, node, + IrInstSrc *shuffle_vector = ir_build_shuffle_vector(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value); return ir_lval_wrap(irb, scope, shuffle_vector, lval, result_loc); } case BuiltinFnIdSplat: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *splat = ir_build_splat_src(irb, scope, node, + IrInstSrc *splat = ir_build_splat_src(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, splat, lval, result_loc); } case BuiltinFnIdMemcpy: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; AstNode *arg2_node = node->data.fn_call_expr.params.at(2); - IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); - if (arg2_value == irb->codegen->invalid_instruction) + IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); + if (arg2_value == irb->codegen->invalid_inst_src) return arg2_value; - IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value); + IrInstSrc *ir_memcpy = ir_build_memcpy_src(irb, scope, node, arg0_value, arg1_value, arg2_value); return ir_lval_wrap(irb, scope, ir_memcpy, lval, result_loc); } case BuiltinFnIdMemset: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; AstNode *arg2_node = node->data.fn_call_expr.params.at(2); - IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); - if (arg2_value == irb->codegen->invalid_instruction) + IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); + if (arg2_value == irb->codegen->invalid_inst_src) return arg2_value; - IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value); + IrInstSrc *ir_memset = ir_build_memset_src(irb, scope, node, arg0_value, arg1_value, arg2_value); return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc); } case BuiltinFnIdMemberCount: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value); + IrInstSrc *member_count = ir_build_member_count(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, member_count, lval, result_loc); } case BuiltinFnIdMemberType: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, member_type, lval, result_loc); } case BuiltinFnIdMemberName: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, member_name, lval, result_loc); } 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, nullptr); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, + IrInstSrc *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, arg0_value, arg1_value, false); if (lval == LValPtr) return ptr_instruction; - IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); + IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); return ir_expr_wrap(irb, scope, load_ptr, result_loc); } case BuiltinFnIdHasField: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *type_info = ir_build_has_field(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *type_info = ir_build_has_field(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, type_info, lval, result_loc); } case BuiltinFnIdTypeInfo: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value); + IrInstSrc *type_info = ir_build_type_info(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, type_info, lval, result_loc); } case BuiltinFnIdType: { AstNode *arg_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg = ir_gen_node(irb, arg_node, scope); - if (arg == irb->codegen->invalid_instruction) + IrInstSrc *arg = ir_gen_node(irb, arg_node, scope); + if (arg == irb->codegen->invalid_inst_src) return arg; - IrInstruction *type = ir_build_type(irb, scope, node, arg); + IrInstSrc *type = ir_build_type(irb, scope, node, arg); return ir_lval_wrap(irb, scope, type, lval, result_loc); } case BuiltinFnIdBreakpoint: return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval, result_loc); case BuiltinFnIdReturnAddress: - return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval, result_loc); + return ir_lval_wrap(irb, scope, ir_build_return_address_src(irb, scope, node), lval, result_loc); case BuiltinFnIdFrameAddress: - return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval, result_loc); + return ir_lval_wrap(irb, scope, ir_build_frame_address_src(irb, scope, node), lval, result_loc); case BuiltinFnIdFrameHandle: if (!irb->exec->fn_entry) { add_node_error(irb->codegen, node, buf_sprintf("@frame() called outside of function definition")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } - return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval, result_loc); + return ir_lval_wrap(irb, scope, ir_build_handle_src(irb, scope, node), lval, result_loc); case BuiltinFnIdFrameType: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *frame_type = ir_build_frame_type(irb, scope, node, arg0_value); + IrInstSrc *frame_type = ir_build_frame_type(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, frame_type, lval, result_loc); } case BuiltinFnIdFrameSize: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *frame_size = ir_build_frame_size_src(irb, scope, node, arg0_value); + IrInstSrc *frame_size = ir_build_frame_size_src(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, frame_size, lval, result_loc); } case BuiltinFnIdAlignOf: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value); + IrInstSrc *align_of = ir_build_align_of(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, align_of, lval, result_loc); } case BuiltinFnIdAddWithOverflow: @@ -5924,173 +6974,175 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo case BuiltinFnIdTypeName: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value); + IrInstSrc *type_name = ir_build_type_name(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, type_name, lval, result_loc); } case BuiltinFnIdPanic: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value); + IrInstSrc *panic = ir_build_panic_src(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, panic, lval, result_loc); } case BuiltinFnIdPtrCast: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true); + IrInstSrc *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true); return ir_lval_wrap(irb, scope, ptr_cast, lval, result_loc); } case BuiltinFnIdBitCast: { AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); - IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope); - if (dest_type == irb->codegen->invalid_instruction) + IrInstSrc *dest_type = ir_gen_node(irb, dest_type_node, scope); + if (dest_type == irb->codegen->invalid_inst_src) return dest_type; ResultLocBitCast *result_loc_bit_cast = allocate<ResultLocBitCast>(1); result_loc_bit_cast->base.id = ResultLocIdBitCast; result_loc_bit_cast->base.source_instruction = dest_type; + result_loc_bit_cast->base.allow_write_through_const = result_loc->allow_write_through_const; ir_ref_instruction(dest_type, irb->current_basic_block); result_loc_bit_cast->parent = result_loc; ir_build_reset_result(irb, scope, node, &result_loc_bit_cast->base); AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, + IrInstSrc *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, &result_loc_bit_cast->base); - if (arg1_value == irb->codegen->invalid_instruction) + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast); + IrInstSrc *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast); return ir_lval_wrap(irb, scope, bitcast, lval, result_loc); } case BuiltinFnIdAs: { AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); - IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope); - if (dest_type == irb->codegen->invalid_instruction) + IrInstSrc *dest_type = ir_gen_node(irb, dest_type_node, scope); + if (dest_type == irb->codegen->invalid_inst_src) return dest_type; ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, dest_type, result_loc); AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, + IrInstSrc *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, &result_loc_cast->base); - if (arg1_value == irb->codegen->invalid_instruction) + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *result = ir_build_implicit_cast(irb, scope, node, arg1_value, result_loc_cast); + IrInstSrc *result = ir_build_implicit_cast(irb, scope, node, arg1_value, result_loc_cast); return ir_lval_wrap(irb, scope, result, lval, result_loc); } case BuiltinFnIdIntToPtr: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *int_to_ptr = ir_build_int_to_ptr_src(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, int_to_ptr, lval, result_loc); } case BuiltinFnIdPtrToInt: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value); + IrInstSrc *ptr_to_int = ir_build_ptr_to_int_src(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, ptr_to_int, lval, result_loc); } case BuiltinFnIdTagName: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, arg0_value); + IrInstSrc *tag_name = ir_build_tag_name_src(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, tag_name, lval, result_loc); } case BuiltinFnIdTagType: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); + IrInstSrc *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, tag_type, lval, result_loc); } case BuiltinFnIdFieldParentPtr: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; AstNode *arg2_node = node->data.fn_call_expr.params.at(2); - IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); - if (arg2_value == irb->codegen->invalid_instruction) + IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); + if (arg2_value == irb->codegen->invalid_inst_src) return arg2_value; - IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr); + IrInstSrc *field_parent_ptr = ir_build_field_parent_ptr_src(irb, scope, node, + arg0_value, arg1_value, arg2_value); return ir_lval_wrap(irb, scope, field_parent_ptr, lval, result_loc); } case BuiltinFnIdByteOffsetOf: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); } case BuiltinFnIdBitOffsetOf: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); } case BuiltinFnIdNewStackCall: @@ -6099,45 +7151,45 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo add_node_error(irb->codegen, node, buf_sprintf("expected at least 2 arguments, found %" ZIG_PRI_usize, node->data.fn_call_expr.params.length)); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } AstNode *new_stack_node = node->data.fn_call_expr.params.at(0); - IrInstruction *new_stack = ir_gen_node(irb, new_stack_node, scope); - if (new_stack == irb->codegen->invalid_instruction) + IrInstSrc *new_stack = ir_gen_node(irb, new_stack_node, scope); + if (new_stack == irb->codegen->invalid_inst_src) return new_stack; AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); - IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); - if (fn_ref == irb->codegen->invalid_instruction) + IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); + if (fn_ref == irb->codegen->invalid_inst_src) return fn_ref; size_t arg_count = node->data.fn_call_expr.params.length - 2; - IrInstruction **args = allocate<IrInstruction*>(arg_count); + IrInstSrc **args = allocate<IrInstSrc*>(arg_count); for (size_t i = 0; i < arg_count; i += 1) { AstNode *arg_node = node->data.fn_call_expr.params.at(i + 2); args[i] = ir_gen_node(irb, arg_node, scope); - if (args[i] == irb->codegen->invalid_instruction) + if (args[i] == irb->codegen->invalid_inst_src) return args[i]; } - IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, + IrInstSrc *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, nullptr, CallModifierNone, false, new_stack, result_loc); return ir_lval_wrap(irb, scope, call, lval, result_loc); } case BuiltinFnIdCall: { // Cast the options parameter to the options type ZigType *options_type = get_builtin_type(irb->codegen, "CallOptions"); - IrInstruction *options_type_inst = ir_build_const_type(irb, scope, node, options_type); + IrInstSrc *options_type_inst = ir_build_const_type(irb, scope, node, options_type); ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, options_type_inst, no_result_loc()); AstNode *options_node = node->data.fn_call_expr.params.at(0); - IrInstruction *options_inner = ir_gen_node_extra(irb, options_node, scope, + IrInstSrc *options_inner = ir_gen_node_extra(irb, options_node, scope, LValNone, &result_loc_cast->base); - if (options_inner == irb->codegen->invalid_instruction) + if (options_inner == irb->codegen->invalid_inst_src) return options_inner; - IrInstruction *options = ir_build_implicit_cast(irb, scope, options_node, options_inner, result_loc_cast); + IrInstSrc *options = ir_build_implicit_cast(irb, scope, options_node, options_inner, result_loc_cast); AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); AstNode *args_node = node->data.fn_call_expr.params.at(2); @@ -6153,18 +7205,18 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo } else { exec_add_error_node(irb->codegen, irb->exec, args_node, buf_sprintf("TODO: @call with anon struct literal")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } } else { - IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); - if (fn_ref == irb->codegen->invalid_instruction) + IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); + if (fn_ref == irb->codegen->invalid_inst_src) return fn_ref; - IrInstruction *args = ir_gen_node(irb, args_node, scope); - if (args == irb->codegen->invalid_instruction) + IrInstSrc *args = ir_gen_node(irb, args_node, scope); + if (args == irb->codegen->invalid_inst_src) return args; - IrInstruction *call = ir_build_call_extra(irb, scope, node, options, fn_ref, args, result_loc); + IrInstSrc *call = ir_build_call_extra(irb, scope, node, options, fn_ref, args, result_loc); return ir_lval_wrap(irb, scope, call, lval, result_loc); } } @@ -6173,237 +7225,233 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo case BuiltinFnIdTypeId: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value); + IrInstSrc *type_id = ir_build_type_id(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, type_id, lval, result_loc); } case BuiltinFnIdShlExact: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); + IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); } case BuiltinFnIdShrExact: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); + IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); } case BuiltinFnIdSetEvalBranchQuota: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); + IrInstSrc *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval, result_loc); } case BuiltinFnIdAlignCast: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *align_cast = ir_build_align_cast_src(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, align_cast, lval, result_loc); } case BuiltinFnIdOpaqueType: { - IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node); + IrInstSrc *opaque_type = ir_build_opaque_type(irb, scope, node); return ir_lval_wrap(irb, scope, opaque_type, lval, result_loc); } case BuiltinFnIdThis: { - IrInstruction *this_inst = ir_gen_this(irb, scope, node); + IrInstSrc *this_inst = ir_gen_this(irb, scope, node); return ir_lval_wrap(irb, scope, this_inst, lval, result_loc); } case BuiltinFnIdSetAlignStack: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); + IrInstSrc *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc); } case BuiltinFnIdArgType: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value, false); + IrInstSrc *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value, false); return ir_lval_wrap(irb, scope, arg_type, lval, result_loc); } case BuiltinFnIdExport: { // Cast the options parameter to the options type ZigType *options_type = get_builtin_type(irb->codegen, "ExportOptions"); - IrInstruction *options_type_inst = ir_build_const_type(irb, scope, node, options_type); + IrInstSrc *options_type_inst = ir_build_const_type(irb, scope, node, options_type); ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, options_type_inst, no_result_loc()); AstNode *target_node = node->data.fn_call_expr.params.at(0); - IrInstruction *target_value = ir_gen_node(irb, target_node, scope); - if (target_value == irb->codegen->invalid_instruction) + IrInstSrc *target_value = ir_gen_node(irb, target_node, scope); + if (target_value == irb->codegen->invalid_inst_src) return target_value; AstNode *options_node = node->data.fn_call_expr.params.at(1); - IrInstruction *options_value = ir_gen_node_extra(irb, options_node, + IrInstSrc *options_value = ir_gen_node_extra(irb, options_node, scope, LValNone, &result_loc_cast->base); - if (options_value == irb->codegen->invalid_instruction) + if (options_value == irb->codegen->invalid_inst_src) return options_value; - IrInstruction *casted_options_value = ir_build_implicit_cast( + IrInstSrc *casted_options_value = ir_build_implicit_cast( irb, scope, options_node, options_value, result_loc_cast); - IrInstruction *ir_export = ir_build_export(irb, scope, node, target_value, casted_options_value); + IrInstSrc *ir_export = ir_build_export(irb, scope, node, target_value, casted_options_value); return ir_lval_wrap(irb, scope, ir_export, lval, result_loc); } case BuiltinFnIdErrorReturnTrace: { - IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null); + IrInstSrc *error_return_trace = ir_build_error_return_trace_src(irb, scope, node, + IrInstErrorReturnTraceNull); return ir_lval_wrap(irb, scope, error_return_trace, lval, result_loc); } case BuiltinFnIdAtomicRmw: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; AstNode *arg2_node = node->data.fn_call_expr.params.at(2); - IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); - if (arg2_value == irb->codegen->invalid_instruction) + IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); + if (arg2_value == irb->codegen->invalid_inst_src) return arg2_value; AstNode *arg3_node = node->data.fn_call_expr.params.at(3); - IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); - if (arg3_value == irb->codegen->invalid_instruction) + IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); + if (arg3_value == irb->codegen->invalid_inst_src) return arg3_value; AstNode *arg4_node = node->data.fn_call_expr.params.at(4); - IrInstruction *arg4_value = ir_gen_node(irb, arg4_node, scope); - if (arg4_value == irb->codegen->invalid_instruction) + IrInstSrc *arg4_value = ir_gen_node(irb, arg4_node, scope); + if (arg4_value == irb->codegen->invalid_inst_src) return arg4_value; - IrInstruction *inst = ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, - arg4_value, - // these 2 values don't mean anything since we passed non-null values for other args - AtomicRmwOp_xchg, AtomicOrderMonotonic); + IrInstSrc *inst = ir_build_atomic_rmw_src(irb, scope, node, + arg0_value, arg1_value, arg2_value, arg3_value, arg4_value); return ir_lval_wrap(irb, scope, inst, lval, result_loc); } case BuiltinFnIdAtomicLoad: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; AstNode *arg2_node = node->data.fn_call_expr.params.at(2); - IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); - if (arg2_value == irb->codegen->invalid_instruction) + IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); + if (arg2_value == irb->codegen->invalid_inst_src) return arg2_value; - IrInstruction *inst = ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value, - // this value does not mean anything since we passed non-null values for other arg - AtomicOrderMonotonic); + IrInstSrc *inst = ir_build_atomic_load_src(irb, scope, node, arg0_value, arg1_value, arg2_value); return ir_lval_wrap(irb, scope, inst, lval, result_loc); } case BuiltinFnIdAtomicStore: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; AstNode *arg2_node = node->data.fn_call_expr.params.at(2); - IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); - if (arg2_value == irb->codegen->invalid_instruction) + IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); + if (arg2_value == irb->codegen->invalid_inst_src) return arg2_value; AstNode *arg3_node = node->data.fn_call_expr.params.at(3); - IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); - if (arg3_value == irb->codegen->invalid_instruction) + IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); + if (arg3_value == irb->codegen->invalid_inst_src) return arg3_value; - IrInstruction *inst = ir_build_atomic_store(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, - // this value does not mean anything since we passed non-null values for other arg - AtomicOrderMonotonic); + IrInstSrc *inst = ir_build_atomic_store_src(irb, scope, node, arg0_value, arg1_value, + arg2_value, arg3_value); return ir_lval_wrap(irb, scope, inst, lval, result_loc); } case BuiltinFnIdIntToEnum: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *result = ir_build_int_to_enum(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *result = ir_build_int_to_enum_src(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, result, lval, result_loc); } case BuiltinFnIdEnumToInt: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; - IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); + IrInstSrc *result = ir_build_enum_to_int(irb, scope, node, arg0_value); return ir_lval_wrap(irb, scope, result, lval, result_loc); } case BuiltinFnIdCtz: @@ -6413,16 +7461,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo case BuiltinFnIdBitReverse: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *result; + IrInstSrc *result; switch (builtin_fn->id) { case BuiltinFnIdCtz: result = ir_build_ctz(irb, scope, node, arg0_value, arg1_value); @@ -6447,28 +7495,28 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo case BuiltinFnIdHasDecl: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) + IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_inst_src) return arg0_value; AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) + IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_inst_src) return arg1_value; - IrInstruction *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value); + IrInstSrc *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, has_decl, lval, result_loc); } case BuiltinFnIdUnionInit: { AstNode *union_type_node = node->data.fn_call_expr.params.at(0); - IrInstruction *union_type_inst = ir_gen_node(irb, union_type_node, scope); - if (union_type_inst == irb->codegen->invalid_instruction) + IrInstSrc *union_type_inst = ir_gen_node(irb, union_type_node, scope); + if (union_type_inst == irb->codegen->invalid_inst_src) return union_type_inst; AstNode *name_node = node->data.fn_call_expr.params.at(1); - IrInstruction *name_inst = ir_gen_node(irb, name_node, scope); - if (name_inst == irb->codegen->invalid_instruction) + IrInstSrc *name_inst = ir_gen_node(irb, name_node, scope); + if (name_inst == irb->codegen->invalid_inst_src) return name_inst; AstNode *init_node = node->data.fn_call_expr.params.at(2); @@ -6480,7 +7528,7 @@ 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 IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeFnCallExpr); @@ -6493,16 +7541,16 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node nullptr, node->data.fn_call_expr.params.items, node->data.fn_call_expr.params.length, lval, result_loc); } -static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, +static IrInstSrc *ir_gen_if_bool_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeIfBoolExpr); - IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); - if (condition == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); + if (condition == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *is_comptime; + IrInstSrc *is_comptime; if (ir_should_inline(irb->exec, scope)) { is_comptime = ir_build_const_bool(irb, scope, node, true); } else { @@ -6512,11 +7560,11 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode AstNode *then_node = node->data.if_bool_expr.then_block; AstNode *else_node = node->data.if_bool_expr.else_node; - IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "Then"); - IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else"); - IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf"); + IrBasicBlockSrc *then_block = ir_create_basic_block(irb, scope, "Then"); + IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "Else"); + IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "EndIf"); - IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, condition, + IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, condition, then_block, else_block, is_comptime); ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, result_loc, is_comptime); @@ -6524,70 +7572,70 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode ir_set_cursor_at_end_and_append_block(irb, then_block); Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); - IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval, + IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval, &peer_parent->peers.at(0)->base); - if (then_expr_result == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; - IrBasicBlock *after_then_block = irb->current_basic_block; + if (then_expr_result == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; + IrBasicBlockSrc *after_then_block = irb->current_basic_block; if (!instr_is_unreachable(then_expr_result)) ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); ir_set_cursor_at_end_and_append_block(irb, else_block); - IrInstruction *else_expr_result; + IrInstSrc *else_expr_result; if (else_node) { else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); - if (else_expr_result == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + if (else_expr_result == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; } else { else_expr_result = ir_build_const_void(irb, scope, node); ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); } - IrBasicBlock *after_else_block = irb->current_basic_block; + IrBasicBlockSrc *after_else_block = irb->current_basic_block; if (!instr_is_unreachable(else_expr_result)) ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); ir_set_cursor_at_end_and_append_block(irb, endif_block); - IrInstruction **incoming_values = allocate<IrInstruction *>(2); + IrInstSrc **incoming_values = allocate<IrInstSrc *>(2); incoming_values[0] = then_expr_result; incoming_values[1] = else_expr_result; - IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *"); + IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *"); incoming_blocks[0] = after_then_block; incoming_blocks[1] = after_else_block; - IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); + IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); return ir_expr_wrap(irb, scope, phi, result_loc); } -static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { +static IrInstSrc *ir_gen_prefix_op_id_lval(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { 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, nullptr); - if (value == irb->codegen->invalid_instruction) + IrInstSrc *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); + if (value == irb->codegen->invalid_inst_src) return value; return ir_build_un_op(irb, scope, node, op_id, value); } -static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id) { +static IrInstSrc *ir_gen_prefix_op_id(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrUnOp op_id) { return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone); } -static IrInstruction *ir_expr_wrap(IrBuilder *irb, Scope *scope, IrInstruction *inst, ResultLoc *result_loc) { - if (inst == irb->codegen->invalid_instruction) return inst; - ir_build_end_expr(irb, scope, inst->source_node, inst, result_loc); +static IrInstSrc *ir_expr_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *inst, ResultLoc *result_loc) { + if (inst == irb->codegen->invalid_inst_src) return inst; + ir_build_end_expr(irb, scope, inst->base.source_node, inst, result_loc); return inst; } -static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval, +static IrInstSrc *ir_lval_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *value, LVal lval, ResultLoc *result_loc) { // This logic must be kept in sync with // [STMT_EXPR_TEST_THING] <--- (search this token) - if (value == irb->codegen->invalid_instruction || + if (value == irb->codegen->invalid_inst_src || instr_is_unreachable(value) || - value->source_node->type == NodeTypeDefer || - value->id == IrInstructionIdDeclVarSrc) + value->base.source_node->type == NodeTypeDefer || + value->id == IrInstSrcIdDeclVar) { return value; } @@ -6595,7 +7643,7 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction * if (lval == LValPtr) { // We needed a pointer to a value, but we got a value. So we create // an instruction which just makes a pointer of it. - return ir_build_ref(irb, scope, value->source_node, value, false, false); + return ir_build_ref_src(irb, scope, value->base.source_node, value, false, false); } else if (result_loc != nullptr) { return ir_expr_wrap(irb, scope, value, result_loc); } else { @@ -6618,7 +7666,7 @@ static PtrLen star_token_to_ptr_len(TokenId token_id) { } } -static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_pointer_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypePointerType); PtrLen ptr_len = star_token_to_ptr_len(node->data.pointer_type.star_token->id); @@ -6630,26 +7678,26 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode AstNode *expr_node = node->data.pointer_type.op_expr; AstNode *align_expr = node->data.pointer_type.align_expr; - IrInstruction *sentinel; + IrInstSrc *sentinel; if (sentinel_expr != nullptr) { sentinel = ir_gen_node(irb, sentinel_expr, scope); - if (sentinel == irb->codegen->invalid_instruction) + if (sentinel == irb->codegen->invalid_inst_src) return sentinel; } else { sentinel = nullptr; } - IrInstruction *align_value; + IrInstSrc *align_value; if (align_expr != nullptr) { align_value = ir_gen_node(irb, align_expr, scope); - if (align_value == irb->codegen->invalid_instruction) + if (align_value == irb->codegen->invalid_inst_src) return align_value; } else { align_value = nullptr; } - IrInstruction *child_type = ir_gen_node(irb, expr_node, scope); - if (child_type == irb->codegen->invalid_instruction) + IrInstSrc *child_type = ir_gen_node(irb, expr_node, scope); + if (child_type == irb->codegen->invalid_inst_src) return child_type; uint32_t bit_offset_start = 0; @@ -6659,7 +7707,7 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_start, 10); exec_add_error_node(irb->codegen, irb->exec, node, buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf))); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } bit_offset_start = bigint_as_u32(node->data.pointer_type.bit_offset_start); } @@ -6671,7 +7719,7 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode bigint_append_buf(val_buf, node->data.pointer_type.host_int_bytes, 10); exec_add_error_node(irb->codegen, irb->exec, node, buf_sprintf("value %s too large for u32 byte count", buf_ptr(val_buf))); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } host_int_bytes = bigint_as_u32(node->data.pointer_type.host_int_bytes); } @@ -6679,43 +7727,43 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode if (host_int_bytes != 0 && bit_offset_start >= host_int_bytes * 8) { exec_add_error_node(irb->codegen, irb->exec, node, buf_sprintf("bit offset starts after end of host integer")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile, ptr_len, sentinel, align_value, bit_offset_start, host_int_bytes, is_allow_zero); } -static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, +static IrInstSrc *ir_gen_catch_unreachable(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, AstNode *expr_node, LVal lval, ResultLoc *result_loc) { - 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; + IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); + if (err_union_ptr == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true, false); - if (payload_ptr == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, scope, source_node, err_union_ptr, true, false); + if (payload_ptr == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; if (lval == LValPtr) return payload_ptr; - IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, source_node, payload_ptr); + IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, source_node, payload_ptr); return ir_expr_wrap(irb, scope, load_ptr, result_loc); } -static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_bool_not(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypePrefixOpExpr); AstNode *expr_node = node->data.prefix_op_expr.primary_expr; - IrInstruction *value = ir_gen_node(irb, expr_node, scope); - if (value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *value = ir_gen_node(irb, expr_node, scope); + if (value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; return ir_build_bool_not(irb, scope, node, value); } -static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, +static IrInstSrc *ir_gen_prefix_op_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypePrefixOpExpr); @@ -6743,12 +7791,12 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod zig_unreachable(); } -static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, +static IrInstSrc *ir_gen_union_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, + IrInstSrc *union_type, IrInstSrc *field_name, AstNode *expr_node, LVal lval, ResultLoc *parent_result_loc) { - IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, source_node, parent_result_loc, union_type); - IrInstruction *field_ptr = ir_build_field_ptr_instruction(irb, scope, source_node, container_ptr, + IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, source_node, parent_result_loc, union_type); + IrInstSrc *field_ptr = ir_build_field_ptr_instruction(irb, scope, source_node, container_ptr, field_name, true); ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); @@ -6757,18 +7805,18 @@ static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNo ir_ref_instruction(field_ptr, irb->current_basic_block); ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); - IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, + IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_inst->base); - if (expr_value == irb->codegen->invalid_instruction) + if (expr_value == irb->codegen->invalid_inst_src) return expr_value; - IrInstruction *init_union = ir_build_union_init_named_field(irb, scope, source_node, union_type, + IrInstSrc *init_union = ir_build_union_init_named_field(irb, scope, source_node, union_type, field_name, field_ptr, container_ptr); return ir_lval_wrap(irb, scope, init_union, lval, parent_result_loc); } -static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, +static IrInstSrc *ir_gen_container_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *parent_result_loc) { assert(node->type == NodeTypeContainerInitExpr); @@ -6780,42 +7828,42 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A ResultLoc *child_result_loc; AstNode *init_array_type_source_node; if (container_init_expr->type != nullptr) { - IrInstruction *container_type; + IrInstSrc *container_type; if (container_init_expr->type->type == NodeTypeInferredArrayType) { if (kind == ContainerInitKindStruct) { add_node_error(irb->codegen, container_init_expr->type, buf_sprintf("initializing array with struct syntax")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } - IrInstruction *sentinel; + IrInstSrc *sentinel; if (container_init_expr->type->data.inferred_array_type.sentinel != nullptr) { sentinel = ir_gen_node(irb, container_init_expr->type->data.inferred_array_type.sentinel, scope); - if (sentinel == irb->codegen->invalid_instruction) + if (sentinel == irb->codegen->invalid_inst_src) return sentinel; } else { sentinel = nullptr; } - IrInstruction *elem_type = ir_gen_node(irb, + IrInstSrc *elem_type = ir_gen_node(irb, container_init_expr->type->data.inferred_array_type.child_type, scope); - if (elem_type == irb->codegen->invalid_instruction) + if (elem_type == irb->codegen->invalid_inst_src) return elem_type; size_t item_count = container_init_expr->entries.length; - IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count); + IrInstSrc *item_count_inst = ir_build_const_usize(irb, scope, node, item_count); container_type = ir_build_array_type(irb, scope, node, item_count_inst, sentinel, elem_type); } else { container_type = ir_gen_node(irb, container_init_expr->type, scope); - if (container_type == irb->codegen->invalid_instruction) + if (container_type == irb->codegen->invalid_inst_src) return container_type; } result_loc_cast = ir_build_cast_result_loc(irb, container_type, parent_result_loc); child_result_loc = &result_loc_cast->base; - init_array_type_source_node = container_type->source_node; + init_array_type_source_node = container_type->base.source_node; } else { child_result_loc = parent_result_loc; if (parent_result_loc->source_instruction != nullptr) { - init_array_type_source_node = parent_result_loc->source_instruction->source_node; + init_array_type_source_node = parent_result_loc->source_instruction->base.source_node; } else { init_array_type_source_node = node; } @@ -6823,11 +7871,11 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A switch (kind) { case ContainerInitKindStruct: { - IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc, + IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc, nullptr); size_t field_count = container_init_expr->entries.length; - IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); + IrInstSrcContainerInitFieldsField *fields = allocate<IrInstSrcContainerInitFieldsField>(field_count); for (size_t i = 0; i < field_count; i += 1) { AstNode *entry_node = container_init_expr->entries.at(i); assert(entry_node->type == NodeTypeStructValueField); @@ -6835,7 +7883,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A Buf *name = entry_node->data.struct_val_field.name; AstNode *expr_node = entry_node->data.struct_val_field.expr; - IrInstruction *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true); + IrInstSrc *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true); ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); result_loc_inst->base.id = ResultLocIdInstruction; result_loc_inst->base.source_instruction = field_ptr; @@ -6843,16 +7891,16 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A ir_ref_instruction(field_ptr, irb->current_basic_block); ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); - IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, + IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_inst->base); - if (expr_value == irb->codegen->invalid_instruction) + if (expr_value == irb->codegen->invalid_inst_src) return expr_value; fields[i].name = name; fields[i].source_node = entry_node; fields[i].result_loc = field_ptr; } - IrInstruction *result = ir_build_container_init_fields(irb, scope, node, field_count, + IrInstSrc *result = ir_build_container_init_fields(irb, scope, node, field_count, fields, container_ptr); if (result_loc_cast != nullptr) { @@ -6863,15 +7911,15 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A case ContainerInitKindArray: { size_t item_count = container_init_expr->entries.length; - IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc, + IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc, nullptr); - IrInstruction **result_locs = allocate<IrInstruction *>(item_count); + IrInstSrc **result_locs = allocate<IrInstSrc *>(item_count); for (size_t i = 0; i < item_count; i += 1) { AstNode *expr_node = container_init_expr->entries.at(i); - IrInstruction *elem_index = ir_build_const_usize(irb, scope, expr_node, i); - IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, + IrInstSrc *elem_index = ir_build_const_usize(irb, scope, expr_node, i); + IrInstSrc *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, elem_index, false, PtrLenSingle, init_array_type_source_node); ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); result_loc_inst->base.id = ResultLocIdInstruction; @@ -6880,14 +7928,14 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A ir_ref_instruction(elem_ptr, irb->current_basic_block); ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); - IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, + IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_inst->base); - if (expr_value == irb->codegen->invalid_instruction) + if (expr_value == irb->codegen->invalid_inst_src) return expr_value; result_locs[i] = elem_ptr; } - IrInstruction *result = ir_build_container_init_list(irb, scope, node, item_count, + IrInstSrc *result = ir_build_container_init_list(irb, scope, node, item_count, result_locs, container_ptr, init_array_type_source_node); if (result_loc_cast != nullptr) { result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast); @@ -6898,19 +7946,19 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A zig_unreachable(); } -static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *alloca, ZigVar *var) { +static ResultLocVar *ir_build_var_result_loc(IrBuilderSrc *irb, IrInstSrc *alloca, ZigVar *var) { ResultLocVar *result_loc_var = allocate<ResultLocVar>(1); result_loc_var->base.id = ResultLocIdVar; result_loc_var->base.source_instruction = alloca; result_loc_var->base.allow_write_through_const = true; result_loc_var->var = var; - ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base); + ir_build_reset_result(irb, alloca->base.scope, alloca->base.source_node, &result_loc_var->base); return result_loc_var; } -static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type, +static ResultLocCast *ir_build_cast_result_loc(IrBuilderSrc *irb, IrInstSrc *dest_type, ResultLoc *parent_result_loc) { ResultLocCast *result_loc_cast = allocate<ResultLocCast>(1); @@ -6920,37 +7968,37 @@ static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *de ir_ref_instruction(dest_type, irb->current_basic_block); result_loc_cast->parent = parent_result_loc; - ir_build_reset_result(irb, dest_type->scope, dest_type->source_node, &result_loc_cast->base); + ir_build_reset_result(irb, dest_type->base.scope, dest_type->base.source_node, &result_loc_cast->base); return result_loc_cast; } -static void build_decl_var_and_init(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, - IrInstruction *init, const char *name_hint, IrInstruction *is_comptime) +static void build_decl_var_and_init(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var, + IrInstSrc *init, const char *name_hint, IrInstSrc *is_comptime) { - IrInstruction *alloca = ir_build_alloca_src(irb, scope, source_node, nullptr, name_hint, is_comptime); + IrInstSrc *alloca = ir_build_alloca_src(irb, scope, source_node, nullptr, name_hint, is_comptime); ResultLocVar *var_result_loc = ir_build_var_result_loc(irb, alloca, var); ir_build_end_expr(irb, scope, source_node, init, &var_result_loc->base); ir_build_var_decl_src(irb, scope, source_node, var, nullptr, alloca); } -static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_var_decl(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeVariableDeclaration); AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; if (buf_eql_str(variable_declaration->symbol, "_")) { add_node_error(irb->codegen, node, buf_sprintf("`_` is not a declarable symbol")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } // Used for the type expr and the align expr Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); - IrInstruction *type_instruction; + IrInstSrc *type_instruction; if (variable_declaration->type != nullptr) { type_instruction = ir_gen_node(irb, variable_declaration->type, comptime_scope); - if (type_instruction == irb->codegen->invalid_instruction) + if (type_instruction == irb->codegen->invalid_inst_src) return type_instruction; } else { type_instruction = nullptr; @@ -6961,22 +8009,22 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod bool is_extern = variable_declaration->is_extern; bool is_comptime_scalar = ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime; - IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, is_comptime_scalar); + IrInstSrc *is_comptime = ir_build_const_bool(irb, scope, node, is_comptime_scalar); ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, is_const, is_const, is_shadowable, is_comptime); - // we detect IrInstructionIdDeclVarSrc in gen_block to make sure the next node + // we detect IrInstSrcDeclVar in gen_block to make sure the next node // is inside var->child_scope if (!is_extern && !variable_declaration->expr) { var->var_type = irb->codegen->builtin_types.entry_invalid; add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } - IrInstruction *align_value = nullptr; + IrInstSrc *align_value = nullptr; if (variable_declaration->align_expr != nullptr) { align_value = ir_gen_node(irb, variable_declaration->align_expr, comptime_scope); - if (align_value == irb->codegen->invalid_instruction) + if (align_value == irb->codegen->invalid_inst_src) return align_value; } @@ -6988,7 +8036,7 @@ 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, + IrInstSrc *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. @@ -7006,19 +8054,19 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod Scope *init_scope = is_comptime_scalar ? create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope; - // Temporarily set the name of the IrExecutable to the VariableDeclaration + // Temporarily set the name of the IrExecutableSrc 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_extra(irb, variable_declaration->expr, init_scope, + IrInstSrc *init_value = ir_gen_node_extra(irb, variable_declaration->expr, init_scope, LValNone, init_result_loc); irb->exec->name = old_exec_name; - if (init_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + if (init_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; if (result_loc_cast != nullptr) { - IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, init_value->source_node, + IrInstSrc *implicit_cast = ir_build_implicit_cast(irb, scope, init_value->base.source_node, init_value, result_loc_cast); ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base); } @@ -7026,7 +8074,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod return ir_build_var_decl_src(irb, scope, node, var, align_value, alloca); } -static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, +static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeWhileExpr); @@ -7034,15 +8082,15 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n AstNode *continue_expr_node = node->data.while_expr.continue_expr; AstNode *else_node = node->data.while_expr.else_node; - IrBasicBlock *cond_block = ir_create_basic_block(irb, scope, "WhileCond"); - IrBasicBlock *body_block = ir_create_basic_block(irb, scope, "WhileBody"); - IrBasicBlock *continue_block = continue_expr_node ? + IrBasicBlockSrc *cond_block = ir_create_basic_block(irb, scope, "WhileCond"); + IrBasicBlockSrc *body_block = ir_create_basic_block(irb, scope, "WhileBody"); + IrBasicBlockSrc *continue_block = continue_expr_node ? ir_create_basic_block(irb, scope, "WhileContinue") : cond_block; - IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "WhileEnd"); - IrBasicBlock *else_block = else_node ? + IrBasicBlockSrc *end_block = ir_create_basic_block(irb, scope, "WhileEnd"); + IrBasicBlockSrc *else_block = else_node ? ir_create_basic_block(irb, scope, "WhileElse") : end_block; - IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, + IrInstSrc *is_comptime = ir_build_const_bool(irb, scope, node, ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline); ir_build_br(irb, scope, node, cond_block, is_comptime); @@ -7063,15 +8111,16 @@ 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, + ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, payload_scope); + IrInstSrc *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) + if (err_val_ptr == irb->codegen->invalid_inst_src) return err_val_ptr; - IrInstruction *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr, + IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr, true, false); - IrBasicBlock *after_cond_block = irb->current_basic_block; - IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); - IrInstruction *cond_br_inst; + IrBasicBlockSrc *after_cond_block = irb->current_basic_block; + IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); + IrInstSrc *cond_br_inst; if (!instr_is_unreachable(is_err)) { cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, else_block, body_block, is_comptime); @@ -7086,15 +8135,15 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n ir_set_cursor_at_end_and_append_block(irb, body_block); if (var_symbol) { - IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node, + IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, &spill_scope->base, symbol_node, err_val_ptr, false, false); - IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? - ir_build_ref(irb, payload_scope, symbol_node, payload_ptr, true, false) : payload_ptr; + IrInstSrc *var_ptr = node->data.while_expr.var_is_ptr ? + ir_build_ref_src(irb, &spill_scope->base, symbol_node, payload_ptr, true, false) : payload_ptr; ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, var_ptr); } - ZigList<IrInstruction *> incoming_values = {0}; - ZigList<IrBasicBlock *> incoming_blocks = {0}; + ZigList<IrInstSrc *> incoming_values = {0}; + ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope); loop_scope->break_block = end_block; @@ -7104,12 +8153,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n loop_scope->incoming_values = &incoming_values; loop_scope->lval = lval; loop_scope->peer_parent = peer_parent; + loop_scope->spill_scope = spill_scope; // Note the body block of the loop is not the place that lval and result_loc are used - // it's actually in break statements, handled similarly to return statements. // That is why we set those values in loop_scope above and not in this ir_gen_node call. - IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); - if (body_result == irb->codegen->invalid_instruction) + IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); + if (body_result == irb->codegen->invalid_inst_src) return body_result; if (!instr_is_unreachable(body_result)) { @@ -7119,8 +8169,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n if (continue_expr_node) { ir_set_cursor_at_end_and_append_block(irb, continue_block); - IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, payload_scope); - if (expr_result == irb->codegen->invalid_instruction) + IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, payload_scope); + if (expr_result == irb->codegen->invalid_inst_src) return expr_result; if (!instr_is_unreachable(expr_result)) { ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, continue_expr_node, expr_result)); @@ -7136,7 +8186,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol, true, false, false, is_comptime); Scope *err_scope = err_var->child_scope; - IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); + IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, err_symbol_node, err_val_ptr); ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, err_ptr); if (peer_parent->peers.length != 0) { @@ -7144,12 +8194,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n } ResultLocPeer *peer_result = create_peer_result(peer_parent); peer_parent->peers.append(peer_result); - IrInstruction *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_result->base); - if (else_result == irb->codegen->invalid_instruction) + IrInstSrc *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_result->base); + if (else_result == irb->codegen->invalid_inst_src) return else_result; if (!instr_is_unreachable(else_result)) ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); - IrBasicBlock *after_else_block = irb->current_basic_block; + IrBasicBlockSrc *after_else_block = irb->current_basic_block; ir_set_cursor_at_end_and_append_block(irb, end_block); if (else_result) { incoming_blocks.append(after_else_block); @@ -7162,7 +8212,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n peer_parent->peers.last()->next_bb = end_block; } - IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, + IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items, peer_parent); return ir_expr_wrap(irb, scope, phi, result_loc); } else if (var_symbol != nullptr) { @@ -7174,15 +8224,16 @@ 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, + ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, child_scope); + IrInstSrc *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) + if (maybe_val_ptr == irb->codegen->invalid_inst_src) return maybe_val_ptr; - IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); - IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); - IrBasicBlock *after_cond_block = irb->current_basic_block; - IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); - IrInstruction *cond_br_inst; + IrInstSrc *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); + IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, scope, node->data.while_expr.condition, maybe_val); + IrBasicBlockSrc *after_cond_block = irb->current_basic_block; + IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); + IrInstSrc *cond_br_inst; if (!instr_is_unreachable(is_non_null)) { cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, body_block, else_block, is_comptime); @@ -7196,13 +8247,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n is_comptime); ir_set_cursor_at_end_and_append_block(irb, body_block); - IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false, false); - IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ? - ir_build_ref(irb, child_scope, symbol_node, payload_ptr, true, false) : payload_ptr; + IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, &spill_scope->base, symbol_node, maybe_val_ptr, false, false); + IrInstSrc *var_ptr = node->data.while_expr.var_is_ptr ? + ir_build_ref_src(irb, &spill_scope->base, symbol_node, payload_ptr, true, false) : payload_ptr; ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, var_ptr); - ZigList<IrInstruction *> incoming_values = {0}; - ZigList<IrBasicBlock *> incoming_blocks = {0}; + ZigList<IrInstSrc *> incoming_values = {0}; + ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); loop_scope->break_block = end_block; @@ -7212,12 +8263,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n loop_scope->incoming_values = &incoming_values; loop_scope->lval = lval; loop_scope->peer_parent = peer_parent; + loop_scope->spill_scope = spill_scope; // Note the body block of the loop is not the place that lval and result_loc are used - // it's actually in break statements, handled similarly to return statements. // That is why we set those values in loop_scope above and not in this ir_gen_node call. - IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); - if (body_result == irb->codegen->invalid_instruction) + IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); + if (body_result == irb->codegen->invalid_inst_src) return body_result; if (!instr_is_unreachable(body_result)) { @@ -7227,8 +8279,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n if (continue_expr_node) { ir_set_cursor_at_end_and_append_block(irb, continue_block); - IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, child_scope); - if (expr_result == irb->codegen->invalid_instruction) + IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, child_scope); + if (expr_result == irb->codegen->invalid_inst_src) return expr_result; if (!instr_is_unreachable(expr_result)) { ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, continue_expr_node, expr_result)); @@ -7236,7 +8288,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n } } - IrInstruction *else_result = nullptr; + IrInstSrc *else_result = nullptr; if (else_node) { ir_set_cursor_at_end_and_append_block(irb, else_block); @@ -7246,12 +8298,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n ResultLocPeer *peer_result = create_peer_result(peer_parent); peer_parent->peers.append(peer_result); else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_result->base); - if (else_result == irb->codegen->invalid_instruction) + if (else_result == irb->codegen->invalid_inst_src) return else_result; if (!instr_is_unreachable(else_result)) ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); } - IrBasicBlock *after_else_block = irb->current_basic_block; + IrBasicBlockSrc *after_else_block = irb->current_basic_block; ir_set_cursor_at_end_and_append_block(irb, end_block); if (else_result) { incoming_blocks.append(after_else_block); @@ -7264,17 +8316,17 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n peer_parent->peers.last()->next_bb = end_block; } - IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, + IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items, peer_parent); return ir_expr_wrap(irb, scope, phi, result_loc); } else { ir_set_cursor_at_end_and_append_block(irb, cond_block); - IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); - if (cond_val == irb->codegen->invalid_instruction) + IrInstSrc *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); + if (cond_val == irb->codegen->invalid_inst_src) return cond_val; - IrBasicBlock *after_cond_block = irb->current_basic_block; - IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); - IrInstruction *cond_br_inst; + IrBasicBlockSrc *after_cond_block = irb->current_basic_block; + IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); + IrInstSrc *cond_br_inst; if (!instr_is_unreachable(cond_val)) { cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, body_block, else_block, is_comptime); @@ -7288,8 +8340,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n is_comptime); ir_set_cursor_at_end_and_append_block(irb, body_block); - ZigList<IrInstruction *> incoming_values = {0}; - ZigList<IrBasicBlock *> incoming_blocks = {0}; + ZigList<IrInstSrc *> incoming_values = {0}; + ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); @@ -7305,8 +8357,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n // Note the body block of the loop is not the place that lval and result_loc are used - // it's actually in break statements, handled similarly to return statements. // That is why we set those values in loop_scope above and not in this ir_gen_node call. - IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); - if (body_result == irb->codegen->invalid_instruction) + IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); + if (body_result == irb->codegen->invalid_inst_src) return body_result; if (!instr_is_unreachable(body_result)) { @@ -7316,8 +8368,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n if (continue_expr_node) { ir_set_cursor_at_end_and_append_block(irb, continue_block); - IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, subexpr_scope); - if (expr_result == irb->codegen->invalid_instruction) + IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, subexpr_scope); + if (expr_result == irb->codegen->invalid_inst_src) return expr_result; if (!instr_is_unreachable(expr_result)) { ir_mark_gen(ir_build_check_statement_is_void(irb, scope, continue_expr_node, expr_result)); @@ -7325,7 +8377,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n } } - IrInstruction *else_result = nullptr; + IrInstSrc *else_result = nullptr; if (else_node) { ir_set_cursor_at_end_and_append_block(irb, else_block); @@ -7336,12 +8388,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n peer_parent->peers.append(peer_result); else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_result->base); - if (else_result == irb->codegen->invalid_instruction) + if (else_result == irb->codegen->invalid_inst_src) return else_result; if (!instr_is_unreachable(else_result)) ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); } - IrBasicBlock *after_else_block = irb->current_basic_block; + IrBasicBlockSrc *after_else_block = irb->current_basic_block; ir_set_cursor_at_end_and_append_block(irb, end_block); if (else_result) { incoming_blocks.append(after_else_block); @@ -7354,13 +8406,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n peer_parent->peers.last()->next_bb = end_block; } - IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, + IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items, peer_parent); return ir_expr_wrap(irb, scope, phi, result_loc); } } -static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, +static IrInstSrc *ir_gen_for_expr(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeForExpr); @@ -7373,17 +8425,17 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo if (!elem_node) { add_node_error(irb->codegen, node, buf_sprintf("for loop expression missing element parameter")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } assert(elem_node->type == NodeTypeSymbol); ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, parent_scope); - IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, &spill_scope->base, LValPtr, nullptr); - if (array_val_ptr == irb->codegen->invalid_instruction) + IrInstSrc *array_val_ptr = ir_gen_node_extra(irb, array_node, &spill_scope->base, LValPtr, nullptr); + if (array_val_ptr == irb->codegen->invalid_inst_src) return array_val_ptr; - IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node, + IrInstSrc *is_comptime = ir_build_const_bool(irb, parent_scope, node, ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); AstNode *index_var_source_node; @@ -7400,50 +8452,49 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo index_var_name = "i"; } - IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0); + IrInstSrc *zero = ir_build_const_usize(irb, parent_scope, node, 0); build_decl_var_and_init(irb, parent_scope, index_var_source_node, index_var, zero, index_var_name, is_comptime); parent_scope = index_var->child_scope; - IrInstruction *one = ir_build_const_usize(irb, parent_scope, node, 1); - IrInstruction *index_ptr = ir_build_var_ptr(irb, parent_scope, node, index_var); + IrInstSrc *one = ir_build_const_usize(irb, parent_scope, node, 1); + IrInstSrc *index_ptr = ir_build_var_ptr(irb, parent_scope, node, index_var); - IrBasicBlock *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond"); - IrBasicBlock *body_block = ir_create_basic_block(irb, parent_scope, "ForBody"); - IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd"); - IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, parent_scope, "ForElse") : end_block; - IrBasicBlock *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue"); + IrBasicBlockSrc *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond"); + IrBasicBlockSrc *body_block = ir_create_basic_block(irb, parent_scope, "ForBody"); + IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd"); + IrBasicBlockSrc *else_block = else_node ? ir_create_basic_block(irb, parent_scope, "ForElse") : end_block; + IrBasicBlockSrc *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue"); Buf *len_field_name = buf_create_from_str("len"); - IrInstruction *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name, false); - IrInstruction *len_val = ir_build_load_ptr(irb, &spill_scope->base, node, len_ref); + IrInstSrc *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name, false); + IrInstSrc *len_val = ir_build_load_ptr(irb, &spill_scope->base, node, len_ref); ir_build_br(irb, parent_scope, node, cond_block, is_comptime); ir_set_cursor_at_end_and_append_block(irb, cond_block); - IrInstruction *index_val = ir_build_load_ptr(irb, &spill_scope->base, node, index_ptr); - IrInstruction *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); - IrBasicBlock *after_cond_block = irb->current_basic_block; - IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); - IrInstruction *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, + IrInstSrc *index_val = ir_build_load_ptr(irb, &spill_scope->base, node, index_ptr); + IrInstSrc *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); + IrBasicBlockSrc *after_cond_block = irb->current_basic_block; + IrInstSrc *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); + IrInstSrc *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, body_block, else_block, is_comptime)); ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, is_comptime); ir_set_cursor_at_end_and_append_block(irb, body_block); - Scope *elem_ptr_scope = node->data.for_expr.elem_is_ptr ? parent_scope : &spill_scope->base; - IrInstruction *elem_ptr = ir_build_elem_ptr(irb, elem_ptr_scope, node, array_val_ptr, index_val, false, - PtrLenSingle, nullptr); + IrInstSrc *elem_ptr = ir_build_elem_ptr(irb, &spill_scope->base, node, array_val_ptr, index_val, + false, PtrLenSingle, nullptr); // TODO make it an error to write to element variable or i variable. Buf *elem_var_name = elem_node->data.symbol_expr.symbol; ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); Scope *child_scope = elem_var->child_scope; - IrInstruction *var_ptr = node->data.for_expr.elem_is_ptr ? - ir_build_ref(irb, &spill_scope->base, elem_node, elem_ptr, true, false) : elem_ptr; + IrInstSrc *var_ptr = node->data.for_expr.elem_is_ptr ? + ir_build_ref_src(irb, &spill_scope->base, elem_node, elem_ptr, true, false) : elem_ptr; ir_build_var_decl_src(irb, parent_scope, elem_node, elem_var, nullptr, var_ptr); - ZigList<IrInstruction *> incoming_values = {0}; - ZigList<IrBasicBlock *> incoming_blocks = {0}; + ZigList<IrInstSrc *> incoming_values = {0}; + ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); loop_scope->break_block = end_block; loop_scope->continue_block = continue_block; @@ -7457,9 +8508,9 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo // Note the body block of the loop is not the place that lval and result_loc are used - // it's actually in break statements, handled similarly to return statements. // That is why we set those values in loop_scope above and not in this ir_gen_node call. - IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base); - if (body_result == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *body_result = ir_gen_node(irb, body_node, &loop_scope->base); + if (body_result == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; if (!instr_is_unreachable(body_result)) { ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result)); @@ -7467,11 +8518,11 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo } ir_set_cursor_at_end_and_append_block(irb, continue_block); - IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false); + IrInstSrc *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false); ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)->allow_write_through_const = true; ir_build_br(irb, child_scope, node, cond_block, is_comptime); - IrInstruction *else_result = nullptr; + IrInstSrc *else_result = nullptr; if (else_node) { ir_set_cursor_at_end_and_append_block(irb, else_block); @@ -7481,12 +8532,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo ResultLocPeer *peer_result = create_peer_result(peer_parent); peer_parent->peers.append(peer_result); else_result = ir_gen_node_extra(irb, else_node, parent_scope, LValNone, &peer_result->base); - if (else_result == irb->codegen->invalid_instruction) + if (else_result == irb->codegen->invalid_inst_src) return else_result; if (!instr_is_unreachable(else_result)) ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); } - IrBasicBlock *after_else_block = irb->current_basic_block; + IrBasicBlockSrc *after_else_block = irb->current_basic_block; ir_set_cursor_at_end_and_append_block(irb, end_block); if (else_result) { @@ -7500,29 +8551,29 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo peer_parent->peers.last()->next_bb = end_block; } - IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, + IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items, peer_parent); return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); } -static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_bool_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeBoolLiteral); return ir_build_const_bool(irb, scope, node, node->data.bool_literal.value); } -static IrInstruction *ir_gen_enum_literal(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_enum_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeEnumLiteral); Buf *name = &node->data.enum_literal.identifier->data.str_lit.str; return ir_build_const_enum_literal(irb, scope, node, name); } -static IrInstruction *ir_gen_string_literal(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_string_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeStringLiteral); return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf); } -static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_array_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeArrayType); AstNode *size_node = node->data.array_type.size; @@ -7535,10 +8586,10 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); - IrInstruction *sentinel; + IrInstSrc *sentinel; if (sentinel_expr != nullptr) { sentinel = ir_gen_node(irb, sentinel_expr, comptime_scope); - if (sentinel == irb->codegen->invalid_instruction) + if (sentinel == irb->codegen->invalid_inst_src) return sentinel; } else { sentinel = nullptr; @@ -7547,42 +8598,42 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n if (size_node) { if (is_const) { add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } if (is_volatile) { add_node_error(irb->codegen, node, buf_create_from_str("volatile qualifier invalid on array type")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } if (is_allow_zero) { add_node_error(irb->codegen, node, buf_create_from_str("allowzero qualifier invalid on array type")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } if (align_expr != nullptr) { add_node_error(irb->codegen, node, buf_create_from_str("align qualifier invalid on array type")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } - IrInstruction *size_value = ir_gen_node(irb, size_node, comptime_scope); - if (size_value == irb->codegen->invalid_instruction) + IrInstSrc *size_value = ir_gen_node(irb, size_node, comptime_scope); + if (size_value == irb->codegen->invalid_inst_src) return size_value; - IrInstruction *child_type = ir_gen_node(irb, child_type_node, comptime_scope); - if (child_type == irb->codegen->invalid_instruction) + IrInstSrc *child_type = ir_gen_node(irb, child_type_node, comptime_scope); + if (child_type == irb->codegen->invalid_inst_src) return child_type; return ir_build_array_type(irb, scope, node, size_value, sentinel, child_type); } else { - IrInstruction *align_value; + IrInstSrc *align_value; if (align_expr != nullptr) { align_value = ir_gen_node(irb, align_expr, comptime_scope); - if (align_value == irb->codegen->invalid_instruction) + if (align_value == irb->codegen->invalid_inst_src) return align_value; } else { align_value = nullptr; } - IrInstruction *child_type = ir_gen_node(irb, child_type_node, comptime_scope); - if (child_type == irb->codegen->invalid_instruction) + IrInstSrc *child_type = ir_gen_node(irb, child_type_node, comptime_scope); + if (child_type == irb->codegen->invalid_inst_src) return child_type; return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, sentinel, @@ -7590,15 +8641,15 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n } } -static IrInstruction *ir_gen_anyframe_type(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_anyframe_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeAnyFrameType); AstNode *payload_type_node = node->data.anyframe_type.payload_type; - IrInstruction *payload_type_value = nullptr; + IrInstSrc *payload_type_value = nullptr; if (payload_type_node != nullptr) { payload_type_value = ir_gen_node(irb, payload_type_node, scope); - if (payload_type_value == irb->codegen->invalid_instruction) + if (payload_type_value == irb->codegen->invalid_inst_src) return payload_type_value; } @@ -7606,7 +8657,7 @@ static IrInstruction *ir_gen_anyframe_type(IrBuilder *irb, Scope *scope, AstNode return ir_build_anyframe_type(irb, scope, node, payload_type_value); } -static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_undefined_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeUndefinedLiteral); return ir_build_const_undefined(irb, scope, node); } @@ -7723,13 +8774,13 @@ static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_ return SIZE_MAX; } -static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_asm_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeAsmExpr); AstNodeAsmExpr *asm_expr = &node->data.asm_expr; - IrInstruction *asm_template = ir_gen_node(irb, asm_expr->asm_template, scope); - if (asm_template == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *asm_template = ir_gen_node(irb, asm_expr->asm_template, scope); + if (asm_template == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; bool is_volatile = asm_expr->volatile_token != nullptr; bool in_fn_scope = (scope_fn_entry(scope) != nullptr); @@ -7738,7 +8789,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod if (is_volatile) { add_token_error(irb->codegen, node->owner, asm_expr->volatile_token, buf_sprintf("volatile is meaningless on global assembly")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 || @@ -7746,34 +8797,34 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod { add_node_error(irb->codegen, node, buf_sprintf("global assembly cannot have inputs, outputs, or clobbers")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } return ir_build_asm_src(irb, scope, node, asm_template, nullptr, nullptr, nullptr, 0, is_volatile, true); } - IrInstruction **input_list = allocate<IrInstruction *>(asm_expr->input_list.length); - IrInstruction **output_types = allocate<IrInstruction *>(asm_expr->output_list.length); + IrInstSrc **input_list = allocate<IrInstSrc *>(asm_expr->input_list.length); + IrInstSrc **output_types = allocate<IrInstSrc *>(asm_expr->output_list.length); ZigVar **output_vars = allocate<ZigVar *>(asm_expr->output_list.length); size_t return_count = 0; if (!is_volatile && asm_expr->output_list.length == 0) { add_node_error(irb->codegen, node, buf_sprintf("assembly expression with no output must be marked volatile")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { AsmOutput *asm_output = asm_expr->output_list.at(i); if (asm_output->return_type) { return_count += 1; - IrInstruction *return_type = ir_gen_node(irb, asm_output->return_type, scope); - if (return_type == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *return_type = ir_gen_node(irb, asm_output->return_type, scope); + if (return_type == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; if (return_count > 1) { add_node_error(irb->codegen, node, buf_sprintf("inline assembly allows up to one output value")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } output_types[i] = return_type; } else { @@ -7786,7 +8837,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod } else { add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } } @@ -7796,14 +8847,14 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported." " Compiler TODO: see https://github.com/ziglang/zig/issues/215", buf_ptr(asm_output->asm_symbolic_name), modifier)); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } } for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { AsmInput *asm_input = asm_expr->input_list.at(i); - IrInstruction *input_value = ir_gen_node(irb, asm_input->expr, scope); - if (input_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *input_value = ir_gen_node(irb, asm_input->expr, scope); + if (input_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; input_list[i] = input_value; } @@ -7812,7 +8863,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod output_vars, return_count, is_volatile, false); } -static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, +static IrInstSrc *ir_gen_if_optional_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeIfOptional); @@ -7823,24 +8874,24 @@ 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, nullptr); - if (maybe_val_ptr == irb->codegen->invalid_instruction) + IrInstSrc *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); + if (maybe_val_ptr == irb->codegen->invalid_inst_src) return maybe_val_ptr; - IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr); - IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, maybe_val); + IrInstSrc *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr); + IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, scope, node, maybe_val); - IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "OptionalThen"); - IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "OptionalElse"); - IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "OptionalEndIf"); + IrBasicBlockSrc *then_block = ir_create_basic_block(irb, scope, "OptionalThen"); + IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "OptionalElse"); + IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "OptionalEndIf"); - IrInstruction *is_comptime; + IrInstSrc *is_comptime; if (ir_should_inline(irb->exec, scope)) { is_comptime = ir_build_const_bool(irb, scope, node, true); } else { is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); } - IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null, + IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null, then_block, else_block, is_comptime); ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, @@ -7856,48 +8907,48 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN ZigVar *var = ir_create_var(irb, node, subexpr_scope, var_symbol, is_const, is_const, is_shadowable, is_comptime); - IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false); - IrInstruction *var_ptr = var_is_ptr ? ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; + IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false); + IrInstSrc *var_ptr = var_is_ptr ? ir_build_ref_src(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr); var_scope = var->child_scope; } else { var_scope = subexpr_scope; } - IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, + IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, &peer_parent->peers.at(0)->base); - if (then_expr_result == irb->codegen->invalid_instruction) + if (then_expr_result == irb->codegen->invalid_inst_src) return then_expr_result; - IrBasicBlock *after_then_block = irb->current_basic_block; + IrBasicBlockSrc *after_then_block = irb->current_basic_block; if (!instr_is_unreachable(then_expr_result)) ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); ir_set_cursor_at_end_and_append_block(irb, else_block); - IrInstruction *else_expr_result; + IrInstSrc *else_expr_result; if (else_node) { else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); - if (else_expr_result == irb->codegen->invalid_instruction) + if (else_expr_result == irb->codegen->invalid_inst_src) return else_expr_result; } else { else_expr_result = ir_build_const_void(irb, scope, node); ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); } - IrBasicBlock *after_else_block = irb->current_basic_block; + IrBasicBlockSrc *after_else_block = irb->current_basic_block; if (!instr_is_unreachable(else_expr_result)) ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); ir_set_cursor_at_end_and_append_block(irb, endif_block); - IrInstruction **incoming_values = allocate<IrInstruction *>(2); + IrInstSrc **incoming_values = allocate<IrInstSrc *>(2); incoming_values[0] = then_expr_result; incoming_values[1] = else_expr_result; - IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *"); + IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *"); incoming_blocks[0] = after_then_block; incoming_blocks[1] = after_else_block; - IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); + IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); return ir_expr_wrap(irb, scope, phi, result_loc); } -static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, +static IrInstSrc *ir_gen_if_err_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeIfErrorExpr); @@ -7910,20 +8961,20 @@ 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, nullptr); - if (err_val_ptr == irb->codegen->invalid_instruction) + IrInstSrc *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); + if (err_val_ptr == irb->codegen->invalid_inst_src) return err_val_ptr; - IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); - IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr, true, false); + IrInstSrc *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); + IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr, true, false); - IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk"); - IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse"); - IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "TryEnd"); + IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, scope, "TryOk"); + IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "TryElse"); + IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "TryEnd"); bool force_comptime = ir_should_inline(irb->exec, scope); - IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); - IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); + IrInstSrc *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); + IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, result_loc, is_comptime); @@ -7934,29 +8985,29 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * Scope *var_scope; if (var_symbol) { bool is_shadowable = false; - IrInstruction *var_is_comptime = force_comptime ? ir_build_const_bool(irb, subexpr_scope, node, true) : ir_build_test_comptime(irb, subexpr_scope, node, err_val); + IrInstSrc *var_is_comptime = force_comptime ? ir_build_const_bool(irb, subexpr_scope, node, true) : ir_build_test_comptime(irb, subexpr_scope, node, err_val); ZigVar *var = ir_create_var(irb, node, subexpr_scope, var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); - IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false, false); - IrInstruction *var_ptr = var_is_ptr ? - ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; + IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, subexpr_scope, node, err_val_ptr, false, false); + IrInstSrc *var_ptr = var_is_ptr ? + ir_build_ref_src(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr; ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr); var_scope = var->child_scope; } else { var_scope = subexpr_scope; } - IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, + IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, &peer_parent->peers.at(0)->base); - if (then_expr_result == irb->codegen->invalid_instruction) + if (then_expr_result == irb->codegen->invalid_inst_src) return then_expr_result; - IrBasicBlock *after_then_block = irb->current_basic_block; + IrBasicBlockSrc *after_then_block = irb->current_basic_block; if (!instr_is_unreachable(then_expr_result)) ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); ir_set_cursor_at_end_and_append_block(irb, else_block); - IrInstruction *else_expr_result; + IrInstSrc *else_expr_result; if (else_node) { Scope *err_var_scope; if (err_symbol) { @@ -7965,40 +9016,40 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * ZigVar *var = ir_create_var(irb, node, subexpr_scope, err_symbol, is_const, is_const, is_shadowable, is_comptime); - IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr); + IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, subexpr_scope, node, err_val_ptr); ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, err_ptr); err_var_scope = var->child_scope; } else { err_var_scope = subexpr_scope; } else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base); - if (else_expr_result == irb->codegen->invalid_instruction) + if (else_expr_result == irb->codegen->invalid_inst_src) return else_expr_result; } else { else_expr_result = ir_build_const_void(irb, scope, node); ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); } - IrBasicBlock *after_else_block = irb->current_basic_block; + IrBasicBlockSrc *after_else_block = irb->current_basic_block; if (!instr_is_unreachable(else_expr_result)) ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); ir_set_cursor_at_end_and_append_block(irb, endif_block); - IrInstruction **incoming_values = allocate<IrInstruction *>(2); + IrInstSrc **incoming_values = allocate<IrInstSrc *>(2); incoming_values[0] = then_expr_result; incoming_values[1] = else_expr_result; - IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *"); + IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *"); incoming_blocks[0] = after_then_block; incoming_blocks[1] = after_else_block; - IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); + IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); return ir_expr_wrap(irb, scope, phi, result_loc); } -static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, - IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, - IrInstruction *target_value_ptr, IrInstruction **prong_values, size_t prong_values_len, - ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values, - IrInstructionSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc) +static bool ir_gen_switch_prong_expr(IrBuilderSrc *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, + IrBasicBlockSrc *end_block, IrInstSrc *is_comptime, IrInstSrc *var_is_comptime, + IrInstSrc *target_value_ptr, IrInstSrc **prong_values, size_t prong_values_len, + ZigList<IrBasicBlockSrc *> *incoming_blocks, ZigList<IrInstSrc *> *incoming_values, + IrInstSrcSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc) { assert(switch_node->type == NodeTypeSwitchExpr); assert(prong_node->type == NodeTypeSwitchProng); @@ -8016,28 +9067,28 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit ZigVar *var = ir_create_var(irb, var_symbol_node, scope, var_name, is_const, is_const, is_shadowable, var_is_comptime); child_scope = var->child_scope; - IrInstruction *var_ptr; + IrInstSrc *var_ptr; if (out_switch_else_var != nullptr) { - IrInstructionSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node, + IrInstSrcSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node, target_value_ptr); *out_switch_else_var = switch_else_var; - IrInstruction *payload_ptr = &switch_else_var->base; - var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr; + IrInstSrc *payload_ptr = &switch_else_var->base; + var_ptr = var_is_ptr ? ir_build_ref_src(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr; } else if (prong_values != nullptr) { - IrInstruction *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, + IrInstSrc *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, prong_values, prong_values_len); - var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr; + var_ptr = var_is_ptr ? ir_build_ref_src(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr; } else { var_ptr = var_is_ptr ? - ir_build_ref(irb, scope, var_symbol_node, target_value_ptr, true, false) : target_value_ptr; + ir_build_ref_src(irb, scope, var_symbol_node, target_value_ptr, true, false) : target_value_ptr; } ir_build_var_decl_src(irb, scope, var_symbol_node, var, nullptr, var_ptr); } else { child_scope = scope; } - IrInstruction *expr_result = ir_gen_node_extra(irb, expr_node, child_scope, lval, result_loc); - if (expr_result == irb->codegen->invalid_instruction) + IrInstSrc *expr_result = ir_gen_node_extra(irb, expr_node, child_scope, lval, result_loc); + if (expr_result == irb->codegen->invalid_inst_src) return false; if (!instr_is_unreachable(expr_result)) ir_mark_gen(ir_build_br(irb, scope, switch_node, end_block, is_comptime)); @@ -8046,25 +9097,25 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit return true; } -static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, +static IrInstSrc *ir_gen_switch_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 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, nullptr); - if (target_value_ptr == irb->codegen->invalid_instruction) + IrInstSrc *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); + if (target_value_ptr == irb->codegen->invalid_inst_src) return target_value_ptr; - IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); + IrInstSrc *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); - IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "SwitchElse"); - IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "SwitchEnd"); + IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "SwitchElse"); + IrBasicBlockSrc *end_block = ir_create_basic_block(irb, scope, "SwitchEnd"); size_t prong_count = node->data.switch_expr.prongs.length; - ZigList<IrInstructionSwitchBrCase> cases = {0}; + ZigList<IrInstSrcSwitchBrCase> cases = {0}; - IrInstruction *is_comptime; - IrInstruction *var_is_comptime; + IrInstSrc *is_comptime; + IrInstSrc *var_is_comptime; if (ir_should_inline(irb->exec, scope)) { is_comptime = ir_build_const_bool(irb, scope, node, true); var_is_comptime = is_comptime; @@ -8073,11 +9124,11 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * var_is_comptime = ir_build_test_comptime(irb, scope, node, target_value_ptr); } - ZigList<IrInstruction *> incoming_values = {0}; - ZigList<IrBasicBlock *> incoming_blocks = {0}; - ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0}; + ZigList<IrInstSrc *> incoming_values = {0}; + ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; + ZigList<IrInstSrcCheckSwitchProngsRange> check_ranges = {0}; - IrInstructionSwitchElseVar *switch_else_var = nullptr; + IrInstSrcSwitchElseVar *switch_else_var = nullptr; ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); peer_parent->base.id = ResultLocIdPeerParent; @@ -8099,7 +9150,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * if (prong_node->data.switch_prong.any_items_are_range) { ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); - IrInstruction *ok_bit = nullptr; + IrInstSrc *ok_bit = nullptr; AstNode *last_item_node = nullptr; for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); @@ -8108,23 +9159,23 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * AstNode *start_node = item_node->data.switch_range.start; AstNode *end_node = item_node->data.switch_range.end; - IrInstruction *start_value = ir_gen_node(irb, start_node, comptime_scope); - if (start_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *start_value = ir_gen_node(irb, start_node, comptime_scope); + if (start_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *end_value = ir_gen_node(irb, end_node, comptime_scope); - if (end_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *end_value = ir_gen_node(irb, end_node, comptime_scope); + if (end_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); + IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one(); check_range->start = start_value; check_range->end = end_value; - IrInstruction *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq, + IrInstSrc *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq, target_value, start_value, false); - IrInstruction *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq, + IrInstSrc *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq, target_value, end_value, false); - IrInstruction *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd, + IrInstSrc *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd, lower_range_ok, upper_range_ok, false); if (ok_bit) { ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false); @@ -8132,15 +9183,15 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * ok_bit = both_ok; } } else { - IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); - if (item_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *item_value = ir_gen_node(irb, item_node, comptime_scope); + if (item_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); + IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one(); check_range->start = item_value; check_range->end = item_value; - IrInstruction *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq, + IrInstSrc *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq, item_value, target_value, false); if (ok_bit) { ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false); @@ -8150,12 +9201,12 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * } } - IrBasicBlock *range_block_yes = ir_create_basic_block(irb, scope, "SwitchRangeYes"); - IrBasicBlock *range_block_no = ir_create_basic_block(irb, scope, "SwitchRangeNo"); + IrBasicBlockSrc *range_block_yes = ir_create_basic_block(irb, scope, "SwitchRangeYes"); + IrBasicBlockSrc *range_block_no = ir_create_basic_block(irb, scope, "SwitchRangeNo"); assert(ok_bit); assert(last_item_node); - IrInstruction *br_inst = ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, + IrInstSrc *br_inst = ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, range_block_no, is_comptime)); if (peer_parent->base.source_instruction == nullptr) { peer_parent->base.source_instruction = br_inst; @@ -8170,7 +9221,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) { - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } ir_set_cursor_at_end_and_append_block(irb, range_block_no); @@ -8181,7 +9232,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * buf_sprintf("multiple else prongs in switch expression")); add_error_note(irb->codegen, msg, else_prong, buf_sprintf("previous else prong is here")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } else_prong = prong_node; } else if (prong_item_count == 1 && @@ -8192,7 +9243,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * buf_sprintf("multiple '_' prongs in switch expression")); add_error_note(irb->codegen, msg, underscore_prong, buf_sprintf("previous '_' prong is here")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } underscore_prong = prong_node; } else { @@ -8207,11 +9258,11 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * else add_error_note(irb->codegen, msg, underscore_prong, buf_sprintf("'_' prong is here")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); - IrBasicBlock *prev_block = irb->current_basic_block; + IrBasicBlockSrc *prev_block = irb->current_basic_block; if (peer_parent->peers.length > 0) { peer_parent->peers.last()->next_bb = else_block; } @@ -8221,7 +9272,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, &switch_else_var, LValNone, &this_peer_result_loc->base)) { - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } ir_set_cursor_at_end(irb, prev_block); } @@ -8240,29 +9291,29 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); - IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); - IrInstruction **items = allocate<IrInstruction *>(prong_item_count); + IrBasicBlockSrc *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); + IrInstSrc **items = allocate<IrInstSrc *>(prong_item_count); for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); assert(item_node->type != NodeTypeSwitchRange); - IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); - if (item_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *item_value = ir_gen_node(irb, item_node, comptime_scope); + if (item_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); + IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one(); check_range->start = item_value; check_range->end = item_value; - IrInstructionSwitchBrCase *this_case = cases.add_one(); + IrInstSrcSwitchBrCase *this_case = cases.add_one(); this_case->value = item_value; this_case->block = prong_block; items[item_i] = item_value; } - IrBasicBlock *prev_block = irb->current_basic_block; + IrBasicBlockSrc *prev_block = irb->current_basic_block; if (peer_parent->peers.length > 0) { peer_parent->peers.last()->next_bb = prong_block; } @@ -8272,21 +9323,21 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) { - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } ir_set_cursor_at_end(irb, prev_block); } - IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, + IrInstSrc *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length, else_prong != nullptr, underscore_prong != nullptr); - IrInstruction *br_instruction; + IrInstSrc *br_instruction; if (cases.length == 0) { br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime); } else { - IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, scope, node, target_value, else_block, + IrInstSrcSwitchBr *switch_br = ir_build_switch_br_src(irb, scope, node, target_value, else_block, cases.length, cases.items, is_comptime, switch_prongs_void); if (switch_else_var != nullptr) { switch_else_var->switch_br = switch_br; @@ -8314,7 +9365,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * ir_set_cursor_at_end_and_append_block(irb, end_block); assert(incoming_blocks.length == incoming_values.length); - IrInstruction *result_instruction; + IrInstSrc *result_instruction; if (incoming_blocks.length == 0) { result_instruction = ir_build_const_void(irb, scope, node); } else { @@ -8324,7 +9375,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * return ir_lval_wrap(irb, scope, result_instruction, lval, result_loc); } -static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) { +static IrInstSrc *ir_gen_comptime(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) { assert(node->type == NodeTypeCompTime); Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); @@ -8332,28 +9383,28 @@ static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNo 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) { - IrInstruction *is_comptime; +static IrInstSrc *ir_gen_return_from_block(IrBuilderSrc *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { + IrInstSrc *is_comptime; if (ir_should_inline(irb->exec, break_scope)) { is_comptime = ir_build_const_bool(irb, break_scope, node, true); } else { is_comptime = block_scope->is_comptime; } - IrInstruction *result_value; + IrInstSrc *result_value; if (node->data.break_expr.expr) { ResultLocPeer *peer_result = create_peer_result(block_scope->peer_parent); block_scope->peer_parent->peers.append(peer_result); result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, block_scope->lval, &peer_result->base); - if (result_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + if (result_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; } else { result_value = ir_build_const_void(irb, break_scope, node); } - IrBasicBlock *dest_block = block_scope->end_block; + IrBasicBlockSrc *dest_block = block_scope->end_block; ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); block_scope->incoming_blocks->append(irb->current_basic_block); @@ -8361,7 +9412,7 @@ static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scop return ir_build_br(irb, break_scope, node, dest_block, is_comptime); } -static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *node) { +static IrInstSrc *ir_gen_break(IrBuilderSrc *irb, Scope *break_scope, AstNode *node) { assert(node->type == NodeTypeBreak); // Search up the scope. We'll find one of these things first: @@ -8376,14 +9427,14 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode * if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { if (node->data.break_expr.name != nullptr) { add_node_error(irb->codegen, node, buf_sprintf("label not found: '%s'", buf_ptr(node->data.break_expr.name))); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } else { add_node_error(irb->codegen, node, buf_sprintf("break expression outside loop")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } } else if (search_scope->id == ScopeIdDeferExpr) { add_node_error(irb->codegen, node, buf_sprintf("cannot break out of defer expression")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } else if (search_scope->id == ScopeIdLoop) { ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; if (node->data.break_expr.name == nullptr || @@ -8402,32 +9453,32 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode * } } else if (search_scope->id == ScopeIdSuspend) { add_node_error(irb->codegen, node, buf_sprintf("cannot break out of suspend block")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } search_scope = search_scope->parent; } - IrInstruction *is_comptime; + IrInstSrc *is_comptime; if (ir_should_inline(irb->exec, break_scope)) { is_comptime = ir_build_const_bool(irb, break_scope, node, true); } else { is_comptime = loop_scope->is_comptime; } - IrInstruction *result_value; + IrInstSrc *result_value; if (node->data.break_expr.expr) { ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent); loop_scope->peer_parent->peers.append(peer_result); result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, loop_scope->lval, &peer_result->base); - if (result_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + if (result_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; } else { result_value = ir_build_const_void(irb, break_scope, node); } - IrBasicBlock *dest_block = loop_scope->break_block; + IrBasicBlockSrc *dest_block = loop_scope->break_block; ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); loop_scope->incoming_blocks->append(irb->current_basic_block); @@ -8435,7 +9486,7 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode * return ir_build_br(irb, break_scope, node, dest_block, is_comptime); } -static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *continue_scope, AstNode *node) { +static IrInstSrc *ir_gen_continue(IrBuilderSrc *irb, Scope *continue_scope, AstNode *node) { assert(node->type == NodeTypeContinue); // Search up the scope. We'll find one of these things first: @@ -8451,14 +9502,14 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *continue_scope, Ast if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { if (node->data.continue_expr.name != nullptr) { add_node_error(irb->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.continue_expr.name))); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } else { add_node_error(irb->codegen, node, buf_sprintf("continue expression outside loop")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } } else if (search_scope->id == ScopeIdDeferExpr) { add_node_error(irb->codegen, node, buf_sprintf("cannot continue out of defer expression")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } else if (search_scope->id == ScopeIdLoop) { ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; if (node->data.continue_expr.name == nullptr || @@ -8474,7 +9525,7 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *continue_scope, Ast search_scope = search_scope->parent; } - IrInstruction *is_comptime; + IrInstSrc *is_comptime; if (ir_should_inline(irb->exec, continue_scope)) { is_comptime = ir_build_const_bool(irb, continue_scope, node, true); } else { @@ -8486,17 +9537,17 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *continue_scope, Ast ir_mark_gen(ir_build_check_runtime_scope(irb, continue_scope, node, scope_runtime->is_comptime, is_comptime)); } - IrBasicBlock *dest_block = loop_scope->continue_block; + IrBasicBlockSrc *dest_block = loop_scope->continue_block; ir_gen_defers_for_block(irb, continue_scope, dest_block->scope, false); return ir_mark_gen(ir_build_br(irb, continue_scope, node, dest_block, is_comptime)); } -static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_error_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeErrorType); return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_global_error_set); } -static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) { +static IrInstSrc *ir_gen_defer(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { assert(node->type == NodeTypeDefer); ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope); @@ -8508,7 +9559,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode return ir_build_const_void(irb, parent_scope, node); } -static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { +static IrInstSrc *ir_gen_slice(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeSliceExpr); AstNodeSliceExpr *slice_expr = &node->data.slice_expr; @@ -8517,38 +9568,38 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node, AstNode *end_node = slice_expr->end; AstNode *sentinel_node = slice_expr->sentinel; - 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; + IrInstSrc *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr); + if (ptr_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *start_value = ir_gen_node(irb, start_node, scope); - if (start_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *start_value = ir_gen_node(irb, start_node, scope); + if (start_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *end_value; + IrInstSrc *end_value; if (end_node) { end_value = ir_gen_node(irb, end_node, scope); - if (end_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + if (end_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; } else { end_value = nullptr; } - IrInstruction *sentinel_value; + IrInstSrc *sentinel_value; if (sentinel_node) { sentinel_value = ir_gen_node(irb, sentinel_node, scope); - if (sentinel_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + if (sentinel_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; } else { sentinel_value = nullptr; } - IrInstruction *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value, + IrInstSrc *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value, sentinel_value, true, result_loc); return ir_lval_wrap(irb, scope, slice, lval, result_loc); } -static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, +static IrInstSrc *ir_gen_catch(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeCatchExpr); @@ -8562,29 +9613,29 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode assert(var_node->type == NodeTypeSymbol); Buf *var_name = var_node->data.symbol_expr.symbol; add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, lval, result_loc); } - 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; + IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); + if (err_union_ptr == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr, true, false); + IrInstSrc *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr, true, false); - IrInstruction *is_comptime; + IrInstSrc *is_comptime; if (ir_should_inline(irb->exec, parent_scope)) { is_comptime = ir_build_const_bool(irb, parent_scope, node, true); } else { is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_err); } - IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); - IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); - IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); - IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); + IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); + IrBasicBlockSrc *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); + IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); + IrInstSrc *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, result_loc, is_comptime); @@ -8600,33 +9651,33 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode ZigVar *var = ir_create_var(irb, node, subexpr_scope, var_name, is_const, is_const, is_shadowable, is_comptime); err_scope = var->child_scope; - IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr); + IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, node, err_union_ptr); ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, err_ptr); } else { err_scope = subexpr_scope; } - IrInstruction *err_result = ir_gen_node_extra(irb, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base); - if (err_result == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; - IrBasicBlock *after_err_block = irb->current_basic_block; + IrInstSrc *err_result = ir_gen_node_extra(irb, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base); + if (err_result == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; + IrBasicBlockSrc *after_err_block = irb->current_basic_block; if (!instr_is_unreachable(err_result)) ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); ir_set_cursor_at_end_and_append_block(irb, ok_block); - IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false, false); - IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); + IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(irb, parent_scope, node, err_union_ptr, false, false); + IrInstSrc *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); - IrBasicBlock *after_ok_block = irb->current_basic_block; + IrBasicBlockSrc *after_ok_block = irb->current_basic_block; ir_build_br(irb, parent_scope, node, end_block, is_comptime); ir_set_cursor_at_end_and_append_block(irb, end_block); - IrInstruction **incoming_values = allocate<IrInstruction *>(2); + IrInstSrc **incoming_values = allocate<IrInstSrc *>(2); incoming_values[0] = err_result; incoming_values[1] = unwrapped_payload; - IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *"); + IrBasicBlockSrc **incoming_blocks = allocate<IrBasicBlockSrc *>(2, "IrBasicBlockSrc *"); incoming_blocks[0] = after_err_block; incoming_blocks[1] = after_ok_block; - IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); + IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); } @@ -8644,7 +9695,7 @@ static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *o return true; } -static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, +static Buf *get_anon_type_name(CodeGen *codegen, IrExecutableSrc *exec, const char *kind_name, Scope *scope, AstNode *source_node, Buf *out_bare_name) { if (exec != nullptr && exec->name) { @@ -8673,7 +9724,7 @@ static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char } } -static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { +static IrInstSrc *ir_gen_container_decl(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { assert(node->type == NodeTypeContainerDecl); ContainerKind kind = node->data.container_decl.kind; @@ -8798,7 +9849,7 @@ static AstNode *ast_field_to_symbol_node(AstNode *err_set_field_node) { } } -static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { +static IrInstSrc *ir_gen_err_set_decl(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { assert(node->type == NodeTypeErrorSetDecl); uint32_t err_count = node->data.err_set_decl.decls.length; @@ -8841,7 +9892,7 @@ static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, A buf_sprintf("duplicate error: '%s'", buf_ptr(&err->name))); add_error_note(irb->codegen, msg, ast_field_to_symbol_node(prev_err->decl_node), buf_sprintf("other error here")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } errors[err->value] = err; } @@ -8849,11 +9900,11 @@ static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, A return ir_build_const_type(irb, parent_scope, node, err_set_type); } -static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNode *node) { +static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { assert(node->type == NodeTypeFnProto); size_t param_count = node->data.fn_proto.params.length; - IrInstruction **param_types = allocate<IrInstruction*>(param_count); + IrInstSrc **param_types = allocate<IrInstSrc*>(param_count); bool is_var_args = false; for (size_t i = 0; i < param_count; i += 1) { @@ -8864,59 +9915,59 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo } if (param_node->data.param_decl.var_token == nullptr) { AstNode *type_node = param_node->data.param_decl.type; - IrInstruction *type_value = ir_gen_node(irb, type_node, parent_scope); - if (type_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *type_value = ir_gen_node(irb, type_node, parent_scope); + if (type_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; param_types[i] = type_value; } else { param_types[i] = nullptr; } } - IrInstruction *align_value = nullptr; + IrInstSrc *align_value = nullptr; if (node->data.fn_proto.align_expr != nullptr) { align_value = ir_gen_node(irb, node->data.fn_proto.align_expr, parent_scope); - if (align_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + if (align_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; } - IrInstruction *callconv_value = nullptr; + IrInstSrc *callconv_value = nullptr; if (node->data.fn_proto.callconv_expr != nullptr) { callconv_value = ir_gen_node(irb, node->data.fn_proto.callconv_expr, parent_scope); - if (callconv_value == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + if (callconv_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; } - IrInstruction *return_type; + IrInstSrc *return_type; if (node->data.fn_proto.return_var_token == nullptr) { if (node->data.fn_proto.return_type == nullptr) { return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void); } else { return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope); - if (return_type == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + if (return_type == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; } } else { add_node_error(irb->codegen, node, buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; //return_type = nullptr; } return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, callconv_value, return_type, is_var_args); } -static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstSrc *ir_gen_resume(IrBuilderSrc *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeResume); - IrInstruction *target_inst = ir_gen_node_extra(irb, node->data.resume_expr.expr, scope, LValPtr, nullptr); - if (target_inst == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *target_inst = ir_gen_node_extra(irb, node->data.resume_expr.expr, scope, LValPtr, nullptr); + if (target_inst == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - return ir_build_resume(irb, scope, node, target_inst); + return ir_build_resume_src(irb, scope, node, target_inst); } -static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, +static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeAwaitExpr); @@ -8937,7 +9988,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n ZigFn *fn_entry = exec_fn_entry(irb->exec); if (!fn_entry) { add_node_error(irb->codegen, node, buf_sprintf("await outside function definition")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } ScopeSuspend *existing_suspend_scope = get_scope_suspend(scope); if (existing_suspend_scope) { @@ -8946,24 +9997,24 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("suspend block here")); existing_suspend_scope->reported_err = true; } - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } - IrInstruction *target_inst = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); - if (target_inst == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; + IrInstSrc *target_inst = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); + if (target_inst == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc); + IrInstSrc *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc); return ir_lval_wrap(irb, scope, await_inst, lval, result_loc); } -static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) { +static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { assert(node->type == NodeTypeSuspend); ZigFn *fn_entry = exec_fn_entry(irb->exec); if (!fn_entry) { add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope); if (existing_suspend_scope) { @@ -8972,21 +10023,21 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here")); existing_suspend_scope->reported_err = true; } - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; } - IrInstructionSuspendBegin *begin = ir_build_suspend_begin(irb, parent_scope, node); + IrInstSrcSuspendBegin *begin = ir_build_suspend_begin_src(irb, parent_scope, node); if (node->data.suspend.block != nullptr) { ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); Scope *child_scope = &suspend_scope->base; - IrInstruction *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope); + IrInstSrc *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope); ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res)); } - return ir_mark_gen(ir_build_suspend_finish(irb, parent_scope, node, begin)); + return ir_mark_gen(ir_build_suspend_finish_src(irb, parent_scope, node, begin)); } -static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, +static IrInstSrc *ir_gen_node_raw(IrBuilderSrc *irb, AstNode *node, Scope *scope, LVal lval, ResultLoc *result_loc) { assert(scope); @@ -9035,39 +10086,39 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop return ir_gen_return(irb, scope, node, lval, result_loc); case NodeTypeFieldAccessExpr: { - IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node); - if (ptr_instruction == irb->codegen->invalid_instruction) + IrInstSrc *ptr_instruction = ir_gen_field_access(irb, scope, node); + if (ptr_instruction == irb->codegen->invalid_inst_src) return ptr_instruction; if (lval == LValPtr) return ptr_instruction; - IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); + IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); return ir_expr_wrap(irb, scope, load_ptr, result_loc); } case NodeTypePtrDeref: { AstNode *expr_node = node->data.ptr_deref_expr.target; - IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); - if (value == irb->codegen->invalid_instruction) + IrInstSrc *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); + if (value == irb->codegen->invalid_inst_src) return value; // We essentially just converted any lvalue from &(x.*) to (&x).*; // this inhibits checking that x is a pointer later, so we directly // record whether the pointer check is needed - IrInstruction *un_op = ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval, result_loc); + IrInstSrc *un_op = ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval, result_loc); return ir_expr_wrap(irb, scope, un_op, result_loc); } case NodeTypeUnwrapOptional: { AstNode *expr_node = node->data.unwrap_optional.expr; - 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; + IrInstSrc *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); + if (maybe_ptr == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; - IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true, false); + IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true, false); if (lval == LValPtr) return unwrapped_ptr; - IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, unwrapped_ptr); + IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, unwrapped_ptr); return ir_expr_wrap(irb, scope, load_ptr, result_loc); } case NodeTypeBoolLiteral: @@ -9125,7 +10176,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop case NodeTypeInferredArrayType: add_node_error(irb->codegen, node, buf_sprintf("inferred array size invalid here")); - return irb->codegen->invalid_instruction; + return irb->codegen->invalid_inst_src; case NodeTypeVarFieldType: return ir_lval_wrap(irb, scope, ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_var), lval, result_loc); @@ -9139,7 +10190,7 @@ static ResultLoc *no_result_loc(void) { return &result_loc_none->base; } -static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, +static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *scope, LVal lval, ResultLoc *result_loc) { if (result_loc == nullptr) { @@ -9156,8 +10207,8 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc } else { child_scope = &create_expr_scope(irb->codegen, node, scope)->base; } - IrInstruction *result = ir_gen_node_raw(irb, node, child_scope, lval, result_loc); - if (result == irb->codegen->invalid_instruction) { + IrInstSrc *result = ir_gen_node_raw(irb, node, child_scope, lval, result_loc); + if (result == irb->codegen->invalid_inst_src) { if (irb->exec->first_err_trace_msg == nullptr) { irb->exec->first_err_trace_msg = irb->codegen->trace_err; } @@ -9165,11 +10216,22 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc return result; } -static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { +static IrInstSrc *ir_gen_node(IrBuilderSrc *irb, AstNode *node, Scope *scope) { return ir_gen_node_extra(irb, node, scope, LValNone, nullptr); } -static void invalidate_exec(IrExecutable *exec, ErrorMsg *msg) { +static void invalidate_exec(IrExecutableSrc *exec, ErrorMsg *msg) { + if (exec->first_err_trace_msg != nullptr) + return; + + exec->first_err_trace_msg = msg; + + for (size_t i = 0; i < exec->tld_list.length; i += 1) { + exec->tld_list.items[i]->resolution = TldResolutionInvalid; + } +} + +static void invalidate_exec_gen(IrExecutableGen *exec, ErrorMsg *msg) { if (exec->first_err_trace_msg != nullptr) return; @@ -9183,24 +10245,25 @@ static void invalidate_exec(IrExecutable *exec, ErrorMsg *msg) { invalidate_exec(exec->source_exec, msg); } -bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) { + +bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutableSrc *ir_executable) { assert(node->owner); - IrBuilder ir_builder = {0}; - IrBuilder *irb = &ir_builder; + IrBuilderSrc ir_builder = {0}; + IrBuilderSrc *irb = &ir_builder; irb->codegen = codegen; irb->exec = ir_executable; irb->main_block_node = node; - IrBasicBlock *entry_block = ir_create_basic_block(irb, scope, "Entry"); + IrBasicBlockSrc *entry_block = ir_create_basic_block(irb, scope, "Entry"); ir_set_cursor_at_end_and_append_block(irb, entry_block); // Entry block gets a reference because we enter it to begin. ir_ref_bb(irb->current_basic_block); - IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); + IrInstSrc *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); - if (result == irb->codegen->invalid_instruction) + if (result == irb->codegen->invalid_inst_src) return false; if (irb->exec->first_err_trace_msg != nullptr) { @@ -9209,9 +10272,13 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec } if (!instr_is_unreachable(result)) { - ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->source_node, result, nullptr)); + ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->base.source_node, result, nullptr)); // no need for save_err_ret_addr because this cannot return error - ir_mark_gen(ir_build_return(irb, scope, result->source_node, result)); + ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1, "ResultLocReturn"); + result_loc_ret->base.id = ResultLocIdReturn; + ir_build_reset_result(irb, scope, node, &result_loc_ret->base); + ir_mark_gen(ir_build_end_expr(irb, scope, node, result, &result_loc_ret->base)); + ir_mark_gen(ir_build_return_src(irb, scope, result->base.source_node, result)); } return true; @@ -9220,7 +10287,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) { assert(fn_entry); - IrExecutable *ir_executable = fn_entry->ir_executable; + IrExecutableSrc *ir_executable = fn_entry->ir_executable; AstNode *body_node = fn_entry->body_node; assert(fn_entry->child_scope); @@ -9228,14 +10295,21 @@ bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) { return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable); } -static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) { +static void ir_add_call_stack_errors_gen(CodeGen *codegen, IrExecutableGen *exec, ErrorMsg *err_msg, int limit) { if (!exec || !exec->source_node || limit < 0) return; add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); - ir_add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1); + ir_add_call_stack_errors_gen(codegen, exec->parent_exec, err_msg, limit - 1); } -static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) { +static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutableSrc *exec, ErrorMsg *err_msg, int limit) { + if (!exec || !exec->source_node || limit < 0) return; + add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); + + ir_add_call_stack_errors_gen(codegen, exec->parent_exec, err_msg, limit - 1); +} + +static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutableSrc *exec, AstNode *source_node, Buf *msg) { ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); invalidate_exec(exec, err_msg); if (exec->parent_exec) { @@ -9244,26 +10318,40 @@ static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNo return err_msg; } +static ErrorMsg *exec_add_error_node_gen(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, Buf *msg) { + ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); + invalidate_exec_gen(exec, err_msg); + if (exec->parent_exec) { + ir_add_call_stack_errors_gen(codegen, exec, err_msg, 10); + } + return err_msg; +} + static ErrorMsg *ir_add_error_node(IrAnalyze *ira, AstNode *source_node, Buf *msg) { - return exec_add_error_node(ira->codegen, ira->new_irb.exec, source_node, msg); + return exec_add_error_node_gen(ira->codegen, ira->new_irb.exec, source_node, msg); } static ErrorMsg *opt_ir_add_error_node(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, Buf *msg) { if (ira != nullptr) - return exec_add_error_node(codegen, ira->new_irb.exec, source_node, msg); + return exec_add_error_node_gen(codegen, ira->new_irb.exec, source_node, msg); else return add_node_error(codegen, source_node, msg); } -static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction, Buf *msg) { +static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInst *source_instruction, Buf *msg) { return ir_add_error_node(ira, source_instruction->source_node, msg); } -static void ir_assert(bool ok, IrInstruction *source_instruction) { +static void ir_assert(bool ok, IrInst *source_instruction) { if (ok) return; src_assert(ok, source_instruction->source_node); } +static void ir_assert_gen(bool ok, IrInstGen *source_instruction) { + if (ok) return; + src_assert(ok, source_instruction->base.source_node); +} + // This function takes a comptime ptr and makes the child const value conform to the type // described by the pointer. static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, @@ -9309,43 +10397,37 @@ ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_va return val; } -static ZigValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec) { - IrBasicBlock *bb = exec->basic_block_list.at(0); +static Error ir_exec_scan_for_side_effects(CodeGen *codegen, IrExecutableGen *exec) { + IrBasicBlockGen *bb = exec->basic_block_list.at(0); for (size_t i = 0; i < bb->instruction_list.length; i += 1) { - IrInstruction *instruction = bb->instruction_list.at(i); - if (instruction->id == IrInstructionIdReturn) { - IrInstructionReturn *ret_inst = (IrInstructionReturn *)instruction; - IrInstruction *operand = ret_inst->operand; - if (operand->value->special == ConstValSpecialRuntime) { - exec_add_error_node(codegen, exec, operand->source_node, - buf_sprintf("unable to evaluate constant expression")); - return codegen->invalid_instruction->value; - } - return operand->value; - } else if (ir_has_side_effects(instruction)) { + IrInstGen *instruction = bb->instruction_list.at(i); + if (instruction->id == IrInstGenIdReturn) { + return ErrorNone; + } else if (ir_inst_gen_has_side_effects(instruction)) { if (instr_is_comptime(instruction)) { switch (instruction->id) { - case IrInstructionIdUnwrapErrPayload: - case IrInstructionIdUnionFieldPtr: + case IrInstGenIdUnwrapErrPayload: + case IrInstGenIdOptionalUnwrapPtr: + case IrInstGenIdUnionFieldPtr: continue; default: break; } } - if (get_scope_typeof(instruction->scope) != nullptr) { + if (get_scope_typeof(instruction->base.scope) != nullptr) { // doesn't count, it's inside a @TypeOf() continue; } - exec_add_error_node(codegen, exec, instruction->source_node, + exec_add_error_node_gen(codegen, exec, instruction->base.source_node, buf_sprintf("unable to evaluate constant expression")); - return codegen->invalid_instruction->value; + return ErrorSemanticAnalyzeFail; } } zig_unreachable(); } -static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) { - if (ir_should_inline(ira->new_irb.exec, source_instruction->scope)) { +static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInst* source_instruction) { + if (ir_should_inline(ira->old_irb.exec, source_instruction->scope)) { ir_add_error(ira, source_instruction, buf_sprintf("unable to evaluate constant expression")); return false; } @@ -10079,7 +11161,39 @@ void float_read_ieee597(ZigValue *val, uint8_t *buf, bool is_big_endian) { } } -static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, ZigType *other_type, +static void value_to_bigfloat(BigFloat *out, ZigValue *val) { + switch (val->type->id) { + case ZigTypeIdInt: + case ZigTypeIdComptimeInt: + bigfloat_init_bigint(out, &val->data.x_bigint); + return; + case ZigTypeIdComptimeFloat: + *out = val->data.x_bigfloat; + return; + case ZigTypeIdFloat: switch (val->type->data.floating.bit_count) { + case 16: + bigfloat_init_16(out, val->data.x_f16); + return; + case 32: + bigfloat_init_32(out, val->data.x_f32); + return; + case 64: + bigfloat_init_64(out, val->data.x_f64); + return; + case 80: + zig_panic("TODO"); + case 128: + bigfloat_init_128(out, val->data.x_f128); + return; + default: + zig_unreachable(); + } + default: + zig_unreachable(); + } +} + +static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstGen *instruction, ZigType *other_type, bool explicit_cast) { if (type_is_invalid(other_type)) { @@ -10173,7 +11287,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc } Buf *val_buf = buf_alloc(); bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); - ir_add_error(ira, instruction, + ir_add_error_node(ira, instruction->base.source_node, buf_sprintf("integer value %s has no representation in type '%s'", buf_ptr(val_buf), buf_ptr(&other_type->name))); @@ -10268,7 +11382,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc } Buf *val_buf = buf_alloc(); float_append_buf(val_buf, const_val); - ir_add_error(ira, instruction, + ir_add_error_node(ira, instruction->base.source_node, buf_sprintf("cast of value %s to type '%s' loses information", buf_ptr(val_buf), buf_ptr(&other_type->name))); @@ -10277,7 +11391,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { Buf *val_buf = buf_alloc(); bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); - ir_add_error(ira, instruction, + ir_add_error_node(ira, instruction->base.source_node, buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", buf_ptr(val_buf), buf_ptr(&other_type->name))); @@ -10298,7 +11412,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc if (!child_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { Buf *val_buf = buf_alloc(); bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); - ir_add_error(ira, instruction, + ir_add_error_node(ira, instruction->base.source_node, buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", buf_ptr(val_buf), buf_ptr(&child_type->name))); @@ -10321,7 +11435,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc Buf *val_buf = buf_alloc(); float_append_buf(val_buf, const_val); - ir_add_error(ira, instruction, + ir_add_error_node(ira, instruction->base.source_node, buf_sprintf("fractional component prevents float value %s from being casted to type '%s'", buf_ptr(val_buf), buf_ptr(&other_type->name))); @@ -10351,7 +11465,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); } - ir_add_error(ira, instruction, + ir_add_error_node(ira, instruction->base.source_node, buf_sprintf("%s value %s cannot be coerced to type '%s'", num_lit_str, buf_ptr(val_buf), @@ -10805,11 +11919,11 @@ static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t * } static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigType *expected_type, - IrInstruction **instructions, size_t instruction_count) + IrInstGen **instructions, size_t instruction_count) { Error err; assert(instruction_count >= 1); - IrInstruction *prev_inst; + IrInstGen *prev_inst; size_t i = 0; for (;;) { prev_inst = instructions[i]; @@ -10829,7 +11943,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT size_t errors_count = 0; ZigType *err_set_type = nullptr; if (prev_inst->value->type->id == ZigTypeIdErrorSet) { - if (!resolve_inferred_error_set(ira->codegen, prev_inst->value->type, prev_inst->source_node)) { + if (!resolve_inferred_error_set(ira->codegen, prev_inst->value->type, prev_inst->base.source_node)) { return ira->codegen->builtin_types.entry_invalid; } if (type_is_global_error_set(prev_inst->value->type)) { @@ -10849,7 +11963,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT bool any_are_null = (prev_inst->value->type->id == ZigTypeIdNull); bool convert_to_const_slice = false; for (; i < instruction_count; i += 1) { - IrInstruction *cur_inst = instructions[i]; + IrInstGen *cur_inst = instructions[i]; ZigType *cur_type = cur_inst->value->type; ZigType *prev_type = prev_inst->value->type; @@ -10871,14 +11985,14 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } if (prev_type->id == ZigTypeIdErrorSet) { - ir_assert(err_set_type != nullptr, prev_inst); + ir_assert_gen(err_set_type != nullptr, prev_inst); if (cur_type->id == ZigTypeIdErrorSet) { if (type_is_global_error_set(err_set_type)) { continue; } bool allow_infer = cur_type->data.error_set.infer_fn != nullptr && cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; - if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { + if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) { return ira->codegen->builtin_types.entry_invalid; } if (!allow_infer && type_is_global_error_set(cur_type)) { @@ -10946,7 +12060,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr && cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; - if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { + if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) { return ira->codegen->builtin_types.entry_invalid; } if (!allow_infer && type_is_global_error_set(cur_err_set_type)) { @@ -11001,7 +12115,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT if (cur_type->id == ZigTypeIdErrorSet) { bool allow_infer = cur_type->data.error_set.infer_fn != nullptr && cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; - if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { + if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) { return ira->codegen->builtin_types.entry_invalid; } if (!allow_infer && type_is_global_error_set(cur_type)) { @@ -11024,7 +12138,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT err_set_type = cur_type; } - if (!allow_infer && !resolve_inferred_error_set(ira->codegen, err_set_type, cur_inst->source_node)) { + if (!allow_infer && !resolve_inferred_error_set(ira->codegen, err_set_type, cur_inst->base.source_node)) { return ira->codegen->builtin_types.entry_invalid; } @@ -11087,11 +12201,11 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT bool allow_infer_cur = cur_err_set_type->data.error_set.infer_fn != nullptr && cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; - if (!allow_infer_prev && !resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) { + if (!allow_infer_prev && !resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->base.source_node)) { return ira->codegen->builtin_types.entry_invalid; } - if (!allow_infer_cur && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { + if (!allow_infer_cur && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) { return ira->codegen->builtin_types.entry_invalid; } @@ -11268,7 +12382,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr && cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; - if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { + if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) { return ira->codegen->builtin_types.entry_invalid; } if ((!allow_infer && type_is_global_error_set(cur_err_set_type)) || @@ -11463,9 +12577,9 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("incompatible types: '%s' and '%s'", buf_ptr(&prev_type->name), buf_ptr(&cur_type->name))); - add_error_note(ira->codegen, msg, prev_inst->source_node, + add_error_note(ira->codegen, msg, prev_inst->base.source_node, buf_sprintf("type '%s' here", buf_ptr(&prev_type->name))); - add_error_note(ira->codegen, msg, cur_inst->source_node, + add_error_note(ira->codegen, msg, cur_inst->base.source_node, buf_sprintf("type '%s' here", buf_ptr(&cur_type->name))); return ira->codegen->builtin_types.entry_invalid; @@ -11535,7 +12649,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } } -static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_instr, +static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInst *source_instr, CastOp cast_op, ZigValue *other_val, ZigType *other_type, ZigValue *const_val, ZigType *new_type) @@ -11635,58 +12749,56 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_ return true; } -static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, ZigType *ty) { - IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, - old_instruction->scope, old_instruction->source_node); - IrInstruction *new_instruction = &const_instruction->base; +static IrInstGen *ir_const(IrAnalyze *ira, IrInst *inst, ZigType *ty) { + IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, + inst->scope, inst->source_node); + IrInstGen *new_instruction = &const_instruction->base; new_instruction->value->type = ty; new_instruction->value->special = ConstValSpecialStatic; return new_instruction; } -static IrInstruction *ir_const_noval(IrAnalyze *ira, IrInstruction *old_instruction) { - IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(&ira->new_irb, +static IrInstGen *ir_const_noval(IrAnalyze *ira, IrInst *old_instruction) { + IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb, old_instruction->scope, old_instruction->source_node); return &const_instruction->base; } -// This function initializes the new IrInstruction with the provided ZigValue, +// This function initializes the new IrInstGen with the provided ZigValue, // rather than creating a new one. -static IrInstruction *ir_const_move(IrAnalyze *ira, IrInstruction *old_instruction, ZigValue *val) { - IrInstruction *result = ir_const_noval(ira, old_instruction); +static IrInstGen *ir_const_move(IrAnalyze *ira, IrInst *old_instruction, ZigValue *val) { + IrInstGen *result = ir_const_noval(ira, old_instruction); result->value = val; return result; } -static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, +static IrInstGen *ir_resolve_cast(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, ZigType *wanted_type, CastOp cast_op) { if (instr_is_comptime(value) || !type_has_bits(wanted_type)) { - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, value->value, value->value->type, result->value, wanted_type)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return result; } else { - IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op); - result->value->type = wanted_type; - return result; + return ir_build_cast(ira, source_instr, wanted_type, value, cast_op); } } -static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *value, ZigType *wanted_type) +static IrInstGen *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *value, ZigType *wanted_type) { - assert(value->value->type->id == ZigTypeIdPointer); + ir_assert(value->value->type->id == ZigTypeIdPointer, source_instr); Error err; if ((err = type_resolve(ira->codegen, value->value->type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value->type)); @@ -11694,9 +12806,9 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, if (instr_is_comptime(value)) { ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, value->value, source_instr->source_node); if (pointee == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (pointee->special != ConstValSpecialRuntime) { - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); result->value->data.x_ptr.special = ConstPtrSpecialBaseArray; result->value->data.x_ptr.mut = value->value->data.x_ptr.mut; result->value->data.x_ptr.data.base_array.array_val = pointee; @@ -11705,70 +12817,71 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, } } - IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, - wanted_type, value, CastOpBitCast); - result->value->type = wanted_type; - return result; + return ir_build_cast(ira, source_instr, wanted_type, value, CastOpBitCast); } -static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *array_ptr, ZigType *wanted_type, ResultLoc *result_loc) +static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *array_ptr, ZigType *wanted_type, ResultLoc *result_loc) { Error err; if ((err = type_resolve(ira->codegen, array_ptr->value->type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } wanted_type = adjust_slice_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, array_ptr->value->type)); if (instr_is_comptime(array_ptr)) { - ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, array_ptr->value, source_instr->source_node); + ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, UndefBad); + if (array_ptr_val == nullptr) + return ira->codegen->invalid_inst_gen; + ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, array_ptr_val, source_instr->source_node); if (pointee == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (pointee->special != ConstValSpecialRuntime) { - assert(array_ptr->value->type->id == ZigTypeIdPointer); - ZigType *array_type = array_ptr->value->type->data.pointer.child_type; + assert(array_ptr_val->type->id == ZigTypeIdPointer); + ZigType *array_type = array_ptr_val->type->data.pointer.child_type; assert(is_slice(wanted_type)); bool is_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const; - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); init_const_slice(ira->codegen, result->value, pointee, 0, array_type->data.array.len, is_const); - result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr->value->data.x_ptr.mut; + result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; result->value->type = wanted_type; return result; } } if (result_loc == nullptr) result_loc = no_result_loc(); - IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, - false, true); - if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { + IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); + if (type_is_invalid(result_loc_inst->value->type) || + result_loc_inst->value->type->id == ZigTypeIdUnreachable) + { return result_loc_inst; } return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, array_ptr, result_loc_inst); } -static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { +static IrBasicBlockGen *ir_get_new_bb(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrInst *ref_old_instruction) { assert(old_bb); - if (old_bb->other) { - if (ref_old_instruction == nullptr || old_bb->other->ref_instruction != ref_old_instruction) { - return old_bb->other; + if (old_bb->child) { + if (ref_old_instruction == nullptr || old_bb->child->ref_instruction != ref_old_instruction) { + return old_bb->child; } } - IrBasicBlock *new_bb = ir_build_bb_from(&ira->new_irb, old_bb); + IrBasicBlockGen *new_bb = ir_build_bb_from(ira, old_bb); new_bb->ref_instruction = ref_old_instruction; return new_bb; } -static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { +static IrBasicBlockGen *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrInst *ref_old_instruction) { assert(ref_old_instruction != nullptr); - IrBasicBlock *new_bb = ir_get_new_bb(ira, old_bb, ref_old_instruction); + IrBasicBlockGen *new_bb = ir_get_new_bb(ira, old_bb, ref_old_instruction); if (new_bb->must_be_comptime_source_instr) { ErrorMsg *msg = ir_add_error(ira, ref_old_instruction, buf_sprintf("control flow attempts to use compile-time variable at runtime")); @@ -11779,24 +12892,24 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, return new_bb; } -static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { - ir_assert(!old_bb->suspended, (old_bb->instruction_list.length != 0) ? old_bb->instruction_list.at(0) : nullptr); +static void ir_start_bb(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrBasicBlockSrc *const_predecessor_bb) { + ir_assert(!old_bb->suspended, (old_bb->instruction_list.length != 0) ? &old_bb->instruction_list.at(0)->base : nullptr); ira->instruction_index = 0; ira->old_irb.current_basic_block = old_bb; ira->const_predecessor_bb = const_predecessor_bb; ira->old_bb_index = old_bb->index; } -static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb, +static IrInstGen *ira_suspend(IrAnalyze *ira, IrInst *old_instruction, IrBasicBlockSrc *next_bb, IrSuspendPosition *suspend_pos) { if (ira->codegen->verbose_ir) { - fprintf(stderr, "suspend %s_%zu %s_%zu #%" PRIu32 " (%zu,%zu)\n", + fprintf(stderr, "suspend %s_%" PRIu32 " %s_%" PRIu32 " #%" PRIu32 " (%zu,%zu)\n", ira->old_irb.current_basic_block->name_hint, ira->old_irb.current_basic_block->debug_id, ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint, ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id, - ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->debug_id, + ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->base.debug_id, ira->old_bb_index, ira->instruction_index); } suspend_pos->basic_block_index = ira->old_bb_index; @@ -11811,13 +12924,13 @@ static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction assert(ira->old_irb.current_basic_block == next_bb); ira->instruction_index = 0; ira->const_predecessor_bb = nullptr; - next_bb->other = ir_get_new_bb_runtime(ira, next_bb, old_instruction); - ira->new_irb.current_basic_block = next_bb->other; + next_bb->child = ir_get_new_bb_runtime(ira, next_bb, old_instruction); + ira->new_irb.current_basic_block = next_bb->child; } return ira->codegen->unreach_instruction; } -static IrInstruction *ira_resume(IrAnalyze *ira) { +static IrInstGen *ira_resume(IrAnalyze *ira) { IrSuspendPosition pos = ira->resume_stack.pop(); if (ira->codegen->verbose_ir) { fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index); @@ -11830,12 +12943,12 @@ static IrInstruction *ira_resume(IrAnalyze *ira) { ira->instruction_index = pos.instruction_index; assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length); if (ira->codegen->verbose_ir) { - fprintf(stderr, "%s_%zu #%" PRIu32 "\n", ira->old_irb.current_basic_block->name_hint, + fprintf(stderr, "%s_%" PRIu32 " #%" PRIu32 "\n", ira->old_irb.current_basic_block->name_hint, ira->old_irb.current_basic_block->debug_id, - ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->debug_id); + ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->base.debug_id); } ira->const_predecessor_bb = nullptr; - ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other; + ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->child; assert(ira->new_irb.current_basic_block != nullptr); return ira->codegen->unreach_instruction; } @@ -11846,8 +12959,8 @@ static void ir_start_next_bb(IrAnalyze *ira) { bool need_repeat = true; for (;;) { while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { - IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); - if (old_bb->other == nullptr && old_bb->suspend_instruction_ref == nullptr) { + IrBasicBlockSrc *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); + if (old_bb->child == nullptr && old_bb->suspend_instruction_ref == nullptr) { ira->old_bb_index += 1; continue; } @@ -11855,8 +12968,8 @@ static void ir_start_next_bb(IrAnalyze *ira) { // if it's a suspended block, // then skip it if (old_bb->suspended || - (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0) || - (old_bb->other != nullptr && old_bb->other->already_appended)) + (old_bb->child != nullptr && old_bb->child->instruction_list.length != 0) || + (old_bb->child != nullptr && old_bb->child->already_appended)) { ira->old_bb_index += 1; continue; @@ -11870,10 +12983,10 @@ static void ir_start_next_bb(IrAnalyze *ira) { return; } - if (old_bb->other == nullptr) { - old_bb->other = ir_get_new_bb_runtime(ira, old_bb, old_bb->suspend_instruction_ref); + if (old_bb->child == nullptr) { + old_bb->child = ir_get_new_bb_runtime(ira, old_bb, old_bb->suspend_instruction_ref); } - ira->new_irb.current_basic_block = old_bb->other; + ira->new_irb.current_basic_block = old_bb->child; ir_start_bb(ira, old_bb, nullptr); return; } @@ -11893,16 +13006,16 @@ static void ir_finish_bb(IrAnalyze *ira) { if (!ira->new_irb.current_basic_block->already_appended) { ira->new_irb.current_basic_block->already_appended = true; if (ira->codegen->verbose_ir) { - fprintf(stderr, "append new bb %s_%zu\n", ira->new_irb.current_basic_block->name_hint, + fprintf(stderr, "append new bb %s_%" PRIu32 "\n", ira->new_irb.current_basic_block->name_hint, ira->new_irb.current_basic_block->debug_id); } ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); } ira->instruction_index += 1; while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { - IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); + IrInstSrc *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); if (!next_instruction->is_gen) { - ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); + ir_add_error(ira, &next_instruction->base, buf_sprintf("unreachable code")); break; } ira->instruction_index += 1; @@ -11911,7 +13024,7 @@ static void ir_finish_bb(IrAnalyze *ira) { ir_start_next_bb(ira); } -static IrInstruction *ir_unreach_error(IrAnalyze *ira) { +static IrInstGen *ir_unreach_error(IrAnalyze *ira) { ira->old_bb_index = SIZE_MAX; if (ira->new_irb.exec->first_err_trace_msg == nullptr) { ira->new_irb.exec->first_err_trace_msg = ira->codegen->trace_err; @@ -11919,7 +13032,7 @@ static IrInstruction *ir_unreach_error(IrAnalyze *ira) { return ira->codegen->unreach_instruction; } -static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instruction) { +static bool ir_emit_backward_branch(IrAnalyze *ira, IrInst* source_instruction) { size_t *bbc = ira->new_irb.exec->backward_branch_count; size_t *quota = ira->new_irb.exec->backward_branch_quota; @@ -11938,66 +13051,85 @@ static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instru return true; } -static IrInstruction *ir_inline_bb(IrAnalyze *ira, IrInstruction *source_instruction, IrBasicBlock *old_bb) { +static IrInstGen *ir_inline_bb(IrAnalyze *ira, IrInst* source_instruction, IrBasicBlockSrc *old_bb) { if (old_bb->debug_id <= ira->old_irb.current_basic_block->debug_id) { if (!ir_emit_backward_branch(ira, source_instruction)) return ir_unreach_error(ira); } - old_bb->other = ira->old_irb.current_basic_block->other; + old_bb->child = ira->old_irb.current_basic_block->child; ir_start_bb(ira, old_bb, ira->old_irb.current_basic_block); return ira->codegen->unreach_instruction; } -static IrInstruction *ir_finish_anal(IrAnalyze *ira, IrInstruction *instruction) { +static IrInstGen *ir_finish_anal(IrAnalyze *ira, IrInstGen *instruction) { if (instruction->value->type->id == ZigTypeIdUnreachable) ir_finish_bb(ira); return instruction; } -static IrInstruction *ir_const_type(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { - IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_type); +static IrInstGen *ir_const_fn(IrAnalyze *ira, IrInst *source_instr, ZigFn *fn_entry) { + IrInstGen *result = ir_const(ira, source_instr, fn_entry->type_entry); + result->value->special = ConstValSpecialStatic; + result->value->data.x_ptr.data.fn.fn_entry = fn_entry; + result->value->data.x_ptr.mut = ConstPtrMutComptimeConst; + result->value->data.x_ptr.special = ConstPtrSpecialFunction; + return result; +} + +static IrInstGen *ir_const_bound_fn(IrAnalyze *ira, IrInst *src_inst, ZigFn *fn_entry, IrInstGen *first_arg, + IrInst *first_arg_src) +{ + IrInstGen *result = ir_const(ira, src_inst, get_bound_fn_type(ira->codegen, fn_entry)); + result->value->data.x_bound_fn.fn = fn_entry; + result->value->data.x_bound_fn.first_arg = first_arg; + result->value->data.x_bound_fn.first_arg_src = first_arg_src; + return result; +} + +static IrInstGen *ir_const_type(IrAnalyze *ira, IrInst *source_instruction, ZigType *ty) { + IrInstGen *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_type); result->value->data.x_type = ty; return result; } -static IrInstruction *ir_const_bool(IrAnalyze *ira, IrInstruction *source_instruction, bool value) { - IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_bool); +static IrInstGen *ir_const_bool(IrAnalyze *ira, IrInst *source_instruction, bool value) { + IrInstGen *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_bool); result->value->data.x_bool = value; return result; } -static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { - IrInstruction *result = ir_const(ira, source_instruction, ty); +static IrInstGen *ir_const_undef(IrAnalyze *ira, IrInst *source_instruction, ZigType *ty) { + IrInstGen *result = ir_const(ira, source_instruction, ty); result->value->special = ConstValSpecialUndef; return result; } -static IrInstruction *ir_const_unreachable(IrAnalyze *ira, IrInstruction *source_instruction) { - IrInstruction *result = ir_const_noval(ira, source_instruction); +static IrInstGen *ir_const_unreachable(IrAnalyze *ira, IrInst *source_instruction) { + IrInstGen *result = ir_const_noval(ira, source_instruction); result->value = ira->codegen->intern.for_unreachable(); return result; } -static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { - IrInstruction *result = ir_const_noval(ira, source_instruction); +static IrInstGen *ir_const_void(IrAnalyze *ira, IrInst *source_instruction) { + IrInstGen *result = ir_const_noval(ira, source_instruction); result->value = ira->codegen->intern.for_void(); return result; } -static IrInstruction *ir_const_unsigned(IrAnalyze *ira, IrInstruction *source_instruction, uint64_t value) { - IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_num_lit_int); +static IrInstGen *ir_const_unsigned(IrAnalyze *ira, IrInst *source_instruction, uint64_t value) { + IrInstGen *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_num_lit_int); bigint_init_unsigned(&result->value->data.x_bigint, value); return result; } -static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instruction, +static IrInstGen *ir_get_const_ptr(IrAnalyze *ira, IrInst *instruction, ZigValue *pointee, ZigType *pointee_type, ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align) { ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type, ptr_is_const, ptr_is_volatile, PtrLenSingle, ptr_align, 0, 0, false); - IrInstruction *const_instr = ir_const(ira, instruction, ptr_type); + IrInstGen *const_instr = ir_const(ira, instruction, ptr_type); ZigValue *const_val = const_instr->value; const_val->data.x_ptr.special = ConstPtrSpecialRef; const_val->data.x_ptr.mut = ptr_mut; @@ -12005,7 +13137,7 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio return const_instr; } -static Error ir_resolve_const_val(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, +static Error ir_resolve_const_val(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, ZigValue *val, UndefAllowed undef_allowed) { Error err; @@ -12017,14 +13149,14 @@ static Error ir_resolve_const_val(CodeGen *codegen, IrExecutable *exec, AstNode if (!type_has_bits(val->type)) return ErrorNone; - exec_add_error_node(codegen, exec, source_node, + exec_add_error_node_gen(codegen, exec, source_node, buf_sprintf("unable to evaluate constant expression")); return ErrorSemanticAnalyzeFail; case ConstValSpecialUndef: if (undef_allowed == UndefOk || undef_allowed == LazyOk) return ErrorNone; - exec_add_error_node(codegen, exec, source_node, + exec_add_error_node_gen(codegen, exec, source_node, buf_sprintf("use of undefined value here causes undefined behavior")); return ErrorSemanticAnalyzeFail; case ConstValSpecialLazy: @@ -12039,9 +13171,9 @@ static Error ir_resolve_const_val(CodeGen *codegen, IrExecutable *exec, AstNode } } -static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { +static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed undef_allowed) { Error err; - if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, value->source_node, + if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, value->base.source_node, value->value, undef_allowed))) { return nullptr; @@ -12049,17 +13181,19 @@ static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAll return value->value; } -ZigValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, - ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota, +Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, + ZigValue *return_ptr, size_t *backward_branch_count, size_t *backward_branch_quota, ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, - IrExecutable *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef_allowed) + IrExecutableGen *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef_allowed) { Error err; - if (expected_type != nullptr && type_is_invalid(expected_type)) - return codegen->invalid_instruction->value; + src_assert(return_ptr->type->id == ZigTypeIdPointer, source_node); + + if (type_is_invalid(return_ptr->type)) + return ErrorSemanticAnalyzeFail; - IrExecutable *ir_executable = allocate<IrExecutable>(1, "IrExecutablePass1"); + IrExecutableSrc *ir_executable = allocate<IrExecutableSrc>(1, "IrExecutableSrc"); ir_executable->source_node = source_node; ir_executable->parent_exec = parent_exec; ir_executable->name = exec_name; @@ -12069,21 +13203,21 @@ ZigValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, ir_executable->begin_scope = scope; if (!ir_gen(codegen, node, scope, ir_executable)) - return codegen->invalid_instruction->value; + return ErrorSemanticAnalyzeFail; if (ir_executable->first_err_trace_msg != nullptr) { codegen->trace_err = ir_executable->first_err_trace_msg; - return codegen->invalid_instruction->value; + return ErrorSemanticAnalyzeFail; } if (codegen->verbose_ir) { fprintf(stderr, "\nSource: "); ast_render(stderr, node, 4); fprintf(stderr, "\n{ // (IR)\n"); - ir_print(codegen, stderr, ir_executable, 2, IrPassSrc); + ir_print_src(codegen, stderr, ir_executable, 2); fprintf(stderr, "}\n"); } - IrExecutable *analyzed_executable = allocate<IrExecutable>(1, "IrExecutablePass2"); + IrExecutableGen *analyzed_executable = allocate<IrExecutableGen>(1, "IrExecutableGen"); analyzed_executable->source_node = source_node; analyzed_executable->parent_exec = parent_exec; analyzed_executable->source_exec = ir_executable; @@ -12094,33 +13228,36 @@ ZigValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, analyzed_executable->backward_branch_count = backward_branch_count; analyzed_executable->backward_branch_quota = backward_branch_quota; analyzed_executable->begin_scope = scope; - ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, expected_type_source_node); + ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, + return_ptr->type->data.pointer.child_type, expected_type_source_node, return_ptr); if (type_is_invalid(result_type)) { - return codegen->invalid_instruction->value; + return ErrorSemanticAnalyzeFail; } if (codegen->verbose_ir) { fprintf(stderr, "{ // (analyzed)\n"); - ir_print(codegen, stderr, analyzed_executable, 2, IrPassGen); + ir_print_gen(codegen, stderr, analyzed_executable, 2); fprintf(stderr, "}\n"); } - ZigValue *result = ir_exec_const_result(codegen, analyzed_executable); - if (type_is_invalid(result->type)) - return codegen->invalid_instruction->value; + if ((err = ir_exec_scan_for_side_effects(codegen, analyzed_executable))) + return err; + ZigValue *result = const_ptr_pointee(nullptr, codegen, return_ptr, source_node); + if (result == nullptr) + return ErrorSemanticAnalyzeFail; if ((err = ir_resolve_const_val(codegen, analyzed_executable, node, result, undef_allowed))) - return codegen->invalid_instruction->value; + return err; - return result; + return ErrorNone; } -static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_value) { +static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstGen *err_value) { if (type_is_invalid(err_value->value->type)) return nullptr; if (err_value->value->type->id != ZigTypeIdErrorSet) { - ir_add_error(ira, err_value, + ir_add_error_node(ira, err_value->base.source_node, buf_sprintf("expected error, found '%s'", buf_ptr(&err_value->value->type->name))); return nullptr; } @@ -12133,7 +13270,7 @@ static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_valu return const_val->data.x_err_set; } -static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, +static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, ZigValue *val) { Error err; @@ -12144,18 +13281,18 @@ static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutable *exec, AstN return val->data.x_type; } -static ZigValue *ir_resolve_type_lazy(IrAnalyze *ira, IrInstruction *type_value) { +static ZigValue *ir_resolve_type_lazy(IrAnalyze *ira, IrInstGen *type_value) { if (type_is_invalid(type_value->value->type)) return nullptr; if (type_value->value->type->id != ZigTypeIdMetaType) { - ir_add_error(ira, type_value, + ir_add_error_node(ira, type_value->base.source_node, buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->value->type->name))); return nullptr; } Error err; - if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, type_value->source_node, + if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, type_value->base.source_node, type_value->value, LazyOk))) { return nullptr; @@ -12164,17 +13301,17 @@ static ZigValue *ir_resolve_type_lazy(IrAnalyze *ira, IrInstruction *type_value) return type_value->value; } -static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { +static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstGen *type_value) { ZigValue *val = ir_resolve_type_lazy(ira, type_value); if (val == nullptr) return ira->codegen->builtin_types.entry_invalid; - return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->source_node, val); + return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->base.source_node, val); } -static Error ir_validate_vector_elem_type(IrAnalyze *ira, IrInstruction *source_instr, ZigType *elem_type) { +static Error ir_validate_vector_elem_type(IrAnalyze *ira, AstNode *source_node, ZigType *elem_type) { if (!is_valid_vector_elem_type(elem_type)) { - ir_add_error(ira, source_instr, + ir_add_error_node(ira, source_node, buf_sprintf("vector element type must be integer, float, bool, or pointer; '%s' is invalid", buf_ptr(&elem_type->name))); return ErrorSemanticAnalyzeFail; @@ -12182,28 +13319,28 @@ static Error ir_validate_vector_elem_type(IrAnalyze *ira, IrInstruction *source_ return ErrorNone; } -static ZigType *ir_resolve_vector_elem_type(IrAnalyze *ira, IrInstruction *elem_type_value) { +static ZigType *ir_resolve_vector_elem_type(IrAnalyze *ira, IrInstGen *elem_type_value) { Error err; ZigType *elem_type = ir_resolve_type(ira, elem_type_value); if (type_is_invalid(elem_type)) return ira->codegen->builtin_types.entry_invalid; - if ((err = ir_validate_vector_elem_type(ira, elem_type_value, elem_type))) + if ((err = ir_validate_vector_elem_type(ira, elem_type_value->base.source_node, elem_type))) return ira->codegen->builtin_types.entry_invalid; return elem_type; } -static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstruction *type_value) { +static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstGen *type_value) { ZigType *ty = ir_resolve_type(ira, type_value); if (type_is_invalid(ty)) return ira->codegen->builtin_types.entry_invalid; if (ty->id != ZigTypeIdInt) { - ErrorMsg *msg = ir_add_error(ira, type_value, + ErrorMsg *msg = ir_add_error_node(ira, type_value->base.source_node, buf_sprintf("expected integer type, found '%s'", buf_ptr(&ty->name))); if (ty->id == ZigTypeIdVector && ty->data.vector.elem_type->id == ZigTypeIdInt) { - add_error_note(ira->codegen, msg, type_value->source_node, + add_error_note(ira->codegen, msg, type_value->base.source_node, buf_sprintf("represent vectors with their element types, i.e. '%s'", buf_ptr(&ty->data.vector.elem_type->name))); } @@ -12213,12 +13350,12 @@ static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstruction *type_value) { return ty; } -static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInstruction *op_source, IrInstruction *type_value) { +static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInst *op_source, IrInstGen *type_value) { if (type_is_invalid(type_value->value->type)) return ira->codegen->builtin_types.entry_invalid; if (type_value->value->type->id != ZigTypeIdMetaType) { - ErrorMsg *msg = ir_add_error(ira, type_value, + ErrorMsg *msg = ir_add_error_node(ira, type_value->base.source_node, buf_sprintf("expected error set type, found '%s'", buf_ptr(&type_value->value->type->name))); add_error_note(ira->codegen, msg, op_source->source_node, buf_sprintf("`||` merges error sets; `or` performs boolean OR")); @@ -12232,7 +13369,7 @@ static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInstruction *op_sour assert(const_val->data.x_type != nullptr); ZigType *result_type = const_val->data.x_type; if (result_type->id != ZigTypeIdErrorSet) { - ErrorMsg *msg = ir_add_error(ira, type_value, + ErrorMsg *msg = ir_add_error_node(ira, type_value->base.source_node, buf_sprintf("expected error set type, found type '%s'", buf_ptr(&result_type->name))); add_error_note(ira->codegen, msg, op_source->source_node, buf_sprintf("`||` merges error sets; `or` performs boolean OR")); @@ -12241,15 +13378,12 @@ static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInstruction *op_sour return result_type; } -static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { - if (fn_value == ira->codegen->invalid_instruction) - return nullptr; - +static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstGen *fn_value) { if (type_is_invalid(fn_value->value->type)) return nullptr; if (fn_value->value->type->id != ZigTypeIdFn) { - ir_add_error_node(ira, fn_value->source_node, + ir_add_error_node(ira, fn_value->base.source_node, buf_sprintf("expected function type, found '%s'", buf_ptr(&fn_value->value->type->name))); return nullptr; } @@ -12265,22 +13399,22 @@ static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { return const_val->data.x_ptr.data.fn.fn_entry; } -static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, - ZigType *wanted_type, ResultLoc *result_loc) +static IrInstGen *ir_analyze_optional_wrap(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *value, ZigType *wanted_type, ResultLoc *result_loc) { assert(wanted_type->id == ZigTypeIdOptional); if (instr_is_comptime(value)) { ZigType *payload_type = wanted_type->data.maybe.child_type; - IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); + IrInstGen *casted_payload = ir_implicit_cast(ira, value, payload_type); if (type_is_invalid(casted_payload->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *val = ir_resolve_const(ira, casted_payload, UndefOk); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, + IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, source_instr->scope, source_instr->source_node); const_instruction->base.value->special = ConstValSpecialStatic; if (types_have_same_zig_comptime_repr(ira->codegen, wanted_type, payload_type)) { @@ -12295,40 +13429,42 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so if (result_loc == nullptr && handle_is_ptr(wanted_type)) { result_loc = no_result_loc(); } - IrInstruction *result_loc_inst = nullptr; + IrInstGen *result_loc_inst = nullptr; if (result_loc != nullptr) { - result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true); - if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { + result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); + if (type_is_invalid(result_loc_inst->value->type) || + result_loc_inst->value->type->id == ZigTypeIdUnreachable) + { return result_loc_inst; } } - IrInstruction *result = ir_build_optional_wrap(ira, source_instr, wanted_type, value, result_loc_inst); + IrInstGen *result = ir_build_optional_wrap(ira, source_instr, wanted_type, value, result_loc_inst); result->value->data.rh_maybe = RuntimeHintOptionalNonNull; return result; } -static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) +static IrInstGen *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *value, ZigType *wanted_type, ResultLoc *result_loc) { assert(wanted_type->id == ZigTypeIdErrorUnion); ZigType *payload_type = wanted_type->data.error_union.payload_type; ZigType *err_set_type = wanted_type->data.error_union.err_set_type; if (instr_is_comptime(value)) { - IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); + IrInstGen *casted_payload = ir_implicit_cast(ira, value, payload_type); if (type_is_invalid(casted_payload->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - ZigValue *val = ir_resolve_const(ira, casted_payload, UndefBad); - if (!val) - return ira->codegen->invalid_instruction; + ZigValue *val = ir_resolve_const(ira, casted_payload, UndefOk); + if (val == nullptr) + return ira->codegen->invalid_inst_gen; ZigValue *err_set_val = create_const_vals(1); err_set_val->type = err_set_type; err_set_val->special = ConstValSpecialStatic; err_set_val->data.x_err_set = nullptr; - IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, + IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, source_instr->scope, source_instr->source_node); const_instruction->base.value->type = wanted_type; const_instruction->base.value->special = ConstValSpecialStatic; @@ -12337,23 +13473,24 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction return &const_instruction->base; } - IrInstruction *result_loc_inst; + IrInstGen *result_loc_inst; if (handle_is_ptr(wanted_type)) { if (result_loc == nullptr) result_loc = no_result_loc(); - result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true); - if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { + result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); + if (type_is_invalid(result_loc_inst->value->type) || + result_loc_inst->value->type->id == ZigTypeIdUnreachable) { return result_loc_inst; } } else { result_loc_inst = nullptr; } - IrInstruction *result = ir_build_err_wrap_payload(ira, source_instr, wanted_type, value, result_loc_inst); + IrInstGen *result = ir_build_err_wrap_payload(ira, source_instr, wanted_type, value, result_loc_inst); result->value->data.rh_error_union = RuntimeHintErrorUnionNonError; return result; } -static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, +static IrInstGen *ir_analyze_err_set_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, ZigType *wanted_type) { assert(value->value->type->id == ZigTypeIdErrorSet); @@ -12362,10 +13499,10 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou if (instr_is_comptime(value)) { ZigValue *val = ir_resolve_const(ira, value, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (!type_is_global_error_set(wanted_type)) { bool subset = false; @@ -12379,11 +13516,11 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou ir_add_error(ira, source_instr, buf_sprintf("error.%s not a member of error set '%s'", buf_ptr(&val->data.x_err_set->name), buf_ptr(&wanted_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } - IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, + IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, source_instr->scope, source_instr->source_node); const_instruction->base.value->type = wanted_type; const_instruction->base.value->special = ConstValSpecialStatic; @@ -12391,18 +13528,16 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou return &const_instruction->base; } - IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, CastOpErrSet); - result->value->type = wanted_type; - return result; + return ir_build_cast(ira, source_instr, wanted_type, value, CastOpErrSet); } -static IrInstruction *ir_analyze_frame_ptr_to_anyframe(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *frame_ptr, ZigType *wanted_type) +static IrInstGen *ir_analyze_frame_ptr_to_anyframe(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *frame_ptr, ZigType *wanted_type) { if (instr_is_comptime(frame_ptr)) { ZigValue *ptr_val = ir_resolve_const(ira, frame_ptr, UndefBad); if (ptr_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ir_assert(ptr_val->type->id == ZigTypeIdPointer, source_instr); if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { @@ -12410,44 +13545,38 @@ static IrInstruction *ir_analyze_frame_ptr_to_anyframe(IrAnalyze *ira, IrInstruc } } - IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, - wanted_type, frame_ptr, CastOpBitCast); - result->value->type = wanted_type; - return result; + return ir_build_cast(ira, source_instr, wanted_type, frame_ptr, CastOpBitCast); } -static IrInstruction *ir_analyze_anyframe_to_anyframe(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *value, ZigType *wanted_type) +static IrInstGen *ir_analyze_anyframe_to_anyframe(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *value, ZigType *wanted_type) { if (instr_is_comptime(value)) { zig_panic("TODO comptime anyframe->T to anyframe"); } - IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, - wanted_type, value, CastOpBitCast); - result->value->type = wanted_type; - return result; + return ir_build_cast(ira, source_instr, wanted_type, value, CastOpBitCast); } -static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, +static IrInstGen *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, ZigType *wanted_type, ResultLoc *result_loc) { assert(wanted_type->id == ZigTypeIdErrorUnion); - IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); + IrInstGen *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); if (instr_is_comptime(casted_value)) { ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *err_set_val = create_const_vals(1); err_set_val->special = ConstValSpecialStatic; err_set_val->type = wanted_type->data.error_union.err_set_type; err_set_val->data.x_err_set = val->data.x_err_set; - IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, + IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, source_instr->scope, source_instr->source_node); const_instruction->base.value->type = wanted_type; const_instruction->base.value->special = ConstValSpecialStatic; @@ -12456,11 +13585,13 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so return &const_instruction->base; } - IrInstruction *result_loc_inst; + IrInstGen *result_loc_inst; if (handle_is_ptr(wanted_type)) { if (result_loc == nullptr) result_loc = no_result_loc(); - result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true); - if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { + result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); + if (type_is_invalid(result_loc_inst->value->type) || + result_loc_inst->value->type->id == ZigTypeIdUnreachable) + { return result_loc_inst; } } else { @@ -12468,19 +13599,19 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so } - IrInstruction *result = ir_build_err_wrap_code(ira, source_instr, wanted_type, value, result_loc_inst); + IrInstGen *result = ir_build_err_wrap_code(ira, source_instr, wanted_type, value, result_loc_inst); result->value->data.rh_error_union = RuntimeHintErrorUnionError; return result; } -static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { +static IrInstGen *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, ZigType *wanted_type) { assert(wanted_type->id == ZigTypeIdOptional); assert(instr_is_comptime(value)); ZigValue *val = ir_resolve_const(ira, value, UndefBad); assert(val != nullptr); - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); result->value->special = ConstValSpecialStatic; if (get_codegen_ptr_type(wanted_type) != nullptr) { result->value->data.x_ptr.special = ConstPtrSpecialNull; @@ -12492,8 +13623,8 @@ static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *so return result; } -static IrInstruction *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *value, ZigType *wanted_type) +static IrInstGen *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInst *source_instr, + IrInstGen *value, ZigType *wanted_type) { assert(wanted_type->id == ZigTypeIdPointer); assert(wanted_type->data.pointer.ptr_len == PtrLenC); @@ -12502,48 +13633,53 @@ static IrInstruction *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInstruction ZigValue *val = ir_resolve_const(ira, value, UndefBad); assert(val != nullptr); - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); result->value->data.x_ptr.special = ConstPtrSpecialNull; result->value->data.x_ptr.mut = ConstPtrMutComptimeConst; return result; } -static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value, - bool is_const, bool is_volatile) +static IrInstGen *ir_get_ref2(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value, + ZigType *elem_type, bool is_const, bool is_volatile) { Error err; - if (type_is_invalid(value->value->type)) - return ira->codegen->invalid_instruction; + if (type_is_invalid(elem_type)) + return ira->codegen->invalid_inst_gen; if (instr_is_comptime(value)) { ZigValue *val = ir_resolve_const(ira, value, LazyOk); if (!val) - return ira->codegen->invalid_instruction; - return ir_get_const_ptr(ira, source_instruction, val, value->value->type, + return ira->codegen->invalid_inst_gen; + return ir_get_const_ptr(ira, source_instruction, val, elem_type, ConstPtrMutComptimeConst, is_const, is_volatile, 0); } - ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value->type, + ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, elem_type, is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); if ((err = type_resolve(ira->codegen, ptr_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result_loc; - if (type_has_bits(ptr_type) && !handle_is_ptr(value->value->type)) { - result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value->type, nullptr, true, - false, true); + IrInstGen *result_loc; + if (type_has_bits(ptr_type) && !handle_is_ptr(elem_type)) { + result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), elem_type, nullptr, true, true); } else { result_loc = nullptr; } - IrInstruction *new_instruction = ir_build_ref_gen(ira, source_instruction, ptr_type, value, result_loc); + IrInstGen *new_instruction = ir_build_ref_gen(ira, source_instruction, ptr_type, value, result_loc); new_instruction->value->data.rh_ptr = RuntimeHintPtrStack; return new_instruction; } -static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, IrInstruction *source_instr, ZigType *union_type) { +static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value, + bool is_const, bool is_volatile) +{ + return ir_get_ref2(ira, source_instruction, value, value->value->type, is_const, is_volatile); +} + +static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, AstNode *source_node, ZigType *union_type) { assert(union_type->id == ZigTypeIdUnion); Error err; @@ -12555,36 +13691,36 @@ static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, IrInstruction *source_ assert(union_type->data.unionation.tag_type != nullptr); return union_type->data.unionation.tag_type; } else { - ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union '%s' has no tag", + ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("union '%s' has no tag", buf_ptr(&union_type->name))); add_error_note(ira->codegen, msg, decl_node, buf_sprintf("consider 'union(enum)' here")); return ira->codegen->builtin_types.entry_invalid; } } -static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target) { +static IrInstGen *ir_analyze_enum_to_int(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target) { Error err; - IrInstruction *enum_target; + IrInstGen *enum_target; ZigType *enum_type; if (target->value->type->id == ZigTypeIdUnion) { - enum_type = ir_resolve_union_tag_type(ira, target, target->value->type); + enum_type = ir_resolve_union_tag_type(ira, target->base.source_node, target->value->type); if (type_is_invalid(enum_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; enum_target = ir_implicit_cast(ira, target, enum_type); if (type_is_invalid(enum_target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (target->value->type->id == ZigTypeIdEnum) { enum_target = target; enum_type = target->value->type; } else { - ir_add_error(ira, target, + ir_add_error_node(ira, target->base.source_node, buf_sprintf("expected enum, found type '%s'", buf_ptr(&target->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *tag_type = enum_type->data.enumeration.tag_int_type; assert(tag_type->id == ZigTypeIdInt || tag_type->id == ZigTypeIdComptimeInt); @@ -12593,7 +13729,7 @@ static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *sour if (enum_type->data.enumeration.layout == ContainerLayoutAuto && enum_type->data.enumeration.src_field_count == 1) { - IrInstruction *result = ir_const(ira, source_instr, tag_type); + IrInstGen *result = ir_const(ira, source_instr, tag_type); init_const_bigint(result->value, tag_type, &enum_type->data.enumeration.fields[0].value); return result; @@ -12602,20 +13738,17 @@ static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *sour if (instr_is_comptime(enum_target)) { ZigValue *val = ir_resolve_const(ira, enum_target, UndefBad); if (!val) - return ira->codegen->invalid_instruction; - IrInstruction *result = ir_const(ira, source_instr, tag_type); + return ira->codegen->invalid_inst_gen; + IrInstGen *result = ir_const(ira, source_instr, tag_type); init_const_bigint(result->value, tag_type, &val->data.x_enum_tag); return result; } - IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, - source_instr->source_node, enum_target); - result->value->type = tag_type; - return result; + return ir_build_widen_or_shorten(ira, source_instr->scope, source_instr->source_node, enum_target, tag_type); } -static IrInstruction *ir_analyze_union_to_tag(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *target, ZigType *wanted_type) +static IrInstGen *ir_analyze_union_to_tag(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *target, ZigType *wanted_type) { assert(target->value->type->id == ZigTypeIdUnion); assert(wanted_type->id == ZigTypeIdEnum); @@ -12624,8 +13757,8 @@ static IrInstruction *ir_analyze_union_to_tag(IrAnalyze *ira, IrInstruction *sou if (instr_is_comptime(target)) { ZigValue *val = ir_resolve_const(ira, target, UndefBad); if (!val) - return ira->codegen->invalid_instruction; - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + return ira->codegen->invalid_inst_gen; + IrInstGen *result = ir_const(ira, source_instr, wanted_type); result->value->special = ConstValSpecialStatic; result->value->type = wanted_type; bigint_init_bigint(&result->value->data.x_enum_tag, &val->data.x_union.tag); @@ -12636,7 +13769,7 @@ static IrInstruction *ir_analyze_union_to_tag(IrAnalyze *ira, IrInstruction *sou if (wanted_type->data.enumeration.layout == ContainerLayoutAuto && wanted_type->data.enumeration.src_field_count == 1) { - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); result->value->special = ConstValSpecialStatic; result->value->type = wanted_type; TypeEnumField *enum_field = target->value->type->data.unionation.fields[0].enum_field; @@ -12644,48 +13777,45 @@ static IrInstruction *ir_analyze_union_to_tag(IrAnalyze *ira, IrInstruction *sou return result; } - IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope, - source_instr->source_node, target); - result->value->type = wanted_type; - return result; + return ir_build_union_tag(ira, source_instr, target, wanted_type); } -static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *target, ZigType *wanted_type) +static IrInstGen *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *target, ZigType *wanted_type) { - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); result->value->special = ConstValSpecialUndef; return result; } -static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *uncasted_target, ZigType *wanted_type) +static IrInstGen *ir_analyze_enum_to_union(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *uncasted_target, ZigType *wanted_type) { Error err; assert(wanted_type->id == ZigTypeIdUnion); if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *target = ir_implicit_cast(ira, uncasted_target, wanted_type->data.unionation.tag_type); + IrInstGen *target = ir_implicit_cast(ira, uncasted_target, wanted_type->data.unionation.tag_type); if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (instr_is_comptime(target)) { ZigValue *val = ir_resolve_const(ira, target, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); assert(union_field != nullptr); ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); if (field_type == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; switch (type_has_one_possible_value(ira->codegen, field_type)) { case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueNo: { AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at( union_field->enum_field->decl_index); @@ -12696,13 +13826,13 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so buf_ptr(union_field->name))); add_error_note(ira->codegen, msg, field_node, buf_sprintf("field '%s' declared here", buf_ptr(union_field->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } case OnePossibleValueYes: break; } - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); result->value->special = ConstValSpecialStatic; result->value->type = wanted_type; bigint_init_bigint(&result->value->data.x_union.tag, &val->data.x_enum_tag); @@ -12715,9 +13845,7 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so // if the union has all fields 0 bits, we can do it // and in fact it's a noop cast because the union value is just the enum value if (wanted_type->data.unionation.gen_field_count == 0) { - IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, wanted_type, target, CastOpNoop); - result->value->type = wanted_type; - return result; + return ir_build_cast(ira, &target->base, wanted_type, target, CastOpNoop); } ErrorMsg *msg = ir_add_error(ira, source_instr, @@ -12727,10 +13855,10 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so TypeUnionField *union_field = &wanted_type->data.unionation.fields[i]; ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); if (field_type == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; bool has_bits; if ((err = type_has_bits2(ira->codegen, field_type, &has_bits))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (has_bits) { AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i); add_error_note(ira->codegen, msg, field_node, @@ -12739,23 +13867,23 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so buf_ptr(&field_type->name))); } } - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } -static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *target, ZigType *wanted_type) +static IrInstGen *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *target, ZigType *wanted_type) { assert(wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdFloat); if (instr_is_comptime(target)) { ZigValue *val = ir_resolve_const(ira, target, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (wanted_type->id == ZigTypeIdInt) { if (bigint_cmp_zero(&val->data.x_bigint) == CmpLT && !wanted_type->data.integral.is_signed) { ir_add_error(ira, source_instr, buf_sprintf("attempt to cast negative value to unsigned integer")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (!bigint_fits_in_bits(&val->data.x_bigint, wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) @@ -12763,10 +13891,10 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction ir_add_error(ira, source_instr, buf_sprintf("cast from '%s' to '%s' truncates bits", buf_ptr(&target->value->type->name), buf_ptr(&wanted_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); result->value->type = wanted_type; if (wanted_type->id == ZigTypeIdInt) { bigint_init_bigint(&result->value->data.x_bigint, &val->data.x_bigint); @@ -12783,19 +13911,16 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction assert(wanted_type->id == ZigTypeIdInt); assert(type_has_bits(target->value->type)); ir_build_assert_zero(ira, source_instr, target); - IrInstruction *result = ir_const_unsigned(ira, source_instr, 0); + IrInstGen *result = ir_const_unsigned(ira, source_instr, 0); result->value->type = wanted_type; return result; } - IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, - source_instr->source_node, target); - result->value->type = wanted_type; - return result; + return ir_build_widen_or_shorten(ira, source_instr->scope, source_instr->source_node, target, wanted_type); } -static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *target, ZigType *wanted_type) +static IrInstGen *ir_analyze_int_to_enum(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *target, ZigType *wanted_type) { Error err; assert(wanted_type->id == ZigTypeIdEnum); @@ -12803,14 +13928,14 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour ZigType *actual_type = target->value->type; if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (actual_type != wanted_type->data.enumeration.tag_int_type) { ir_add_error(ira, source_instr, buf_sprintf("integer to enum cast from '%s' instead of its tag type, '%s'", buf_ptr(&actual_type->name), buf_ptr(&wanted_type->data.enumeration.tag_int_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } assert(actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt); @@ -12818,7 +13943,7 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour if (instr_is_comptime(target)) { ZigValue *val = ir_resolve_const(ira, target, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; TypeEnumField *field = find_enum_field_by_tag(wanted_type, &val->data.x_bigint); if (field == nullptr && !wanted_type->data.enumeration.non_exhaustive) { @@ -12829,28 +13954,25 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour buf_ptr(&wanted_type->name), buf_ptr(val_buf))); add_error_note(ira->codegen, msg, wanted_type->data.enumeration.decl_node, buf_sprintf("'%s' declared here", buf_ptr(&wanted_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); bigint_init_bigint(&result->value->data.x_enum_tag, &val->data.x_bigint); return result; } - IrInstruction *result = ir_build_int_to_enum(&ira->new_irb, source_instr->scope, - source_instr->source_node, nullptr, target); - result->value->type = wanted_type; - return result; + return ir_build_int_to_enum_gen(ira, source_instr->scope, source_instr->source_node, wanted_type, target); } -static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *target, ZigType *wanted_type) +static IrInstGen *ir_analyze_number_to_literal(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *target, ZigType *wanted_type) { ZigValue *val = ir_resolve_const(ira, target, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); if (wanted_type->id == ZigTypeIdComptimeFloat) { float_init_float(result->value, val); } else if (wanted_type->id == ZigTypeIdComptimeInt) { @@ -12861,7 +13983,7 @@ static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction return result; } -static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, +static IrInstGen *ir_analyze_int_to_err(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, ZigType *wanted_type) { assert(target->value->type->id == ZigTypeIdInt); @@ -12871,12 +13993,12 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc if (instr_is_comptime(target)) { ZigValue *val = ir_resolve_const(ira, target, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (type_is_global_error_set(wanted_type)) { @@ -12888,7 +14010,7 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc bigint_append_buf(val_buf, &val->data.x_bigint, 10); ir_add_error(ira, source_instr, buf_sprintf("integer value %s represents no error", buf_ptr(val_buf))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } size_t index = bigint_as_usize(&val->data.x_bigint); @@ -12912,7 +14034,7 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc bigint_append_buf(val_buf, &val->data.x_bigint, 10); ir_add_error(ira, source_instr, buf_sprintf("integer value %s represents no error in '%s'", buf_ptr(val_buf), buf_ptr(&wanted_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } result->value->data.x_err_set = err; @@ -12920,12 +14042,10 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc } } - IrInstruction *result = ir_build_int_to_err(&ira->new_irb, source_instr->scope, source_instr->source_node, target); - result->value->type = wanted_type; - return result; + return ir_build_int_to_err_gen(ira, source_instr->scope, source_instr->source_node, target, wanted_type); } -static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, +static IrInstGen *ir_analyze_err_to_int(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, ZigType *wanted_type) { assert(wanted_type->id == ZigTypeIdInt); @@ -12935,9 +14055,9 @@ static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *sourc if (instr_is_comptime(target)) { ZigValue *val = ir_resolve_const(ira, target, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); ErrorTableEntry *err; if (err_type->id == ZigTypeIdErrorUnion) { @@ -12957,7 +14077,7 @@ static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *sourc ir_add_error_node(ira, source_instr->source_node, buf_sprintf("error code '%s' does not fit in '%s'", buf_ptr(&err->name), buf_ptr(&wanted_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return result; @@ -12973,14 +14093,14 @@ static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *sourc } if (!type_is_global_error_set(err_set_type)) { if (!resolve_inferred_error_set(ira->codegen, err_set_type, source_instr->source_node)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (err_set_type->data.error_set.err_count == 0) { - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); bigint_init_unsigned(&result->value->data.x_bigint, 0); return result; } else if (err_set_type->data.error_set.err_count == 1) { - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); ErrorTableEntry *err = err_set_type->data.error_set.errors[0]; bigint_init_unsigned(&result->value->data.x_bigint, err->value); return result; @@ -12992,21 +14112,19 @@ static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *sourc if (!bigint_fits_in_bits(&bn, wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) { ir_add_error_node(ira, source_instr->source_node, buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *result = ir_build_err_to_int(&ira->new_irb, source_instr->scope, source_instr->source_node, target); - result->value->type = wanted_type; - return result; + return ir_build_err_to_int_gen(ira, source_instr->scope, source_instr->source_node, target, wanted_type); } -static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, +static IrInstGen *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, ZigType *wanted_type) { assert(wanted_type->id == ZigTypeIdPointer); Error err; if ((err = type_resolve(ira->codegen, target->value->type->data.pointer.child_type, ResolveStatusAlignmentKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; assert((wanted_type->data.pointer.is_const && target->value->type->data.pointer.is_const) || !target->value->type->data.pointer.is_const); wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, target->value->type)); ZigType *array_type = wanted_type->data.pointer.child_type; @@ -13016,12 +14134,12 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou if (instr_is_comptime(target)) { ZigValue *val = ir_resolve_const(ira, target, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; assert(val->type->id == ZigTypeIdPointer); ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); if (pointee == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (pointee->special != ConstValSpecialRuntime) { ZigValue *array_val = create_const_vals(1); array_val->special = ConstValSpecialStatic; @@ -13031,7 +14149,7 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou array_val->parent.id = ConstParentIdScalar; array_val->parent.data.p_scalar.scalar_val = pointee; - IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, + IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, source_instr->scope, source_instr->source_node); const_instruction->base.value->type = wanted_type; const_instruction->base.value->special = ConstValSpecialStatic; @@ -13043,10 +14161,7 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou } // pointer to array and pointer to single item are represented the same way at runtime - IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, - wanted_type, target, CastOpBitCast); - result->value->type = wanted_type; - return result; + return ir_build_cast(ira, &target->base, wanted_type, target, CastOpBitCast); } static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCastOnly *cast_result, @@ -13234,12 +14349,12 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa } } -static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *array, ZigType *vector_type) +static IrInstGen *ir_analyze_array_to_vector(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *array, ZigType *vector_type) { if (instr_is_comptime(array)) { // arrays and vectors have the same ZigValue representation - IrInstruction *result = ir_const(ira, source_instr, vector_type); + IrInstGen *result = ir_const(ira, source_instr, vector_type); copy_const_val(result->value, array->value); result->value->type = vector_type; return result; @@ -13247,12 +14362,12 @@ static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction * return ir_build_array_to_vector(ira, source_instr, array, vector_type); } -static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *vector, ZigType *array_type, ResultLoc *result_loc) +static IrInstGen *ir_analyze_vector_to_array(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *vector, ZigType *array_type, ResultLoc *result_loc) { if (instr_is_comptime(vector)) { // arrays and vectors have the same ZigValue representation - IrInstruction *result = ir_const(ira, source_instr, array_type); + IrInstGen *result = ir_const(ira, source_instr, array_type); copy_const_val(result->value, vector->value); result->value->type = array_type; return result; @@ -13260,18 +14375,17 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction * if (result_loc == nullptr) { result_loc = no_result_loc(); } - IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, - true, false, true); - if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { + IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, true, true); + if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { return result_loc_inst; } return ir_build_vector_to_array(ira, source_instr, array_type, vector, result_loc_inst); } -static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *integer, ZigType *dest_type) +static IrInstGen *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *integer, ZigType *dest_type) { - IrInstruction *unsigned_integer; + IrInstGen *unsigned_integer; if (instr_is_comptime(integer)) { unsigned_integer = integer; } else { @@ -13284,7 +14398,7 @@ static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *sou buf_sprintf("integer type '%s' too big for implicit @intToPtr to type '%s'", buf_ptr(&integer->value->type->name), buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (integer->value->type->data.integral.is_signed) { @@ -13292,7 +14406,7 @@ static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *sou integer->value->type->data.integral.bit_count); unsigned_integer = ir_analyze_bit_cast(ira, source_instr, integer, unsigned_int_type); if (type_is_invalid(unsigned_integer->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { unsigned_integer = integer; } @@ -13312,14 +14426,14 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { return false; } -static IrInstruction *ir_analyze_enum_literal(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, +static IrInstGen *ir_analyze_enum_literal(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, ZigType *enum_type) { assert(enum_type->id == ZigTypeIdEnum); Error err; if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; TypeEnumField *field = find_enum_type_field(enum_type, value->value->data.x_enum_literal); if (field == nullptr) { @@ -13327,40 +14441,40 @@ static IrInstruction *ir_analyze_enum_literal(IrAnalyze *ira, IrInstruction *sou buf_ptr(&enum_type->name), buf_ptr(value->value->data.x_enum_literal))); add_error_note(ira->codegen, msg, enum_type->data.enumeration.decl_node, buf_sprintf("'%s' declared here", buf_ptr(&enum_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *result = ir_const(ira, source_instr, enum_type); + IrInstGen *result = ir_const(ira, source_instr, enum_type); bigint_init_bigint(&result->value->data.x_enum_tag, &field->value); return result; } -static IrInstruction *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *value, ZigType *wanted_type) +static IrInstGen *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *value, ZigType *wanted_type) { ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon list literal to array")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } -static IrInstruction *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *value, ZigType *wanted_type) +static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *value, ZigType *wanted_type) { ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to struct")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } -static IrInstruction *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *value, ZigType *wanted_type) +static IrInstGen *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *value, ZigType *wanted_type) { ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to union")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } // Add a compile error and return ErrorSemanticAnalyzeFail if the pointer alignment does not work, // otherwise return ErrorNone. Does not emit any instructions. // Assumes that the pointer types have element types with the same ABI alignment. Avoids resolving the // pointer types' alignments if both of the pointer types are ABI aligned. -static Error ir_cast_ptr_align(IrAnalyze *ira, IrInstruction *source_instr, ZigType *dest_ptr_type, +static Error ir_cast_ptr_align(IrAnalyze *ira, IrInst* source_instr, ZigType *dest_ptr_type, ZigType *src_ptr_type, AstNode *src_source_node) { Error err; @@ -13394,37 +14508,37 @@ static Error ir_cast_ptr_align(IrAnalyze *ira, IrInstruction *source_instr, ZigT return ErrorNone; } -static IrInstruction *ir_analyze_struct_value_field_value(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *struct_operand, TypeStructField *field) +static IrInstGen *ir_analyze_struct_value_field_value(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *struct_operand, TypeStructField *field) { - IrInstruction *struct_ptr = ir_get_ref(ira, source_instr, struct_operand, true, false); + IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, struct_operand, true, false); if (type_is_invalid(struct_ptr->value->type)) - return ira->codegen->invalid_instruction; - IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, struct_ptr, + return ira->codegen->invalid_inst_gen; + IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, struct_ptr, struct_operand->value->type, false); if (type_is_invalid(field_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return ir_get_deref(ira, source_instr, field_ptr, nullptr); } -static IrInstruction *ir_analyze_optional_value_payload_value(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *optional_operand, bool safety_check_on) +static IrInstGen *ir_analyze_optional_value_payload_value(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *optional_operand, bool safety_check_on) { - IrInstruction *opt_ptr = ir_get_ref(ira, source_instr, optional_operand, true, false); - IrInstruction *payload_ptr = ir_analyze_unwrap_optional_payload(ira, source_instr, opt_ptr, + IrInstGen *opt_ptr = ir_get_ref(ira, source_instr, optional_operand, true, false); + IrInstGen *payload_ptr = ir_analyze_unwrap_optional_payload(ira, source_instr, opt_ptr, safety_check_on, false); return ir_get_deref(ira, source_instr, payload_ptr, nullptr); } -static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, - ZigType *wanted_type, IrInstruction *value) +static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr, + ZigType *wanted_type, IrInstGen *value) { Error err; ZigType *actual_type = value->value->type; AstNode *source_node = source_instr->source_node; if (type_is_invalid(wanted_type) || type_is_invalid(actual_type)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } // This means the wanted type is anything. @@ -13436,7 +14550,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type, source_node, false); if (const_cast_result.id == ConstCastResultIdInvalid) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (const_cast_result.id == ConstCastResultIdOk) { return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); } @@ -13470,7 +14584,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, nullptr); } else { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else if ( wanted_child_type->id == ZigTypeIdPointer && @@ -13480,18 +14594,18 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst actual_type->data.pointer.child_type->id == ZigTypeIdArray) { if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, actual_type->data.pointer.child_type->data.array.child_type, source_node, !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) { - IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, + IrInstGen *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_child_type); if (type_is_invalid(cast1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type, nullptr); } } @@ -13509,7 +14623,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, nullptr); } else { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } } @@ -13525,13 +14639,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdComptimeFloat) { - IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); + IrInstGen *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); if (type_is_invalid(cast1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); + IrInstGen *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); if (type_is_invalid(cast2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return cast2; } @@ -13546,13 +14660,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst wanted_type->id == ZigTypeIdFloat || wanted_type->id == ZigTypeIdComptimeFloat)) { if (value->value->special == ConstValSpecialUndef) { - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); result->value->special = ConstValSpecialUndef; return result; } if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) { - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { copy_const_val(result->value, value->value); result->value->type = wanted_type; @@ -13561,7 +14675,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst } return result; } else if (wanted_type->id == ZigTypeIdComptimeFloat || wanted_type->id == ZigTypeIdFloat) { - IrInstruction *result = ir_const(ira, source_instr, wanted_type); + IrInstGen *result = ir_const(ira, source_instr, wanted_type); if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { BigFloat bf; bigfloat_init_bigint(&bf, &value->value->data.x_bigint); @@ -13573,7 +14687,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst } zig_unreachable(); } else { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } @@ -13609,13 +14723,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst actual_type->data.pointer.ptr_len == PtrLenSingle && actual_type->data.pointer.child_type->id == ZigTypeIdArray) { - IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); + IrInstGen *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); if (type_is_invalid(cast1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); + IrInstGen *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); if (type_is_invalid(cast2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return cast2; } @@ -13636,9 +14750,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst actual_array_type->data.array.sentinel))) { if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type) && types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, actual_type->data.pointer.child_type->data.array.child_type, source_node, @@ -13679,24 +14793,24 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if ((err = type_resolve(ira->codegen, slice_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type); } if (ok_align) { if (wanted_type->id == ZigTypeIdErrorUnion) { - IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, slice_type, value); + IrInstGen *cast1 = ir_analyze_cast(ira, source_instr, slice_type, value); if (type_is_invalid(cast1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); + IrInstGen *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); if (type_is_invalid(cast2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return cast2; } else { @@ -13731,12 +14845,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if ((err = type_resolve(ira->codegen, slice_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type); } @@ -13777,7 +14891,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst } } if (ok) { - IrInstruction *cast1 = ir_analyze_frame_ptr_to_anyframe(ira, source_instr, value, anyframe_type); + IrInstGen *cast1 = ir_analyze_frame_ptr_to_anyframe(ira, source_instr, value, anyframe_type); if (anyframe_type == wanted_type) return cast1; return ir_analyze_cast(ira, source_instr, wanted_type, cast1); @@ -13832,28 +14946,28 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst if (actual_type->id == ZigTypeIdEnumLiteral && (wanted_type->id == ZigTypeIdOptional && wanted_type->data.maybe.child_type->id == ZigTypeIdEnum)) { - IrInstruction *result = ir_analyze_enum_literal(ira, source_instr, value, wanted_type->data.maybe.child_type); - if (result == ira->codegen->invalid_instruction) + IrInstGen *result = ir_analyze_enum_literal(ira, source_instr, value, wanted_type->data.maybe.child_type); + if (type_is_invalid(result->value->type)) return result; - return ir_analyze_optional_wrap(ira, result, value, wanted_type, nullptr); + return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, nullptr); } // cast from enum literal to error union when payload is an enum if (actual_type->id == ZigTypeIdEnumLiteral && (wanted_type->id == ZigTypeIdErrorUnion && wanted_type->data.error_union.payload_type->id == ZigTypeIdEnum)) { - IrInstruction *result = ir_analyze_enum_literal(ira, source_instr, value, wanted_type->data.error_union.payload_type); - if (result == ira->codegen->invalid_instruction) + IrInstGen *result = ir_analyze_enum_literal(ira, source_instr, value, wanted_type->data.error_union.payload_type); + if (type_is_invalid(result->value->type)) return result; - return ir_analyze_err_wrap_payload(ira, result, value, wanted_type, nullptr); + return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, nullptr); } // cast from union to the enum type of the union if (actual_type->id == ZigTypeIdUnion && wanted_type->id == ZigTypeIdEnum) { if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (actual_type->data.unionation.tag_type == wanted_type) { return ir_analyze_union_to_tag(ira, source_instr, value, wanted_type); @@ -13881,8 +14995,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) { - if ((err = ir_cast_ptr_align(ira, source_instr, wanted_type, actual_type, value->source_node))) - return ira->codegen->invalid_instruction; + if ((err = ir_cast_ptr_align(ira, source_instr, wanted_type, actual_type, value->base.source_node))) + return ira->codegen->invalid_inst_gen; return ir_analyze_ptr_to_array(ira, source_instr, value, wanted_type); } @@ -13905,7 +15019,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst slice_ptr_type->data.pointer.sentinel)))) { TypeStructField *ptr_field = actual_type->data.structure.fields[slice_ptr_index]; - IrInstruction *slice_ptr = ir_analyze_struct_value_field_value(ira, source_instr, value, ptr_field); + IrInstGen *slice_ptr = ir_analyze_struct_value_field_value(ira, source_instr, value, ptr_field); return ir_implicit_cast2(ira, source_instr, slice_ptr, wanted_type); } } @@ -13925,7 +15039,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst dest_ptr_type = wanted_type->data.maybe.child_type; } if (dest_ptr_type != nullptr) { - return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr, true); + return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true); } } @@ -13936,7 +15050,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst { bool has_bits; if ((err = type_has_bits2(ira->codegen, actual_type, &has_bits))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!has_bits) { return ir_get_ref(ira, source_instr, value, false, false); } @@ -13967,7 +15081,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst actual_type->data.pointer.child_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) { - return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr, true); + return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true); } // cast from integer to C pointer @@ -14003,9 +15117,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst // T to ?U, where T implicitly casts to U if (wanted_type->id == ZigTypeIdOptional && actual_type->id != ZigTypeIdOptional) { - IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type); + IrInstGen *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type); if (type_is_invalid(cast1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); } @@ -14013,9 +15127,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id != ZigTypeIdErrorUnion && actual_type->id != ZigTypeIdErrorSet) { - IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.error_union.payload_type); + IrInstGen *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.error_union.payload_type); if (type_is_invalid(cast1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); } @@ -14024,14 +15138,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst buf_ptr(&wanted_type->name), buf_ptr(&actual_type->name))); report_recursive_error(ira, source_instr->source_node, &const_cast_result, parent_msg); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } -static IrInstruction *ir_implicit_cast2(IrAnalyze *ira, IrInstruction *value_source_instr, - IrInstruction *value, ZigType *expected_type) +static IrInstGen *ir_implicit_cast2(IrAnalyze *ira, IrInst *value_source_instr, + IrInstGen *value, ZigType *expected_type) { assert(value); - assert(value != ira->codegen->invalid_instruction); assert(!expected_type || !type_is_invalid(expected_type)); assert(value->value->type); assert(!type_is_invalid(value->value->type)); @@ -14045,17 +15158,17 @@ static IrInstruction *ir_implicit_cast2(IrAnalyze *ira, IrInstruction *value_sou return ir_analyze_cast(ira, value_source_instr, expected_type, value); } -static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) { - return ir_implicit_cast2(ira, value, value, expected_type); +static IrInstGen *ir_implicit_cast(IrAnalyze *ira, IrInstGen *value, ZigType *expected_type) { + return ir_implicit_cast2(ira, &value->base, value, expected_type); } -static ZigType *get_ptr_elem_type(CodeGen *g, IrInstruction *ptr) { - ir_assert(ptr->value->type->id == ZigTypeIdPointer, ptr); +static ZigType *get_ptr_elem_type(CodeGen *g, IrInstGen *ptr) { + ir_assert_gen(ptr->value->type->id == ZigTypeIdPointer, ptr); ZigType *elem_type = ptr->value->type->data.pointer.child_type; if (elem_type != g->builtin_types.entry_var) return elem_type; - if (ir_resolve_lazy(g, ptr->source_node, ptr->value)) + if (ir_resolve_lazy(g, ptr->base.source_node, ptr->value)) return g->builtin_types.entry_invalid; assert(value_is_comptime(ptr->value)); @@ -14063,28 +15176,28 @@ static ZigType *get_ptr_elem_type(CodeGen *g, IrInstruction *ptr) { return pointee->type; } -static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr, +static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *ptr, ResultLoc *result_loc) { Error err; ZigType *ptr_type = ptr->value->type; if (type_is_invalid(ptr_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (ptr_type->id != ZigTypeIdPointer) { ir_add_error_node(ira, source_instruction->source_node, buf_sprintf("attempt to dereference non-pointer type '%s'", buf_ptr(&ptr_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *child_type = ptr_type->data.pointer.child_type; if (type_is_invalid(child_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // if the child type has one possible value, the deref is comptime switch (type_has_one_possible_value(ira->codegen, child_type)) { case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueYes: return ir_const_move(ira, source_instruction, get_the_one_possible_value(ira->codegen, child_type)); @@ -14093,8 +15206,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc } if (instr_is_comptime(ptr)) { if (ptr->value->special == ConstValSpecialUndef) { - ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &ptr->base, buf_sprintf("attempt to dereference undefined value")); + return ira->codegen->invalid_inst_gen; } if (ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { ZigValue *pointee = const_ptr_pointee_unchecked(ira->codegen, ptr->value); @@ -14102,12 +15215,12 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc child_type = pointee->type; } if (pointee->special != ConstValSpecialRuntime) { - IrInstruction *result = ir_const(ira, source_instruction, child_type); + IrInstGen *result = ir_const(ira, source_instruction, child_type); if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, result->value, ptr->value))) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } result->value->type = child_type; return result; @@ -14116,38 +15229,37 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc } // if the instruction is a const ref instruction we can skip it - if (ptr->id == IrInstructionIdRef) { - IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr); - return ref_inst->value; + if (ptr->id == IrInstGenIdRef) { + IrInstGenRef *ref_inst = reinterpret_cast<IrInstGenRef *>(ptr); + return ref_inst->operand; } // If the instruction is a element pointer instruction to a vector, we emit // vector element extract instruction rather than load pointer. If the // pointer type has non-VECTOR_INDEX_RUNTIME value, it would have been - // possible to implement this in the codegen for IrInstructionLoadPtrGen. + // possible to implement this in the codegen for IrInstGenLoadPtr. // However if it has VECTOR_INDEX_RUNTIME then we must emit a compile error // if the vector index cannot be determined right here, right now, because // the type information does not contain enough information to actually // perform a dereference. if (ptr_type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) { - if (ptr->id == IrInstructionIdElemPtr) { - IrInstructionElemPtr *elem_ptr = (IrInstructionElemPtr *)ptr; - IrInstruction *vector_loaded = ir_get_deref(ira, elem_ptr->array_ptr, + if (ptr->id == IrInstGenIdElemPtr) { + IrInstGenElemPtr *elem_ptr = (IrInstGenElemPtr *)ptr; + IrInstGen *vector_loaded = ir_get_deref(ira, &elem_ptr->array_ptr->base, elem_ptr->array_ptr, nullptr); - IrInstruction *elem_index = elem_ptr->elem_index; + IrInstGen *elem_index = elem_ptr->elem_index; return ir_build_vector_extract_elem(ira, source_instruction, vector_loaded, elem_index); } - ir_add_error(ira, ptr, + ir_add_error(ira, &ptr->base, buf_sprintf("unable to determine vector element index of type '%s'", buf_ptr(&ptr_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *result_loc_inst; + IrInstGen *result_loc_inst; if (ptr_type->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { if (result_loc == nullptr) result_loc = no_result_loc(); - result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, - true, false, true); - if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { + result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, true, true); + if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { return result_loc_inst; } } else { @@ -14157,7 +15269,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst); } -static bool ir_resolve_const_align(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, +static bool ir_resolve_const_align(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, ZigValue *const_val, uint32_t *out) { Error err; @@ -14166,12 +15278,12 @@ static bool ir_resolve_const_align(CodeGen *codegen, IrExecutable *exec, AstNode uint32_t align_bytes = bigint_as_u32(&const_val->data.x_bigint); if (align_bytes == 0) { - exec_add_error_node(codegen, exec, source_node, buf_sprintf("alignment must be >= 1")); + exec_add_error_node_gen(codegen, exec, source_node, buf_sprintf("alignment must be >= 1")); return false; } if (!is_power_of_2(align_bytes)) { - exec_add_error_node(codegen, exec, source_node, + exec_add_error_node_gen(codegen, exec, source_node, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); return false; } @@ -14180,7 +15292,7 @@ static bool ir_resolve_const_align(CodeGen *codegen, IrExecutable *exec, AstNode return true; } -static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, ZigType *elem_type, uint32_t *out) { +static bool ir_resolve_align(IrAnalyze *ira, IrInstGen *value, ZigType *elem_type, uint32_t *out) { if (type_is_invalid(value->value->type)) return false; @@ -14201,19 +15313,19 @@ static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, ZigType *elem } } - IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); + IrInstGen *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); if (type_is_invalid(casted_value->value->type)) return false; - return ir_resolve_const_align(ira->codegen, ira->new_irb.exec, value->source_node, + return ir_resolve_const_align(ira->codegen, ira->new_irb.exec, value->base.source_node, casted_value->value, out); } -static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) { +static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstGen *value, ZigType *int_type, uint64_t *out) { if (type_is_invalid(value->value->type)) return false; - IrInstruction *casted_value = ir_implicit_cast(ira, value, int_type); + IrInstGen *casted_value = ir_implicit_cast(ira, value, int_type); if (type_is_invalid(casted_value->value->type)) return false; @@ -14225,15 +15337,15 @@ static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *i return true; } -static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) { +static bool ir_resolve_usize(IrAnalyze *ira, IrInstGen *value, uint64_t *out) { return ir_resolve_unsigned(ira, value, ira->codegen->builtin_types.entry_usize, out); } -static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *value, bool *out) { +static bool ir_resolve_bool(IrAnalyze *ira, IrInstGen *value, bool *out) { if (type_is_invalid(value->value->type)) return false; - IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_bool); + IrInstGen *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_bool); if (type_is_invalid(casted_value->value->type)) return false; @@ -14245,7 +15357,7 @@ static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *value, bool *out) { return true; } -static bool ir_resolve_comptime(IrAnalyze *ira, IrInstruction *value, bool *out) { +static bool ir_resolve_comptime(IrAnalyze *ira, IrInstGen *value, bool *out) { if (!value) { *out = false; return true; @@ -14253,13 +15365,13 @@ static bool ir_resolve_comptime(IrAnalyze *ira, IrInstruction *value, bool *out) return ir_resolve_bool(ira, value, out); } -static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, AtomicOrder *out) { +static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstGen *value, AtomicOrder *out) { if (type_is_invalid(value->value->type)) return false; ZigType *atomic_order_type = get_builtin_type(ira->codegen, "AtomicOrder"); - IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_order_type); + IrInstGen *casted_value = ir_implicit_cast(ira, value, atomic_order_type); if (type_is_invalid(casted_value->value->type)) return false; @@ -14271,13 +15383,13 @@ static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, Atomic return true; } -static bool ir_resolve_atomic_rmw_op(IrAnalyze *ira, IrInstruction *value, AtomicRmwOp *out) { +static bool ir_resolve_atomic_rmw_op(IrAnalyze *ira, IrInstGen *value, AtomicRmwOp *out) { if (type_is_invalid(value->value->type)) return false; ZigType *atomic_rmw_op_type = get_builtin_type(ira->codegen, "AtomicRmwOp"); - IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_rmw_op_type); + IrInstGen *casted_value = ir_implicit_cast(ira, value, atomic_rmw_op_type); if (type_is_invalid(casted_value->value->type)) return false; @@ -14289,13 +15401,13 @@ static bool ir_resolve_atomic_rmw_op(IrAnalyze *ira, IrInstruction *value, Atomi return true; } -static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstruction *value, GlobalLinkageId *out) { +static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstGen *value, GlobalLinkageId *out) { if (type_is_invalid(value->value->type)) return false; ZigType *global_linkage_type = get_builtin_type(ira->codegen, "GlobalLinkage"); - IrInstruction *casted_value = ir_implicit_cast(ira, value, global_linkage_type); + IrInstGen *casted_value = ir_implicit_cast(ira, value, global_linkage_type); if (type_is_invalid(casted_value->value->type)) return false; @@ -14307,13 +15419,13 @@ static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstruction *value, Glob return true; } -static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstruction *value, FloatMode *out) { +static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstGen *value, FloatMode *out) { if (type_is_invalid(value->value->type)) return false; ZigType *float_mode_type = get_builtin_type(ira->codegen, "FloatMode"); - IrInstruction *casted_value = ir_implicit_cast(ira, value, float_mode_type); + IrInstGen *casted_value = ir_implicit_cast(ira, value, float_mode_type); if (type_is_invalid(casted_value->value->type)) return false; @@ -14325,14 +15437,14 @@ static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstruction *value, FloatMod return true; } -static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { +static Buf *ir_resolve_str(IrAnalyze *ira, IrInstGen *value) { if (type_is_invalid(value->value->type)) return nullptr; ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, true, false, PtrLenUnknown, 0, 0, 0, false); ZigType *str_type = get_slice_type(ira->codegen, ptr_type); - IrInstruction *casted_value = ir_implicit_cast(ira, value, str_type); + IrInstGen *casted_value = ir_implicit_cast(ira, value, str_type); if (type_is_invalid(casted_value->value->type)) return nullptr; @@ -14356,7 +15468,7 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; ZigValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index]; if (char_val->special == ConstValSpecialUndef) { - ir_add_error(ira, casted_value, buf_sprintf("use of undefined value")); + ir_add_error(ira, &casted_value->base, buf_sprintf("use of undefined value")); return nullptr; } uint64_t big_c = bigint_as_u64(&char_val->data.x_bigint); @@ -14367,10 +15479,10 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { return result; } -static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, - IrInstructionAddImplicitReturnType *instruction) +static IrInstGen *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, + IrInstSrcAddImplicitReturnType *instruction) { - IrInstruction *value = instruction->value->child; + IrInstGen *value = instruction->value->child; if (type_is_invalid(value->value->type)) return ir_unreach_error(ira); @@ -14378,15 +15490,15 @@ static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze ira->src_implicit_return_type_list.append(value); } - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructionReturn *instruction) { - IrInstruction *operand = instruction->operand->child; +static IrInstGen *ir_analyze_instruction_return(IrAnalyze *ira, IrInstSrcReturn *instruction) { + IrInstGen *operand = instruction->operand->child; if (type_is_invalid(operand->value->type)) return ir_unreach_error(ira); - IrInstruction *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type); + IrInstGen *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type); if (type_is_invalid(casted_operand->value->type)) { AstNode *source_node = ira->explicit_return_type_source_node; if (source_node != nullptr) { @@ -14401,9 +15513,7 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio handle_is_ptr(ira->explicit_return_type)) { // result location mechanism took care of it. - IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, nullptr); - result->value->type = ira->codegen->builtin_types.entry_unreachable; + IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, nullptr); return ir_finish_anal(ira, result); } @@ -14411,47 +15521,45 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio casted_operand->value->type->id == ZigTypeIdPointer && casted_operand->value->data.rh_ptr == RuntimeHintPtrStack) { - ir_add_error(ira, casted_operand, buf_sprintf("function returns address of local variable")); + ir_add_error(ira, &instruction->operand->base, buf_sprintf("function returns address of local variable")); return ir_unreach_error(ira); } - IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, casted_operand); - result->value->type = ira->codegen->builtin_types.entry_unreachable; + IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, casted_operand); return ir_finish_anal(ira, result); } -static IrInstruction *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *instruction) { - return ir_const_move(ira, &instruction->base, instruction->base.value); +static IrInstGen *ir_analyze_instruction_const(IrAnalyze *ira, IrInstSrcConst *instruction) { + return ir_const_move(ira, &instruction->base.base, instruction->value); } -static IrInstruction *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { - IrInstruction *op1 = bin_op_instruction->op1->child; +static IrInstGen *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { + IrInstGen *op1 = bin_op_instruction->op1->child; if (type_is_invalid(op1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *op2 = bin_op_instruction->op2->child; + IrInstGen *op2 = bin_op_instruction->op2->child; if (type_is_invalid(op2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *bool_type = ira->codegen->builtin_types.entry_bool; - IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, bool_type); - if (casted_op1 == ira->codegen->invalid_instruction) - return ira->codegen->invalid_instruction; + IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, bool_type); + if (type_is_invalid(casted_op1->value->type)) + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, bool_type); - if (casted_op2 == ira->codegen->invalid_instruction) - return ira->codegen->invalid_instruction; + IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, bool_type); + if (type_is_invalid(casted_op2->value->type)) + return ira->codegen->invalid_inst_gen; if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); if (op1_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); if (op2_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; assert(casted_op1->value->type->id == ZigTypeIdBool); assert(casted_op2->value->type->id == ZigTypeIdBool); @@ -14463,14 +15571,11 @@ static IrInstruction *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp } else { zig_unreachable(); } - return ir_const_bool(ira, &bin_op_instruction->base, result_bool); + return ir_const_bool(ira, &bin_op_instruction->base.base, result_bool); } - IrInstruction *result = ir_build_bin_op(&ira->new_irb, - bin_op_instruction->base.scope, bin_op_instruction->base.source_node, + return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, bool_type, bin_op_instruction->op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); - result->value->type = bool_type; - return result; } static bool resolve_cmp_op_id(IrBinOp op_id, Cmp cmp) { @@ -14535,12 +15640,13 @@ static void set_optional_payload(ZigValue *opt_val, ZigValue *payload) { } } -static IrInstruction *ir_evaluate_bin_op_cmp(IrAnalyze *ira, ZigType *resolved_type, - ZigValue *op1_val, ZigValue *op2_val, IrInstructionBinOp *bin_op_instruction, IrBinOp op_id, - bool one_possible_value) { +static IrInstGen *ir_evaluate_bin_op_cmp(IrAnalyze *ira, ZigType *resolved_type, + ZigValue *op1_val, ZigValue *op2_val, IrInstSrcBinOp *bin_op_instruction, IrBinOp op_id, + bool one_possible_value) +{ if (op1_val->special == ConstValSpecialUndef || op2_val->special == ConstValSpecialUndef) - return ir_const_undef(ira, &bin_op_instruction->base, resolved_type); + return ir_const_undef(ira, &bin_op_instruction->base.base, resolved_type); if (resolved_type->id == ZigTypeIdPointer && op_id != IrBinOpCmpEq && op_id != IrBinOpCmpNotEq) { if ((op1_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || op1_val->data.x_ptr.special == ConstPtrSpecialNull) && @@ -14560,7 +15666,7 @@ static IrInstruction *ir_evaluate_bin_op_cmp(IrAnalyze *ira, ZigType *resolved_t cmp_result = CmpEQ; } bool answer = resolve_cmp_op_id(op_id, cmp_result); - return ir_const_bool(ira, &bin_op_instruction->base, answer); + return ir_const_bool(ira, &bin_op_instruction->base.base, answer); } } else { bool are_equal = one_possible_value || const_values_equal(ira->codegen, op1_val, op2_val); @@ -14572,15 +15678,33 @@ static IrInstruction *ir_evaluate_bin_op_cmp(IrAnalyze *ira, ZigType *resolved_t } else { zig_unreachable(); } - return ir_const_bool(ira, &bin_op_instruction->base, answer); + return ir_const_bool(ira, &bin_op_instruction->base.base, answer); } zig_unreachable(); } // Returns ErrorNotLazy when the value cannot be determined -static Error lazy_cmp_zero(AstNode *source_node, ZigValue *val, Cmp *result) { +static Error lazy_cmp_zero(CodeGen *codegen, AstNode *source_node, ZigValue *val, Cmp *result) { Error err; + switch (type_has_one_possible_value(codegen, val->type)) { + case OnePossibleValueInvalid: + return ErrorSemanticAnalyzeFail; + case OnePossibleValueNo: + break; + case OnePossibleValueYes: + switch (val->type->id) { + case ZigTypeIdInt: + src_assert(val->type->data.integral.bit_count == 0, source_node); + *result = CmpEQ; + return ErrorNone; + case ZigTypeIdUndefined: + return ErrorNotLazy; + default: + zig_unreachable(); + } + } + switch (val->special) { case ConstValSpecialRuntime: case ConstValSpecialUndef: @@ -14626,7 +15750,7 @@ static Error lazy_cmp_zero(AstNode *source_node, ZigValue *val, Cmp *result) { zig_unreachable(); } -static ErrorMsg *ir_eval_bin_op_cmp_scalar(IrAnalyze *ira, IrInstruction *source_instr, +static ErrorMsg *ir_eval_bin_op_cmp_scalar(IrAnalyze *ira, IrInst* source_instr, ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val, ZigValue *out_val) { Error err; @@ -14634,12 +15758,12 @@ static ErrorMsg *ir_eval_bin_op_cmp_scalar(IrAnalyze *ira, IrInstruction *source // Before resolving the values, we special case comparisons against zero. These can often // be done without resolving lazy values, preventing potential dependency loops. Cmp op1_cmp_zero; - if ((err = lazy_cmp_zero(source_instr->source_node, op1_val, &op1_cmp_zero))) { + if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op1_val, &op1_cmp_zero))) { if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally; return ira->codegen->trace_err; } Cmp op2_cmp_zero; - if ((err = lazy_cmp_zero(source_instr->source_node, op2_val, &op2_cmp_zero))) { + if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op2_val, &op2_cmp_zero))) { if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally; return ira->codegen->trace_err; } @@ -14704,14 +15828,14 @@ never_mind_just_calculate_it_normally: return nullptr; } if (op1_val->type->id == ZigTypeIdComptimeFloat) { - IrInstruction *tmp = ir_const_noval(ira, source_instr); + IrInstGen *tmp = ir_const_noval(ira, source_instr); tmp->value = op1_val; - IrInstruction *casted = ir_implicit_cast(ira, tmp, op2_val->type); + IrInstGen *casted = ir_implicit_cast(ira, tmp, op2_val->type); op1_val = casted->value; } else if (op2_val->type->id == ZigTypeIdComptimeFloat) { - IrInstruction *tmp = ir_const_noval(ira, source_instr); + IrInstGen *tmp = ir_const_noval(ira, source_instr); tmp->value = op2_val; - IrInstruction *casted = ir_implicit_cast(ira, tmp, op1_val->type); + IrInstGen *casted = ir_implicit_cast(ira, tmp, op1_val->type); op2_val = casted->value; } Cmp cmp_result = float_cmp(op1_val, op2_val); @@ -14723,38 +15847,49 @@ never_mind_just_calculate_it_normally: bool op1_is_int = op1_val->type->id == ZigTypeIdInt || op1_val->type->id == ZigTypeIdComptimeInt; bool op2_is_int = op2_val->type->id == ZigTypeIdInt || op2_val->type->id == ZigTypeIdComptimeInt; - BigInt *op1_bigint; - BigInt *op2_bigint; - bool need_to_free_op1_bigint = false; - bool need_to_free_op2_bigint = false; - if (op1_is_float) { - op1_bigint = allocate<BigInt>(1, "BigInt"); - need_to_free_op1_bigint = true; - float_init_bigint(op1_bigint, op1_val); - } else { - assert(op1_is_int); - op1_bigint = &op1_val->data.x_bigint; + if (op1_is_int && op2_is_int) { + Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); + out_val->special = ConstValSpecialStatic; + out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result); + + return nullptr; } - if (op2_is_float) { - op2_bigint = allocate<BigInt>(1, "BigInt"); - need_to_free_op2_bigint = true; - float_init_bigint(op2_bigint, op2_val); + + // Handle the case where one of the two operands is a fp value and the other + // is an integer value + ZigValue *float_val; + if (op1_is_int && op2_is_float) { + float_val = op2_val; + } else if (op1_is_float && op2_is_int) { + float_val = op1_val; } else { - assert(op2_is_int); - op2_bigint = &op2_val->data.x_bigint; + zig_unreachable(); + } + + // They can never be equal if the fp value has a non-zero decimal part + if (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq) { + if (float_has_fraction(float_val)) { + out_val->special = ConstValSpecialStatic; + out_val->data.x_bool = op_id == IrBinOpCmpNotEq; + return nullptr; + } } - Cmp cmp_result = bigint_cmp(op1_bigint, op2_bigint); + // Cast the integer operand into a fp value to perform the comparison + BigFloat op1_bigfloat; + BigFloat op2_bigfloat; + value_to_bigfloat(&op1_bigfloat, op1_val); + value_to_bigfloat(&op2_bigfloat, op2_val); + + Cmp cmp_result = bigfloat_cmp(&op1_bigfloat, &op2_bigfloat); out_val->special = ConstValSpecialStatic; out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result); - if (need_to_free_op1_bigint) destroy(op1_bigint, "BigInt"); - if (need_to_free_op2_bigint) destroy(op2_bigint, "BigInt"); return nullptr; } -static IrInstruction *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *op1, IrInstruction *op2, IrBinOp op_id) +static IrInstGen *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInst *source_instr, + IrInstGen *op1, IrInstGen *op2, IrBinOp op_id) { Error err; @@ -14767,7 +15902,7 @@ static IrInstruction *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInstructio ir_add_error(ira, source_instr, buf_sprintf("vector length mismatch: %" PRIu32 " and %" PRIu32, op1->value->type->data.vector.len, op2->value->type->data.vector.len)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } result_type = get_vector_type(ira->codegen, op1->value->type->data.vector.len, scalar_result_type); op1_scalar_type = op1->value->type->data.vector.elem_type; @@ -14776,13 +15911,13 @@ static IrInstruction *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInstructio ir_add_error(ira, source_instr, buf_sprintf("mixed scalar and vector operands to comparison operator: '%s' and '%s'", buf_ptr(&op1->value->type->name), buf_ptr(&op2->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } bool opv_op1; switch (type_has_one_possible_value(ira->codegen, op1->value->type)) { case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueYes: opv_op1 = true; break; @@ -14793,7 +15928,7 @@ static IrInstruction *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInstructio bool opv_op2; switch (type_has_one_possible_value(ira->codegen, op2->value->type)) { case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueYes: opv_op2 = true; break; @@ -14803,22 +15938,22 @@ static IrInstruction *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInstructio } Cmp op1_cmp_zero; bool have_op1_cmp_zero = false; - if ((err = lazy_cmp_zero(source_instr->source_node, op1->value, &op1_cmp_zero))) { - if (err != ErrorNotLazy) return ira->codegen->invalid_instruction; + if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op1->value, &op1_cmp_zero))) { + if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen; } else { have_op1_cmp_zero = true; } Cmp op2_cmp_zero; bool have_op2_cmp_zero = false; - if ((err = lazy_cmp_zero(source_instr->source_node, op2->value, &op2_cmp_zero))) { - if (err != ErrorNotLazy) return ira->codegen->invalid_instruction; + if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op2->value, &op2_cmp_zero))) { + if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen; } else { have_op2_cmp_zero = true; } if (((opv_op1 || instr_is_comptime(op1)) && (opv_op2 || instr_is_comptime(op2))) || (have_op1_cmp_zero && have_op2_cmp_zero)) { - IrInstruction *result_instruction = ir_const(ira, source_instr, result_type); + IrInstGen *result_instruction = ir_const(ira, source_instr, result_type); ZigValue *out_val = result_instruction->value; if (result_type->id == ZigTypeIdVector) { size_t len = result_type->data.vector.len; @@ -14836,7 +15971,7 @@ static IrInstruction *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInstructio if (msg != nullptr) { add_error_note(ira->codegen, msg, source_instr->source_node, buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } out_val->type = result_type; @@ -14845,7 +15980,7 @@ static IrInstruction *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInstructio if (ir_eval_bin_op_cmp_scalar(ira, source_instr, op1->value, op_id, op2->value, out_val) != nullptr) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } return result_instruction; @@ -14939,10 +16074,10 @@ static IrInstruction *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInstructio } ZigType *dest_type = (result_type->id == ZigTypeIdVector) ? get_vector_type(ira->codegen, result_type->data.vector.len, dest_scalar_type) : dest_scalar_type; - IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, dest_type); - IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, dest_type); + IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, dest_type); + IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, dest_type); if (type_is_invalid(casted_op1->value->type) || type_is_invalid(casted_op2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return ir_build_bin_op_gen(ira, source_instr, result_type, op_id, casted_op1, casted_op2, true); } @@ -14972,12 +16107,12 @@ static IrInstruction *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInstructio if (instr_is_comptime(op1)) { ZigValue *op1_val = ir_resolve_const(ira, op1, UndefOk); if (op1_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (op1_val->special == ConstValSpecialUndef) return ir_const_undef(ira, source_instr, ira->codegen->builtin_types.entry_bool); if (result_type->id == ZigTypeIdVector) { - ir_add_error(ira, op1, buf_sprintf("compiler bug: TODO: support comptime vector here")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &op1->base, buf_sprintf("compiler bug: TODO: support comptime vector here")); + return ira->codegen->invalid_inst_gen; } bool is_unsigned; if (op1_is_float) { @@ -15016,12 +16151,12 @@ static IrInstruction *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInstructio if (instr_is_comptime(op2)) { ZigValue *op2_val = ir_resolve_const(ira, op2, UndefOk); if (op2_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (op2_val->special == ConstValSpecialUndef) return ir_const_undef(ira, source_instr, ira->codegen->builtin_types.entry_bool); if (result_type->id == ZigTypeIdVector) { - ir_add_error(ira, op2, buf_sprintf("compiler bug: TODO: support comptime vector here")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &op2->base, buf_sprintf("compiler bug: TODO: support comptime vector here")); + return ira->codegen->invalid_inst_gen; } bool is_unsigned; if (op2_is_float) { @@ -15062,35 +16197,35 @@ static IrInstruction *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInstructio ZigType *dest_type = (result_type->id == ZigTypeIdVector) ? get_vector_type(ira->codegen, result_type->data.vector.len, dest_scalar_type) : dest_scalar_type; - IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, dest_type); + IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, dest_type); if (type_is_invalid(casted_op1->value->type)) - return ira->codegen->invalid_instruction; - IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, dest_type); + return ira->codegen->invalid_inst_gen; + IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, dest_type); if (type_is_invalid(casted_op2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return ir_build_bin_op_gen(ira, source_instr, result_type, op_id, casted_op1, casted_op2, true); } -static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { - IrInstruction *op1 = bin_op_instruction->op1->child; +static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { + IrInstGen *op1 = bin_op_instruction->op1->child; if (type_is_invalid(op1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *op2 = bin_op_instruction->op2->child; + IrInstGen *op2 = bin_op_instruction->op2->child; if (type_is_invalid(op2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - AstNode *source_node = bin_op_instruction->base.source_node; + AstNode *source_node = bin_op_instruction->base.base.source_node; IrBinOp op_id = bin_op_instruction->op_id; bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); if (is_equality_cmp && op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdNull) { - return ir_const_bool(ira, &bin_op_instruction->base, (op_id == IrBinOpCmpEq)); + return ir_const_bool(ira, &bin_op_instruction->base.base, (op_id == IrBinOpCmpEq)); } else if (is_equality_cmp && ((op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdOptional) || (op2->value->type->id == ZigTypeIdNull && op1->value->type->id == ZigTypeIdOptional))) { - IrInstruction *maybe_op; + IrInstGen *maybe_op; if (op1->value->type->id == ZigTypeIdNull) { maybe_op = op2; } else if (op2->value->type->id == ZigTypeIdNull) { @@ -15101,21 +16236,16 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * if (instr_is_comptime(maybe_op)) { ZigValue *maybe_val = ir_resolve_const(ira, maybe_op, UndefBad); if (!maybe_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; bool is_null = optional_value_is_null(maybe_val); bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; - return ir_const_bool(ira, &bin_op_instruction->base, bool_result); + return ir_const_bool(ira, &bin_op_instruction->base.base, bool_result); } - IrInstruction *is_non_null = ir_build_test_nonnull(&ira->new_irb, bin_op_instruction->base.scope, - source_node, maybe_op); - is_non_null->value->type = ira->codegen->builtin_types.entry_bool; + IrInstGen *is_non_null = ir_build_test_non_null_gen(ira, &bin_op_instruction->base.base, maybe_op); if (op_id == IrBinOpCmpEq) { - IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope, - bin_op_instruction->base.source_node, is_non_null); - result->value->type = ira->codegen->builtin_types.entry_bool; - return result; + return ir_build_bool_not_gen(ira, &bin_op_instruction->base.base, is_non_null); } else { return is_non_null; } @@ -15125,7 +16255,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * (op2->value->type->id == ZigTypeIdNull && op1->value->type->id == ZigTypeIdPointer && op1->value->type->data.pointer.ptr_len == PtrLenC))) { - IrInstruction *c_ptr_op; + IrInstGen *c_ptr_op; if (op1->value->type->id == ZigTypeIdNull) { c_ptr_op = op2; } else if (op2->value->type->id == ZigTypeIdNull) { @@ -15136,24 +16266,19 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * if (instr_is_comptime(c_ptr_op)) { ZigValue *c_ptr_val = ir_resolve_const(ira, c_ptr_op, UndefOk); if (!c_ptr_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (c_ptr_val->special == ConstValSpecialUndef) - return ir_const_undef(ira, &bin_op_instruction->base, ira->codegen->builtin_types.entry_bool); + return ir_const_undef(ira, &bin_op_instruction->base.base, ira->codegen->builtin_types.entry_bool); bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; - return ir_const_bool(ira, &bin_op_instruction->base, bool_result); + return ir_const_bool(ira, &bin_op_instruction->base.base, bool_result); } - IrInstruction *is_non_null = ir_build_test_nonnull(&ira->new_irb, bin_op_instruction->base.scope, - source_node, c_ptr_op); - is_non_null->value->type = ira->codegen->builtin_types.entry_bool; + IrInstGen *is_non_null = ir_build_test_non_null_gen(ira, &bin_op_instruction->base.base, c_ptr_op); if (op_id == IrBinOpCmpEq) { - IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope, - bin_op_instruction->base.source_node, is_non_null); - result->value->type = ira->codegen->builtin_types.entry_bool; - return result; + return ir_build_bool_not_gen(ira, &bin_op_instruction->base.base, is_non_null); } else { return is_non_null; } @@ -15161,61 +16286,57 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * ZigType *non_null_type = (op1->value->type->id == ZigTypeIdNull) ? op2->value->type : op1->value->type; ir_add_error_node(ira, source_node, buf_sprintf("comparison of '%s' with null", buf_ptr(&non_null_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (is_equality_cmp && ( (op1->value->type->id == ZigTypeIdEnumLiteral && op2->value->type->id == ZigTypeIdUnion) || (op2->value->type->id == ZigTypeIdEnumLiteral && op1->value->type->id == ZigTypeIdUnion))) { // Support equality comparison between a union's tag value and a enum literal - IrInstruction *union_val = op1->value->type->id == ZigTypeIdUnion ? op1 : op2; - IrInstruction *enum_val = op1->value->type->id == ZigTypeIdUnion ? op2 : op1; + IrInstGen *union_val = op1->value->type->id == ZigTypeIdUnion ? op1 : op2; + IrInstGen *enum_val = op1->value->type->id == ZigTypeIdUnion ? op2 : op1; ZigType *tag_type = union_val->value->type->data.unionation.tag_type; assert(tag_type != nullptr); - IrInstruction *casted_union = ir_implicit_cast(ira, union_val, tag_type); + IrInstGen *casted_union = ir_implicit_cast(ira, union_val, tag_type); if (type_is_invalid(casted_union->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_val = ir_implicit_cast(ira, enum_val, tag_type); + IrInstGen *casted_val = ir_implicit_cast(ira, enum_val, tag_type); if (type_is_invalid(casted_val->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (instr_is_comptime(casted_union)) { ZigValue *const_union_val = ir_resolve_const(ira, casted_union, UndefBad); if (!const_union_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *const_enum_val = ir_resolve_const(ira, casted_val, UndefBad); if (!const_enum_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; Cmp cmp_result = bigint_cmp(&const_union_val->data.x_union.tag, &const_enum_val->data.x_enum_tag); bool bool_result = (op_id == IrBinOpCmpEq) ? cmp_result == CmpEQ : cmp_result != CmpEQ; - return ir_const_bool(ira, &bin_op_instruction->base, bool_result); + return ir_const_bool(ira, &bin_op_instruction->base.base, bool_result); } - IrInstruction *result = ir_build_bin_op(&ira->new_irb, - bin_op_instruction->base.scope, bin_op_instruction->base.source_node, + return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, ira->codegen->builtin_types.entry_bool, op_id, casted_union, casted_val, bin_op_instruction->safety_check_on); - result->value->type = ira->codegen->builtin_types.entry_bool; - - return result; } if (op1->value->type->id == ZigTypeIdErrorSet && op2->value->type->id == ZigTypeIdErrorSet) { if (!is_equality_cmp) { ir_add_error_node(ira, source_node, buf_sprintf("operator not allowed for errors")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *intersect_type = get_error_set_intersection(ira, op1->value->type, op2->value->type, source_node); if (type_is_invalid(intersect_type)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (!resolve_inferred_error_set(ira->codegen, intersect_type, source_node)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } // exception if one of the operators has the type of the empty error set, we allow the comparison @@ -15232,7 +16353,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * } else { zig_unreachable(); } - return ir_const_bool(ira, &bin_op_instruction->base, answer); + return ir_const_bool(ira, &bin_op_instruction->base.base, answer); } if (!type_is_global_error_set(intersect_type)) { @@ -15240,7 +16361,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * ir_add_error_node(ira, source_node, buf_sprintf("error sets '%s' and '%s' have no common errors", buf_ptr(&op1->value->type->name), buf_ptr(&op2->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (op1->value->type->data.error_set.err_count == 1 && op2->value->type->data.error_set.err_count == 1) { bool are_equal = true; @@ -15252,17 +16373,17 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * } else { zig_unreachable(); } - return ir_const_bool(ira, &bin_op_instruction->base, answer); + return ir_const_bool(ira, &bin_op_instruction->base.base, answer); } } if (instr_is_comptime(op1) && instr_is_comptime(op2)) { ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); if (op1_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); if (op2_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; bool answer; bool are_equal = op1_val->data.x_err_set->value == op2_val->data.x_err_set->value; @@ -15274,27 +16395,24 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * zig_unreachable(); } - return ir_const_bool(ira, &bin_op_instruction->base, answer); + return ir_const_bool(ira, &bin_op_instruction->base.base, answer); } - IrInstruction *result = ir_build_bin_op(&ira->new_irb, - bin_op_instruction->base.scope, bin_op_instruction->base.source_node, + return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, ira->codegen->builtin_types.entry_bool, op_id, op1, op2, bin_op_instruction->safety_check_on); - result->value->type = ira->codegen->builtin_types.entry_bool; - return result; } if (type_is_numeric(op1->value->type) && type_is_numeric(op2->value->type)) { // This operation allows any combination of integer and float types, regardless of the // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for // numeric types. - return ir_analyze_bin_op_cmp_numeric(ira, &bin_op_instruction->base, op1, op2, op_id); + return ir_analyze_bin_op_cmp_numeric(ira, &bin_op_instruction->base.base, op1, op2, op_id); } - IrInstruction *instructions[] = {op1, op2}; + IrInstGen *instructions[] = {op1, op2}; ZigType *resolved_type = ir_resolve_peer_types(ira, source_node, nullptr, instructions, 2); if (type_is_invalid(resolved_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; bool operator_allowed; switch (resolved_type->id) { @@ -15342,21 +16460,21 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * if (!operator_allowed) { ir_add_error_node(ira, source_node, buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); - if (casted_op1 == ira->codegen->invalid_instruction) - return ira->codegen->invalid_instruction; + IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); + if (type_is_invalid(casted_op1->value->type)) + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); - if (casted_op2 == ira->codegen->invalid_instruction) - return ira->codegen->invalid_instruction; + IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); + if (type_is_invalid(casted_op2->value->type)) + return ira->codegen->invalid_inst_gen; bool one_possible_value; switch (type_has_one_possible_value(ira->codegen, resolved_type)) { case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueYes: one_possible_value = true; break; @@ -15368,20 +16486,20 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * if (one_possible_value || (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2))) { ZigValue *op1_val = one_possible_value ? casted_op1->value : ir_resolve_const(ira, casted_op1, UndefBad); if (op1_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *op2_val = one_possible_value ? casted_op2->value : ir_resolve_const(ira, casted_op2, UndefBad); if (op2_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (resolved_type->id != ZigTypeIdVector) return ir_evaluate_bin_op_cmp(ira, resolved_type, op1_val, op2_val, bin_op_instruction, op_id, one_possible_value); - IrInstruction *result = ir_const(ira, &bin_op_instruction->base, + IrInstGen *result = ir_const(ira, &bin_op_instruction->base.base, get_vector_type(ira->codegen, resolved_type->data.vector.len, ira->codegen->builtin_types.entry_bool)); result->value->data.x_array.data.s_none.elements = create_const_vals(resolved_type->data.vector.len); expand_undef_array(ira->codegen, result->value); for (size_t i = 0;i < resolved_type->data.vector.len;i++) { - IrInstruction *cur_res = ir_evaluate_bin_op_cmp(ira, resolved_type->data.vector.elem_type, + IrInstGen *cur_res = ir_evaluate_bin_op_cmp(ira, resolved_type->data.vector.elem_type, &op1_val->data.x_array.data.s_none.elements[i], &op2_val->data.x_array.data.s_none.elements[i], bin_op_instruction, op_id, one_possible_value); @@ -15390,19 +16508,14 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * return result; } - IrInstruction *result = ir_build_bin_op(&ira->new_irb, - bin_op_instruction->base.scope, bin_op_instruction->base.source_node, + ZigType *res_type = (resolved_type->id == ZigTypeIdVector) ? + get_vector_type(ira->codegen, resolved_type->data.vector.len, ira->codegen->builtin_types.entry_bool) : + ira->codegen->builtin_types.entry_bool; + return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, res_type, op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); - if (resolved_type->id == ZigTypeIdVector) { - result->value->type = get_vector_type(ira->codegen, resolved_type->data.vector.len, - ira->codegen->builtin_types.entry_bool); - } else { - result->value->type = ira->codegen->builtin_types.entry_bool; - } - return result; } -static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *type_entry, +static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInst* source_instr, ZigType *type_entry, ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val, ZigValue *out_val) { bool is_int; @@ -15582,10 +16695,10 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_in } // This works on operands that have already been checked to be comptime known. -static IrInstruction *ir_analyze_math_op(IrAnalyze *ira, IrInstruction *source_instr, +static IrInstGen *ir_analyze_math_op(IrAnalyze *ira, IrInst* source_instr, ZigType *type_entry, ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val) { - IrInstruction *result_instruction = ir_const(ira, source_instr, type_entry); + IrInstGen *result_instruction = ir_const(ira, source_instr, type_entry); ZigValue *out_val = result_instruction->value; if (type_entry->id == ZigTypeIdVector) { expand_undef_array(ira->codegen, op1_val); @@ -15606,43 +16719,43 @@ static IrInstruction *ir_analyze_math_op(IrAnalyze *ira, IrInstruction *source_i if (msg != nullptr) { add_error_note(ira->codegen, msg, source_instr->source_node, buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } out_val->type = type_entry; out_val->special = ConstValSpecialStatic; } else { if (ir_eval_math_op_scalar(ira, source_instr, type_entry, op1_val, op_id, op2_val, out_val) != nullptr) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } return ir_implicit_cast(ira, result_instruction, type_entry); } -static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { - IrInstruction *op1 = bin_op_instruction->op1->child; +static IrInstGen *ir_analyze_bit_shift(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { + IrInstGen *op1 = bin_op_instruction->op1->child; if (type_is_invalid(op1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (op1->value->type->id != ZigTypeIdInt && op1->value->type->id != ZigTypeIdComptimeInt) { - ir_add_error(ira, bin_op_instruction->op1, + ir_add_error(ira, &bin_op_instruction->op1->base, buf_sprintf("bit shifting operation expected integer type, found '%s'", buf_ptr(&op1->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *op2 = bin_op_instruction->op2->child; + IrInstGen *op2 = bin_op_instruction->op2->child; if (type_is_invalid(op2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (op2->value->type->id != ZigTypeIdInt && op2->value->type->id != ZigTypeIdComptimeInt) { - ir_add_error(ira, bin_op_instruction->op2, + ir_add_error(ira, &bin_op_instruction->op2->base, buf_sprintf("shift amount has to be an integer type, but found '%s'", buf_ptr(&op2->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *casted_op2; + IrInstGen *casted_op2; IrBinOp op_id = bin_op_instruction->op_id; if (op1->value->type->id == ZigTypeIdComptimeInt) { casted_op2 = op2; @@ -15654,8 +16767,8 @@ static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *b if (casted_op2->value->data.x_bigint.is_negative) { Buf *val_buf = buf_alloc(); bigint_append_buf(val_buf, &casted_op2->value->data.x_bigint, 10); - ir_add_error(ira, casted_op2, buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &casted_op2->base, buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); + return ira->codegen->invalid_inst_gen; } } else { ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, @@ -15665,57 +16778,51 @@ static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *b ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); if (op2_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!bigint_fits_in_bits(&op2_val->data.x_bigint, shift_amt_type->data.integral.bit_count, op2_val->data.x_bigint.is_negative)) { Buf *val_buf = buf_alloc(); bigint_append_buf(val_buf, &op2_val->data.x_bigint, 10); ErrorMsg* msg = ir_add_error(ira, - &bin_op_instruction->base, + &bin_op_instruction->base.base, buf_sprintf("RHS of shift is too large for LHS type")); add_error_note( ira->codegen, msg, - op2->source_node, + op2->base.source_node, buf_sprintf("value %s cannot fit into type %s", buf_ptr(val_buf), buf_ptr(&shift_amt_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); - if (casted_op2 == ira->codegen->invalid_instruction) - return ira->codegen->invalid_instruction; + if (type_is_invalid(casted_op2->value->type)) + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) { ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); if (op1_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); if (op2_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_math_op(ira, &bin_op_instruction->base, op1->value->type, op1_val, op_id, op2_val); + return ir_analyze_math_op(ira, &bin_op_instruction->base.base, op1->value->type, op1_val, op_id, op2_val); } else if (op1->value->type->id == ZigTypeIdComptimeInt) { - ir_add_error(ira, &bin_op_instruction->base, + ir_add_error(ira, &bin_op_instruction->base.base, buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (instr_is_comptime(casted_op2) && bigint_cmp_zero(&casted_op2->value->data.x_bigint) == CmpEQ) { - IrInstruction *result = ir_build_cast(&ira->new_irb, bin_op_instruction->base.scope, - bin_op_instruction->base.source_node, op1->value->type, op1, CastOpNoop); - result->value->type = op1->value->type; - return result; + return ir_build_cast(ira, &bin_op_instruction->base.base, op1->value->type, op1, CastOpNoop); } - IrInstruction *result = ir_build_bin_op(&ira->new_irb, bin_op_instruction->base.scope, - bin_op_instruction->base.source_node, op_id, - op1, casted_op2, bin_op_instruction->safety_check_on); - result->value->type = op1->value->type; - return result; + return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, op1->value->type, + op_id, op1, casted_op2, bin_op_instruction->safety_check_on); } static bool ok_float_op(IrBinOp op) { @@ -15779,24 +16886,24 @@ static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) { zig_unreachable(); } -static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) { +static IrInstGen *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstSrcBinOp *instruction) { Error err; - IrInstruction *op1 = instruction->op1->child; + IrInstGen *op1 = instruction->op1->child; if (type_is_invalid(op1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *op2 = instruction->op2->child; + IrInstGen *op2 = instruction->op2->child; if (type_is_invalid(op2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; IrBinOp op_id = instruction->op_id; // look for pointer math if (is_pointer_arithmetic_allowed(op1->value->type, op_id)) { - IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, ira->codegen->builtin_types.entry_usize); + IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, ira->codegen->builtin_types.entry_usize); if (type_is_invalid(casted_op2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // If either operand is undef, result is undef. ZigValue *op1_val = nullptr; @@ -15804,28 +16911,28 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp if (instr_is_comptime(op1)) { op1_val = ir_resolve_const(ira, op1, UndefOk); if (op1_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (op1_val->special == ConstValSpecialUndef) - return ir_const_undef(ira, &instruction->base, op1->value->type); + return ir_const_undef(ira, &instruction->base.base, op1->value->type); } if (instr_is_comptime(casted_op2)) { op2_val = ir_resolve_const(ira, casted_op2, UndefOk); if (op2_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (op2_val->special == ConstValSpecialUndef) - return ir_const_undef(ira, &instruction->base, op1->value->type); + return ir_const_undef(ira, &instruction->base.base, op1->value->type); } ZigType *elem_type = op1->value->type->data.pointer.child_type; if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // NOTE: this variable is meaningful iff op2_val is not null! uint64_t byte_offset; if (op2_val != nullptr) { uint64_t elem_offset; if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; byte_offset = type_size(ira->codegen, elem_type) * elem_offset; } @@ -15840,7 +16947,7 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp { uint32_t align_bytes; if ((err = resolve_ptr_align(ira, op1->value->type, &align_bytes))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // If the addend is not a comptime-known value we can still count on // it being a multiple of the type size @@ -15869,23 +16976,20 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp } else { zig_unreachable(); } - IrInstruction *result = ir_const(ira, &instruction->base, result_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; result->value->data.x_ptr.data.hard_coded_addr.addr = new_addr; return result; } - IrInstruction *result = ir_build_bin_op(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, op_id, op1, casted_op2, true); - result->value->type = result_type; - return result; + return ir_build_bin_op_gen(ira, &instruction->base.base, result_type, op_id, op1, casted_op2, true); } - IrInstruction *instructions[] = {op1, op2}; - ZigType *resolved_type = ir_resolve_peer_types(ira, instruction->base.source_node, nullptr, instructions, 2); + IrInstGen *instructions[] = {op1, op2}; + ZigType *resolved_type = ir_resolve_peer_types(ira, instruction->base.base.source_node, nullptr, instructions, 2); if (type_is_invalid(resolved_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; bool is_int = resolved_type->id == ZigTypeIdInt || resolved_type->id == ZigTypeIdComptimeInt; bool is_float = resolved_type->id == ZigTypeIdFloat || resolved_type->id == ZigTypeIdComptimeFloat; @@ -15905,11 +17009,11 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp if (instr_is_comptime(op1) && instr_is_comptime(op2)) { ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); if (op1_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); if (op2_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (bigint_cmp_zero(&op2_val->data.x_bigint) == CmpEQ) { // the division by zero error will be caught later, but we don't have a @@ -15928,11 +17032,11 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp } } if (!ok) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("division with '%s' and '%s': signed integers must use @divTrunc, @divFloor, or @divExact", buf_ptr(&op1->value->type->name), buf_ptr(&op2->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else { op_id = IrBinOpDivTrunc; @@ -15943,12 +17047,12 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp if (instr_is_comptime(op1) && instr_is_comptime(op2)) { ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); if (op1_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (is_int) { ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); if (op2_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (bigint_cmp_zero(&op2->value->data.x_bigint) == CmpEQ) { // the division by zero error will be caught later, but we don't @@ -15962,13 +17066,13 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ; } } else { - IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); - if (casted_op2 == ira->codegen->invalid_instruction) - return ira->codegen->invalid_instruction; + IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); + if (type_is_invalid(casted_op2->value->type)) + return ira->codegen->invalid_inst_gen; ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); if (op2_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (float_cmp_zero(casted_op2->value) == CmpEQ) { // the division by zero error will be caught later, but we don't @@ -15984,11 +17088,11 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp } } if (!ok) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("remainder division with '%s' and '%s': signed integers and floats must use @rem or @mod", buf_ptr(&op1->value->type->name), buf_ptr(&op2->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } op_id = IrBinOpRemRem; @@ -16008,12 +17112,12 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp } } if (!ok) { - AstNode *source_node = instruction->base.source_node; + AstNode *source_node = instruction->base.base.source_node; ir_add_error_node(ira, source_node, buf_sprintf("invalid operands to binary expression: '%s' and '%s'", buf_ptr(&op1->value->type->name), buf_ptr(&op2->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (resolved_type->id == ZigTypeIdComptimeInt) { @@ -16026,33 +17130,31 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp } } - IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); - if (casted_op1 == ira->codegen->invalid_instruction) - return ira->codegen->invalid_instruction; + IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); + if (type_is_invalid(casted_op1->value->type)) + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); - if (casted_op2 == ira->codegen->invalid_instruction) - return ira->codegen->invalid_instruction; + IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); + if (type_is_invalid(casted_op2->value->type)) + return ira->codegen->invalid_inst_gen; if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); if (op1_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); if (op2_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_math_op(ira, &instruction->base, resolved_type, op1_val, op_id, op2_val); + return ir_analyze_math_op(ira, &instruction->base.base, resolved_type, op1_val, op_id, op2_val); } - IrInstruction *result = ir_build_bin_op(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, op_id, casted_op1, casted_op2, instruction->safety_check_on); - result->value->type = resolved_type; - return result; + return ir_build_bin_op_gen(ira, &instruction->base.base, resolved_type, + op_id, casted_op1, casted_op2, instruction->safety_check_on); } -static IrInstruction *ir_analyze_tuple_cat(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *op1, IrInstruction *op2) +static IrInstGen *ir_analyze_tuple_cat(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *op1, IrInstGen *op2) { Error err; ZigType *op1_type = op1->value->type; @@ -16069,10 +17171,10 @@ static IrInstruction *ir_analyze_tuple_cat(IrAnalyze *ira, IrInstruction *source new_type->data.structure.special = StructSpecialInferredTuple; new_type->data.structure.resolve_status = ResolveStatusBeingInferred; - bool is_comptime = ir_should_inline(ira->new_irb.exec, source_instr->scope); + bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope); - IrInstruction *new_struct_ptr = ir_resolve_result(ira, source_instr, no_result_loc(), - new_type, nullptr, false, false, true); + IrInstGen *new_struct_ptr = ir_resolve_result(ira, source_instr, no_result_loc(), + new_type, nullptr, false, true); uint32_t new_field_count = op1_field_count + op2_field_count; new_type->data.structure.src_field_count = new_field_count; @@ -16095,13 +17197,13 @@ static IrInstruction *ir_analyze_tuple_cat(IrAnalyze *ira, IrInstruction *source new_field->is_comptime = src_field->is_comptime; } if ((err = type_resolve(ira->codegen, new_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - ZigList<IrInstruction *> const_ptrs = {}; - IrInstruction *first_non_const_instruction = nullptr; + ZigList<IrInstGen *> const_ptrs = {}; + IrInstGen *first_non_const_instruction = nullptr; for (uint32_t i = 0; i < new_field_count; i += 1) { TypeStructField *dst_field = new_type->data.structure.fields[i]; - IrInstruction *src_struct_op; + IrInstGen *src_struct_op; TypeStructField *src_field; if (i < op1_field_count) { src_field = op1_type->data.structure.fields[i]; @@ -16110,73 +17212,73 @@ static IrInstruction *ir_analyze_tuple_cat(IrAnalyze *ira, IrInstruction *source src_field = op2_type->data.structure.fields[i - op1_field_count]; src_struct_op = op2; } - IrInstruction *field_value = ir_analyze_struct_value_field_value(ira, source_instr, + IrInstGen *field_value = ir_analyze_struct_value_field_value(ira, source_instr, src_struct_op, src_field); if (type_is_invalid(field_value->value->type)) - return ira->codegen->invalid_instruction; - IrInstruction *dest_ptr = ir_analyze_struct_field_ptr(ira, source_instr, dst_field, + return ira->codegen->invalid_inst_gen; + IrInstGen *dest_ptr = ir_analyze_struct_field_ptr(ira, source_instr, dst_field, new_struct_ptr, new_type, true); if (type_is_invalid(dest_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (instr_is_comptime(field_value)) { const_ptrs.append(dest_ptr); } else { first_non_const_instruction = field_value; } - IrInstruction *store_ptr_inst = ir_analyze_store_ptr(ira, source_instr, dest_ptr, field_value, + IrInstGen *store_ptr_inst = ir_analyze_store_ptr(ira, source_instr, dest_ptr, field_value, true); if (type_is_invalid(store_ptr_inst->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (const_ptrs.length != new_field_count) { new_struct_ptr->value->special = ConstValSpecialRuntime; for (size_t i = 0; i < const_ptrs.length; i += 1) { - IrInstruction *elem_result_loc = const_ptrs.at(i); + IrInstGen *elem_result_loc = const_ptrs.at(i); assert(elem_result_loc->value->special == ConstValSpecialStatic); if (elem_result_loc->value->type->data.pointer.inferred_struct_field != nullptr) { // This field will be generated comptime; no need to do this. continue; } - IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr); + IrInstGen *deref = ir_get_deref(ira, &elem_result_loc->base, elem_result_loc, nullptr); elem_result_loc->value->special = ConstValSpecialRuntime; - ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref, false); + ir_analyze_store_ptr(ira, &elem_result_loc->base, elem_result_loc, deref, false); } } - IrInstruction *result = ir_get_deref(ira, source_instr, new_struct_ptr, nullptr); + IrInstGen *result = ir_get_deref(ira, source_instr, new_struct_ptr, nullptr); if (instr_is_comptime(result)) return result; if (is_comptime) { - ir_add_error_node(ira, first_non_const_instruction->source_node, + ir_add_error(ira, &first_non_const_instruction->base, buf_sprintf("unable to evaluate constant expression")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return result; } -static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruction) { - IrInstruction *op1 = instruction->op1->child; +static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instruction) { + IrInstGen *op1 = instruction->op1->child; ZigType *op1_type = op1->value->type; if (type_is_invalid(op1_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *op2 = instruction->op2->child; + IrInstGen *op2 = instruction->op2->child; ZigType *op2_type = op2->value->type; if (type_is_invalid(op2_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (is_tuple(op1_type) && is_tuple(op2_type)) { - return ir_analyze_tuple_cat(ira, &instruction->base, op1, op2); + return ir_analyze_tuple_cat(ira, &instruction->base.base, op1, op2); } ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); if (!op1_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); if (!op2_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *sentinel1 = nullptr; ZigValue *op1_array_val; @@ -16214,15 +17316,15 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i { ZigType *array_type = op1_type->data.pointer.child_type; child_type = array_type->data.array.child_type; - op1_array_val = const_ptr_pointee(ira, ira->codegen, op1_val, op1->source_node); + op1_array_val = const_ptr_pointee(ira, ira->codegen, op1_val, op1->base.source_node); if (op1_array_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; op1_array_index = 0; op1_array_end = array_type->data.array.len; sentinel1 = array_type->data.array.sentinel; } else { - ir_add_error(ira, op1, buf_sprintf("expected array, found '%s'", buf_ptr(&op1->value->type->name))); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &op1->base, buf_sprintf("expected array, found '%s'", buf_ptr(&op1->value->type->name))); + return ira->codegen->invalid_inst_gen; } ZigValue *sentinel2 = nullptr; @@ -16262,23 +17364,23 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i { ZigType *array_type = op2_type->data.pointer.child_type; op2_type_valid = array_type->data.array.child_type == child_type; - op2_array_val = const_ptr_pointee(ira, ira->codegen, op2_val, op2->source_node); + op2_array_val = const_ptr_pointee(ira, ira->codegen, op2_val, op2->base.source_node); if (op2_array_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; op2_array_index = 0; op2_array_end = array_type->data.array.len; sentinel2 = array_type->data.array.sentinel; } else { - ir_add_error(ira, op2, + ir_add_error(ira, &op2->base, buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (!op2_type_valid) { - ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", + ir_add_error(ira, &op2->base, buf_sprintf("expected array of type '%s', found '%s'", buf_ptr(&child_type->name), buf_ptr(&op2->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigValue *sentinel; @@ -16295,7 +17397,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i } // The type of result is populated in the following if blocks - IrInstruction *result = ir_const(ira, &instruction->base, nullptr); + IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); ZigValue *out_val = result->value; ZigValue *out_array_val; @@ -16383,14 +17485,14 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i return result; } -static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *instruction) { - IrInstruction *op1 = instruction->op1->child; +static IrInstGen *ir_analyze_array_mult(IrAnalyze *ira, IrInstSrcBinOp *instruction) { + IrInstGen *op1 = instruction->op1->child; if (type_is_invalid(op1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *op2 = instruction->op2->child; + IrInstGen *op2 = instruction->op2->child; if (type_is_invalid(op2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; bool want_ptr_to_array = false; ZigType *array_type; @@ -16399,49 +17501,49 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * array_type = op1->value->type; array_val = ir_resolve_const(ira, op1, UndefOk); if (array_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (op1->value->type->id == ZigTypeIdPointer && op1->value->type->data.pointer.ptr_len == PtrLenSingle && op1->value->type->data.pointer.child_type->id == ZigTypeIdArray) { array_type = op1->value->type->data.pointer.child_type; - IrInstruction *array_inst = ir_get_deref(ira, op1, op1, nullptr); + IrInstGen *array_inst = ir_get_deref(ira, &op1->base, op1, nullptr); if (type_is_invalid(array_inst->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; array_val = ir_resolve_const(ira, array_inst, UndefOk); if (array_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; want_ptr_to_array = true; } else { - ir_add_error(ira, op1, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value->type->name))); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &op1->base, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value->type->name))); + return ira->codegen->invalid_inst_gen; } uint64_t mult_amt; if (!ir_resolve_usize(ira, op2, &mult_amt)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint64_t old_array_len = array_type->data.array.len; uint64_t new_array_len; if (mul_u64_overflow(old_array_len, mult_amt, &new_array_len)) { - ir_add_error(ira, &instruction->base, buf_sprintf("operation results in overflow")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("operation results in overflow")); + return ira->codegen->invalid_inst_gen; } ZigType *child_type = array_type->data.array.child_type; ZigType *result_array_type = get_array_type(ira->codegen, child_type, new_array_len, array_type->data.array.sentinel); - IrInstruction *array_result; + IrInstGen *array_result; if (array_val->special == ConstValSpecialUndef || array_val->data.x_array.special == ConstArraySpecialUndef) { - array_result = ir_const_undef(ira, &instruction->base, result_array_type); + array_result = ir_const_undef(ira, &instruction->base.base, result_array_type); } else { - array_result = ir_const(ira, &instruction->base, result_array_type); + array_result = ir_const(ira, &instruction->base.base, result_array_type); ZigValue *out_val = array_result->value; switch (type_has_one_possible_value(ira->codegen, result_array_type)) { case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueYes: goto skip_computation; case OnePossibleValueNo: @@ -16477,35 +17579,35 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * } skip_computation: if (want_ptr_to_array) { - return ir_get_ref(ira, &instruction->base, array_result, true, false); + return ir_get_ref(ira, &instruction->base.base, array_result, true, false); } else { return array_result; } } -static IrInstruction *ir_analyze_instruction_merge_err_sets(IrAnalyze *ira, - IrInstructionMergeErrSets *instruction) +static IrInstGen *ir_analyze_instruction_merge_err_sets(IrAnalyze *ira, + IrInstSrcMergeErrSets *instruction) { - ZigType *op1_type = ir_resolve_error_set_type(ira, &instruction->base, instruction->op1->child); + ZigType *op1_type = ir_resolve_error_set_type(ira, &instruction->base.base, instruction->op1->child); if (type_is_invalid(op1_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - ZigType *op2_type = ir_resolve_error_set_type(ira, &instruction->base, instruction->op2->child); + ZigType *op2_type = ir_resolve_error_set_type(ira, &instruction->base.base, instruction->op2->child); if (type_is_invalid(op2_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (type_is_global_error_set(op1_type) || type_is_global_error_set(op2_type)) { - return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_global_error_set); + return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_global_error_set); } - if (!resolve_inferred_error_set(ira->codegen, op1_type, instruction->op1->child->source_node)) { - return ira->codegen->invalid_instruction; + if (!resolve_inferred_error_set(ira->codegen, op1_type, instruction->op1->child->base.source_node)) { + return ira->codegen->invalid_inst_gen; } - if (!resolve_inferred_error_set(ira->codegen, op2_type, instruction->op2->child->source_node)) { - return ira->codegen->invalid_instruction; + if (!resolve_inferred_error_set(ira->codegen, op2_type, instruction->op2->child->base.source_node)) { + return ira->codegen->invalid_inst_gen; } size_t errors_count = ira->codegen->errors_by_index.length; @@ -16518,11 +17620,11 @@ static IrInstruction *ir_analyze_instruction_merge_err_sets(IrAnalyze *ira, ZigType *result_type = get_error_set_union(ira->codegen, errors, op1_type, op2_type, instruction->type_name); deallocate(errors, errors_count, "ErrorTableEntry *"); - return ir_const_type(ira, &instruction->base, result_type); + return ir_const_type(ira, &instruction->base.base, result_type); } -static IrInstruction *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { +static IrInstGen *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { IrBinOp op_id = bin_op_instruction->op_id; switch (op_id) { case IrBinOpInvalid: @@ -16567,41 +17669,39 @@ static IrInstruction *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructio zig_unreachable(); } -static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, - IrInstructionDeclVarSrc *decl_var_instruction) -{ +static IrInstGen *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstSrcDeclVar *decl_var_instruction) { Error err; ZigVar *var = decl_var_instruction->var; ZigType *explicit_type = nullptr; - IrInstruction *var_type = nullptr; + IrInstGen *var_type = nullptr; if (decl_var_instruction->var_type != nullptr) { var_type = decl_var_instruction->var_type->child; ZigType *proposed_type = ir_resolve_type(ira, var_type); - explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type); + explicit_type = validate_var_type(ira->codegen, var_type->base.source_node, proposed_type); if (type_is_invalid(explicit_type)) { var->var_type = ira->codegen->builtin_types.entry_invalid; - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } - AstNode *source_node = decl_var_instruction->base.source_node; + AstNode *source_node = decl_var_instruction->base.base.source_node; bool is_comptime_var = ir_get_var_is_comptime(var); bool var_class_requires_const = false; - IrInstruction *var_ptr = decl_var_instruction->ptr->child; + IrInstGen *var_ptr = decl_var_instruction->ptr->child; // if this is null, a compiler error happened and did not initialize the variable. // if there are no compile errors there may be a missing ir_expr_wrap in pass1 IR generation. if (var_ptr == nullptr || type_is_invalid(var_ptr->value->type)) { - ir_assert(var_ptr != nullptr || ira->codegen->errors.length != 0, &decl_var_instruction->base); + ir_assert(var_ptr != nullptr || ira->codegen->errors.length != 0, &decl_var_instruction->base.base); var->var_type = ira->codegen->builtin_types.entry_invalid; - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } // The ir_build_var_decl_src call is supposed to pass a pointer to the allocation, not an initialization value. - ir_assert(var_ptr->value->type->id == ZigTypeIdPointer, &decl_var_instruction->base); + ir_assert(var_ptr->value->type->id == ZigTypeIdPointer, &decl_var_instruction->base.base); ZigType *result_type = var_ptr->value->type->data.pointer.child_type; if (type_is_invalid(result_type)) { @@ -16612,7 +17712,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, ZigValue *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); + init_val = const_ptr_pointee(ira, ira->codegen, var_ptr->value, decl_var_instruction->base.base.source_node); if (is_comptime_var) { if (var->gen_is_const) { var->const_value = init_val; @@ -16639,7 +17739,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, case ReqCompTimeNo: if (init_val != nullptr && value_is_comptime(init_val)) { if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, - decl_var_instruction->base.source_node, init_val, UndefOk))) + decl_var_instruction->base.base.source_node, init_val, UndefOk))) { result_type = ira->codegen->builtin_types.entry_invalid; } else if (init_val->type->id == ZigTypeIdFn && @@ -16660,42 +17760,27 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, break; } - if (var->var_type != nullptr && !is_comptime_var) { - // This is at least the second time we've seen this variable declaration during analysis. - // This means that this is actually a different variable due to, e.g. an inline while loop. - // We make a new variable so that it can hold a different type, and so the debug info can - // be distinct. - ZigVar *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope, - buf_create_from_str(var->name), var->src_is_const, var->gen_is_const, - var->shadowable, var->is_comptime, true); - new_var->owner_exec = var->owner_exec; - new_var->align_bytes = var->align_bytes; - if (var->mem_slot_index != SIZE_MAX) { - ZigValue *vals = create_const_vals(1); - new_var->mem_slot_index = ira->exec_context.mem_slot_list.length; - ira->exec_context.mem_slot_list.append(vals); - } - - var->next_var = new_var; - var = new_var; + while (var->next_var != nullptr) { + var = var->next_var; } // This must be done after possibly creating a new variable above var->ref_count = 0; + var->ptr_instruction = var_ptr; var->var_type = result_type; assert(var->var_type); if (type_is_invalid(result_type)) { - return ir_const_void(ira, &decl_var_instruction->base); + return ir_const_void(ira, &decl_var_instruction->base.base); } if (decl_var_instruction->align_value == nullptr) { if ((err = type_resolve(ira->codegen, result_type, ResolveStatusAlignmentKnown))) { var->var_type = ira->codegen->builtin_types.entry_invalid; - return ir_const_void(ira, &decl_var_instruction->base); + return ir_const_void(ira, &decl_var_instruction->base.base); } - var->align_bytes = get_abi_alignment(ira->codegen, result_type); + var->align_bytes = get_ptr_align(ira->codegen, var_ptr->value->type); } else { if (!ir_resolve_align(ira, decl_var_instruction->align_value->child, nullptr, &var->align_bytes)) { var->var_type = ira->codegen->builtin_types.entry_invalid; @@ -16712,104 +17797,96 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, // we need a runtime ptr but we have a comptime val. // since it's a comptime val there are no instructions for it. // we memcpy the init value here - IrInstruction *deref = ir_get_deref(ira, var_ptr, var_ptr, nullptr); + IrInstGen *deref = ir_get_deref(ira, &var_ptr->base, var_ptr, nullptr); if (type_is_invalid(deref->value->type)) { var->var_type = ira->codegen->builtin_types.entry_invalid; - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } // If this assertion trips, something is wrong with the IR instructions, because // we expected the above deref to return a constant value, but it created a runtime // instruction. assert(deref->value->special != ConstValSpecialRuntime); var_ptr->value->special = ConstValSpecialRuntime; - ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref, false); + ir_analyze_store_ptr(ira, &var_ptr->base, var_ptr, deref, false); } - - if (instr_is_comptime(var_ptr) && var->mem_slot_index != SIZE_MAX) { - assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); - ZigValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); - copy_const_val(mem_slot, init_val); - ira_ref(var->owner_exec->analysis); - - if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { - return ir_const_void(ira, &decl_var_instruction->base); - } + if (instr_is_comptime(var_ptr) && (is_comptime_var || (var_class_requires_const && var->gen_is_const))) { + return ir_const_void(ira, &decl_var_instruction->base.base); } } else if (is_comptime_var) { - ir_add_error(ira, &decl_var_instruction->base, + ir_add_error(ira, &decl_var_instruction->base.base, buf_sprintf("cannot store runtime value in compile time variable")); var->var_type = ira->codegen->builtin_types.entry_invalid; - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); + ZigFn *fn_entry = ira->new_irb.exec->fn_entry; if (fn_entry) fn_entry->variable_list.append(var); - return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, var_ptr); + return ir_build_var_decl_gen(ira, &decl_var_instruction->base.base, var, var_ptr); } -static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { - IrInstruction *target = instruction->target->child; +static IrInstGen *ir_analyze_instruction_export(IrAnalyze *ira, IrInstSrcExport *instruction) { + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *options = instruction->options->child; + IrInstGen *options = instruction->options->child; if (type_is_invalid(options->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *options_type = options->value->type; assert(options_type->id == ZigTypeIdStruct); TypeStructField *name_field = find_struct_type_field(options_type, buf_create_from_str("name")); - ir_assert(name_field != nullptr, &instruction->base); - IrInstruction *name_inst = ir_analyze_struct_value_field_value(ira, &instruction->base, options, name_field); + ir_assert(name_field != nullptr, &instruction->base.base); + IrInstGen *name_inst = ir_analyze_struct_value_field_value(ira, &instruction->base.base, options, name_field); if (type_is_invalid(name_inst->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; TypeStructField *linkage_field = find_struct_type_field(options_type, buf_create_from_str("linkage")); - ir_assert(linkage_field != nullptr, &instruction->base); - IrInstruction *linkage_inst = ir_analyze_struct_value_field_value(ira, &instruction->base, options, linkage_field); + ir_assert(linkage_field != nullptr, &instruction->base.base); + IrInstGen *linkage_inst = ir_analyze_struct_value_field_value(ira, &instruction->base.base, options, linkage_field); if (type_is_invalid(linkage_inst->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; TypeStructField *section_field = find_struct_type_field(options_type, buf_create_from_str("section")); - ir_assert(section_field != nullptr, &instruction->base); - IrInstruction *section_inst = ir_analyze_struct_value_field_value(ira, &instruction->base, options, section_field); + ir_assert(section_field != nullptr, &instruction->base.base); + IrInstGen *section_inst = ir_analyze_struct_value_field_value(ira, &instruction->base.base, options, section_field); if (type_is_invalid(section_inst->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // The `section` field is optional, we have to unwrap it first - IrInstruction *non_null_check = ir_analyze_test_non_null(ira, &instruction->base, section_inst); + IrInstGen *non_null_check = ir_analyze_test_non_null(ira, &instruction->base.base, section_inst); bool is_non_null; if (!ir_resolve_bool(ira, non_null_check, &is_non_null)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *section_str_inst = nullptr; + IrInstGen *section_str_inst = nullptr; if (is_non_null) { - section_str_inst = ir_analyze_optional_value_payload_value(ira, &instruction->base, section_inst, false); + section_str_inst = ir_analyze_optional_value_payload_value(ira, &instruction->base.base, section_inst, false); if (type_is_invalid(section_str_inst->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } // Resolve all the comptime values Buf *symbol_name = ir_resolve_str(ira, name_inst); if (!symbol_name) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (buf_len(symbol_name) < 1) { - ir_add_error(ira, name_inst, + ir_add_error(ira, &name_inst->base, buf_sprintf("exported symbol name cannot be empty")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } GlobalLinkageId global_linkage_id; if (!ir_resolve_global_linkage(ira, linkage_inst, &global_linkage_id)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; Buf *section_name = nullptr; if (section_str_inst != nullptr && !(section_name = ir_resolve_str(ira, section_str_inst))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // TODO: This function needs to be audited. // It's not clear how all the different types are supposed to be handled. @@ -16817,15 +17894,15 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio // in another file. TldFn *tld_fn = allocate<TldFn>(1); tld_fn->base.id = TldIdFn; - tld_fn->base.source_node = instruction->base.source_node; + tld_fn->base.source_node = instruction->base.base.source_node; auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, &tld_fn->base); if (entry) { AstNode *other_export_node = entry->value->source_node; - ErrorMsg *msg = ir_add_error(ira, &instruction->base, + ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name))); add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } Error err; @@ -16841,12 +17918,12 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc; switch (cc) { case CallingConventionUnspecified: { - ErrorMsg *msg = ir_add_error(ira, target, + ErrorMsg *msg = ir_add_error(ira, &target->base, buf_sprintf("exported function must specify calling convention")); add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); } break; case CallingConventionAsync: { - ErrorMsg *msg = ir_add_error(ira, target, + ErrorMsg *msg = ir_add_error(ira, &target->base, buf_sprintf("exported function cannot be async")); add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); } break; @@ -16869,10 +17946,10 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio } break; case ZigTypeIdStruct: if (is_slice(target->value->type)) { - ir_add_error(ira, target, + ir_add_error(ira, &target->base, buf_sprintf("unable to export value of type '%s'", buf_ptr(&target->value->type->name))); } else if (target->value->type->data.structure.layout != ContainerLayoutExtern) { - ErrorMsg *msg = ir_add_error(ira, target, + ErrorMsg *msg = ir_add_error(ira, &target->base, buf_sprintf("exported struct value must be declared extern")); add_error_note(ira->codegen, msg, target->value->type->data.structure.decl_node, buf_sprintf("declared here")); } else { @@ -16881,7 +17958,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio break; case ZigTypeIdUnion: if (target->value->type->data.unionation.layout != ContainerLayoutExtern) { - ErrorMsg *msg = ir_add_error(ira, target, + ErrorMsg *msg = ir_add_error(ira, &target->base, buf_sprintf("exported union value must be declared extern")); add_error_note(ira->codegen, msg, target->value->type->data.unionation.decl_node, buf_sprintf("declared here")); } else { @@ -16890,7 +17967,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio break; case ZigTypeIdEnum: if (target->value->type->data.enumeration.layout != ContainerLayoutExtern) { - ErrorMsg *msg = ir_add_error(ira, target, + ErrorMsg *msg = ir_add_error(ira, &target->base, buf_sprintf("exported enum value must be declared extern")); add_error_note(ira->codegen, msg, target->value->type->data.enumeration.decl_node, buf_sprintf("declared here")); } else { @@ -16900,10 +17977,10 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio case ZigTypeIdArray: { bool ok_type; if ((err = type_allowed_in_extern(ira->codegen, target->value->type->data.array.child_type, &ok_type))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!ok_type) { - ir_add_error(ira, target, + ir_add_error(ira, &target->base, buf_sprintf("array element type '%s' not extern-compatible", buf_ptr(&target->value->type->data.array.child_type->name))); } else { @@ -16918,31 +17995,31 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio zig_unreachable(); case ZigTypeIdStruct: if (is_slice(type_value)) { - ir_add_error(ira, target, + ir_add_error(ira, &target->base, buf_sprintf("unable to export type '%s'", buf_ptr(&type_value->name))); } else if (type_value->data.structure.layout != ContainerLayoutExtern) { - ErrorMsg *msg = ir_add_error(ira, target, + ErrorMsg *msg = ir_add_error(ira, &target->base, buf_sprintf("exported struct must be declared extern")); add_error_note(ira->codegen, msg, type_value->data.structure.decl_node, buf_sprintf("declared here")); } break; case ZigTypeIdUnion: if (type_value->data.unionation.layout != ContainerLayoutExtern) { - ErrorMsg *msg = ir_add_error(ira, target, + ErrorMsg *msg = ir_add_error(ira, &target->base, buf_sprintf("exported union must be declared extern")); add_error_note(ira->codegen, msg, type_value->data.unionation.decl_node, buf_sprintf("declared here")); } break; case ZigTypeIdEnum: if (type_value->data.enumeration.layout != ContainerLayoutExtern) { - ErrorMsg *msg = ir_add_error(ira, target, + ErrorMsg *msg = ir_add_error(ira, &target->base, buf_sprintf("exported enum must be declared extern")); add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here")); } break; case ZigTypeIdFn: { if (type_value->data.fn.fn_type_id.cc == CallingConventionUnspecified) { - ir_add_error(ira, target, + ir_add_error(ira, &target->base, buf_sprintf("exported function type must specify calling convention")); } } break; @@ -16968,7 +18045,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio case ZigTypeIdOpaque: case ZigTypeIdFnFrame: case ZigTypeIdAnyFrame: - ir_add_error(ira, target, + ir_add_error(ira, &target->base, buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name))); break; } @@ -16993,61 +18070,55 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio case ZigTypeIdEnumLiteral: case ZigTypeIdFnFrame: case ZigTypeIdAnyFrame: - ir_add_error(ira, target, + ir_add_error(ira, &target->base, buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value->type->name))); break; } // TODO audit the various ways to use @export - if (want_var_export && target->id == IrInstructionIdLoadPtrGen) { - IrInstructionLoadPtrGen *load_ptr = reinterpret_cast<IrInstructionLoadPtrGen *>(target); - if (load_ptr->ptr->id == IrInstructionIdVarPtr) { - IrInstructionVarPtr *var_ptr = reinterpret_cast<IrInstructionVarPtr *>(load_ptr->ptr); + if (want_var_export && target->id == IrInstGenIdLoadPtr) { + IrInstGenLoadPtr *load_ptr = reinterpret_cast<IrInstGenLoadPtr *>(target); + if (load_ptr->ptr->id == IrInstGenIdVarPtr) { + IrInstGenVarPtr *var_ptr = reinterpret_cast<IrInstGenVarPtr *>(load_ptr->ptr); ZigVar *var = var_ptr->var; add_var_export(ira->codegen, var, buf_ptr(symbol_name), global_linkage_id); var->section_name = section_name; } } - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static bool exec_has_err_ret_trace(CodeGen *g, IrExecutable *exec) { +static bool exec_has_err_ret_trace(CodeGen *g, IrExecutableSrc *exec) { ZigFn *fn_entry = exec_fn_entry(exec); return fn_entry != nullptr && fn_entry->calls_or_awaits_errorable_fn && g->have_err_ret_tracing; } -static IrInstruction *ir_analyze_instruction_error_return_trace(IrAnalyze *ira, - IrInstructionErrorReturnTrace *instruction) +static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira, + IrInstSrcErrorReturnTrace *instruction) { ZigType *ptr_to_stack_trace_type = get_pointer_to_type(ira->codegen, get_stack_trace_type(ira->codegen), false); - if (instruction->optional == IrInstructionErrorReturnTrace::Null) { + if (instruction->optional == IrInstErrorReturnTraceNull) { ZigType *optional_type = get_optional_type(ira->codegen, ptr_to_stack_trace_type); - if (!exec_has_err_ret_trace(ira->codegen, ira->new_irb.exec)) { - IrInstruction *result = ir_const(ira, &instruction->base, optional_type); + if (!exec_has_err_ret_trace(ira->codegen, ira->old_irb.exec)) { + IrInstGen *result = ir_const(ira, &instruction->base.base, optional_type); ZigValue *out_val = result->value; assert(get_codegen_ptr_type(optional_type) != nullptr); out_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; out_val->data.x_ptr.data.hard_coded_addr.addr = 0; return result; } - IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, instruction->optional); - new_instruction->value->type = optional_type; - return new_instruction; + return ir_build_error_return_trace_gen(ira, instruction->base.base.scope, + instruction->base.base.source_node, instruction->optional, optional_type); } else { assert(ira->codegen->have_err_ret_tracing); - IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, instruction->optional); - new_instruction->value->type = ptr_to_stack_trace_type; - return new_instruction; + return ir_build_error_return_trace_gen(ira, instruction->base.base.scope, + instruction->base.base.source_node, instruction->optional, ptr_to_stack_trace_type); } } -static IrInstruction *ir_analyze_instruction_error_union(IrAnalyze *ira, - IrInstructionErrorUnion *instruction) -{ - IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); +static IrInstGen *ir_analyze_instruction_error_union(IrAnalyze *ira, IrInstSrcErrorUnion *instruction) { + IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); result->value->special = ConstValSpecialLazy; LazyValueErrUnionType *lazy_err_union_type = allocate<LazyValueErrUnionType>(1, "LazyValueErrUnionType"); @@ -17057,24 +18128,25 @@ static IrInstruction *ir_analyze_instruction_error_union(IrAnalyze *ira, lazy_err_union_type->err_set_type = instruction->err_set->child; if (ir_resolve_type_lazy(ira, lazy_err_union_type->err_set_type) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; lazy_err_union_type->payload_type = instruction->payload->child; if (ir_resolve_type_lazy(ira, lazy_err_union_type->payload_type) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return result; } -static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_inst, ZigType *var_type, +static IrInstGen *ir_analyze_alloca(IrAnalyze *ira, IrInst *source_inst, ZigType *var_type, uint32_t align, const char *name_hint, bool force_comptime) { Error err; ZigValue *pointee = create_const_vals(1); pointee->special = ConstValSpecialUndef; + pointee->llvm_align = align; - IrInstructionAllocaGen *result = ir_build_alloca_gen(ira, source_inst, align, name_hint); + IrInstGenAlloca *result = ir_build_alloca_gen(ira, source_inst, align, name_hint); result->base.value->special = ConstValSpecialStatic; result->base.value->data.x_ptr.special = ConstPtrSpecialRef; result->base.value->data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer; @@ -17082,15 +18154,15 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in bool var_type_has_bits; if ((err = type_has_bits2(ira->codegen, var_type, &var_type_has_bits))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (align != 0) { if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!var_type_has_bits) { ir_add_error(ira, source_inst, buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned", name_hint, buf_ptr(&var_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } assert(result->base.value->data.x_ptr.special != ConstPtrSpecialInvalid); @@ -17099,15 +18171,16 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in 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); + if (!force_comptime) { + ZigFn *fn_entry = ira->new_irb.exec->fn_entry; + if (fn_entry != nullptr) { + fn_entry->alloca_gen_list.append(result); + } } - result->base.is_gen = true; return &result->base; } -static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspend_source_instr, +static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInst *suspend_source_instr, ResultLoc *result_loc) { switch (result_loc->id) { @@ -17150,7 +18223,7 @@ static bool type_can_bit_cast(ZigType *t) { } } -static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) { +static void set_up_result_loc_for_inferred_comptime(IrInstGen *ptr) { ZigValue *undef_child = create_const_vals(1); undef_child->type = ptr->value->type->data.pointer.child_type; undef_child->special = ConstValSpecialUndef; @@ -17189,16 +18262,16 @@ static Error ir_result_has_type(IrAnalyze *ira, ResultLoc *result_loc, bool *out zig_unreachable(); } -static IrInstruction *ir_resolve_no_result_loc(IrAnalyze *ira, IrInstruction *suspend_source_instr, - ResultLoc *result_loc, ZigType *value_type, bool force_runtime, bool non_null_comptime) +static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_source_instr, + ResultLoc *result_loc, ZigType *value_type) { if (type_is_invalid(value_type)) - return ira->codegen->invalid_instruction; - IrInstructionAllocaGen *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, ""); + return ira->codegen->invalid_inst_gen; + IrInstGenAlloca *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, ""); alloca_gen->base.value->type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, PtrLenSingle, 0, 0, 0, false); set_up_result_loc_for_inferred_comptime(&alloca_gen->base); - ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); + ZigFn *fn_entry = ira->new_irb.exec->fn_entry; if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) { fn_entry->alloca_gen_list.append(alloca_gen); } @@ -17207,10 +18280,25 @@ static IrInstruction *ir_resolve_no_result_loc(IrAnalyze *ira, IrInstruction *su return result_loc->resolved_loc; } +static bool result_loc_is_discard(ResultLoc *result_loc_pass1) { + if (result_loc_pass1->id == ResultLocIdInstruction && + result_loc_pass1->source_instruction->id == IrInstSrcIdConst) + { + IrInstSrcConst *const_inst = reinterpret_cast<IrInstSrcConst *>(result_loc_pass1->source_instruction); + if (value_is_comptime(const_inst->value) && + const_inst->value->type->id == ZigTypeIdPointer && + const_inst->value->data.x_ptr.special == ConstPtrSpecialDiscard) + { + return true; + } + } + return false; +} + // when calling this function, at the callsite must check for result type noreturn and propagate it up -static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, - ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, - bool non_null_comptime, bool allow_discard) +static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_instr, + ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime, + bool allow_discard) { Error err; if (result_loc->resolved_loc != nullptr) { @@ -17230,54 +18318,56 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe return nullptr; } // need to return a result location and don't have one. use a stack allocation - return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, - force_runtime, non_null_comptime); + return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type); } case ResultLocIdVar: { ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc); - assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc); - + assert(result_loc->source_instruction->id == IrInstSrcIdAlloca); + IrInstSrcAlloca *alloca_src = reinterpret_cast<IrInstSrcAlloca *>(result_loc->source_instruction); + + ZigVar *var = result_loc_var->var; + if (var->var_type != nullptr && !ir_get_var_is_comptime(var)) { + // This is at least the second time we've seen this variable declaration during analysis. + // This means that this is actually a different variable due to, e.g. an inline while loop. + // We make a new variable so that it can hold a different type, and so the debug info can + // be distinct. + ZigVar *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope, + buf_create_from_str(var->name), var->src_is_const, var->gen_is_const, + var->shadowable, var->is_comptime, true); + new_var->owner_exec = var->owner_exec; + new_var->align_bytes = var->align_bytes; + + var->next_var = new_var; + var = new_var; + } if (value_type->id == ZigTypeIdUnreachable || value_type->id == ZigTypeIdOpaque) { - ir_add_error(ira, result_loc->source_instruction, + ir_add_error(ira, &result_loc->source_instruction->base, buf_sprintf("variable of type '%s' not allowed", buf_ptr(&value_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - - IrInstructionAllocaSrc *alloca_src = - reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); - bool force_comptime; - if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) - return ira->codegen->invalid_instruction; - bool is_comptime = force_comptime || (!force_runtime && value != nullptr && - value->value->special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); - - if (alloca_src->base.child == nullptr || is_comptime) { + if (alloca_src->base.child == nullptr || var->ptr_instruction == nullptr) { + bool force_comptime; + if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) + return ira->codegen->invalid_inst_gen; uint32_t align = 0; if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, nullptr, &align)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *alloca_gen; - if (is_comptime && value != nullptr) { - if (align > value->value->llvm_align) { - value->value->llvm_align = align; - } - alloca_gen = ir_get_ref(ira, result_loc->source_instruction, value, true, false); - } else { - alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align, - alloca_src->name_hint, force_comptime); - if (force_runtime) { - alloca_gen->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; - alloca_gen->value->special = ConstValSpecialRuntime; - } + IrInstGen *alloca_gen = ir_analyze_alloca(ira, &result_loc->source_instruction->base, value_type, + align, alloca_src->name_hint, force_comptime); + if (force_runtime) { + alloca_gen->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; + alloca_gen->value->special = ConstValSpecialRuntime; } if (alloca_src->base.child != nullptr && !result_loc->written) { - alloca_src->base.child->ref_count = 0; + alloca_src->base.child->base.ref_count = 0; } alloca_src->base.child = alloca_gen; + var->ptr_instruction = alloca_gen; } result_loc->written = true; - result_loc->resolved_loc = is_comptime ? nullptr : alloca_src->base.child; - return result_loc->resolved_loc; + result_loc->resolved_loc = alloca_src->base.child; + return alloca_src->base.child; } case ResultLocIdInstruction: { result_loc->written = true; @@ -17289,27 +18379,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = true; ira->src_implicit_return_type_list.append(value); } - if (!non_null_comptime) { - bool is_comptime = value != nullptr && value->value->special != ConstValSpecialRuntime; - if (is_comptime) - return nullptr; - } - bool has_bits; - if ((err = type_has_bits2(ira->codegen, ira->explicit_return_type, &has_bits))) - return ira->codegen->invalid_instruction; - if (!has_bits || !handle_is_ptr(ira->explicit_return_type)) { - ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); - if (fn_entry == nullptr || fn_entry->inferred_async_node == nullptr) { - return nullptr; - } - } - - ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false); result_loc->written = true; - result_loc->resolved_loc = ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type); - if (ir_should_inline(ira->old_irb.exec, result_loc->source_instruction->scope)) { - set_up_result_loc_for_inferred_comptime(result_loc->resolved_loc); - } + result_loc->resolved_loc = ira->return_ptr; return result_loc->resolved_loc; } case ResultLocIdPeer: { @@ -17317,8 +18388,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe ResultLocPeerParent *peer_parent = result_peer->parent; if (peer_parent->peers.length == 1) { - IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, - value_type, value, force_runtime, non_null_comptime, true); + IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, + value_type, value, force_runtime, true); result_peer->suspend_pos.basic_block_index = SIZE_MAX; result_peer->suspend_pos.instruction_index = SIZE_MAX; if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || @@ -17333,22 +18404,19 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe bool is_condition_comptime; if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_condition_comptime)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (is_condition_comptime) { peer_parent->skipped = true; - if (non_null_comptime) { - return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, - value_type, value, force_runtime, non_null_comptime, true); - } - return nullptr; + return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, + value_type, value, force_runtime, true); } bool peer_parent_has_type; if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (peer_parent_has_type) { peer_parent->skipped = true; - IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, - value_type, value, force_runtime || !is_condition_comptime, true, true); + IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, + value_type, value, force_runtime || !is_condition_comptime, true); if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || parent_result_loc->value->type->id == ZigTypeIdUnreachable) { @@ -17364,7 +18432,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe if (peer_parent->end_bb->suspend_instruction_ref == nullptr) { peer_parent->end_bb->suspend_instruction_ref = suspend_source_instr; } - IrInstruction *unreach_inst = ira_suspend(ira, suspend_source_instr, result_peer->next_bb, + IrInstGen *unreach_inst = ira_suspend(ira, suspend_source_instr, result_peer->next_bb, &result_peer->suspend_pos); if (result_peer->next_bb == nullptr) { ir_start_next_bb(ira); @@ -17372,8 +18440,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe return unreach_inst; } - IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, - peer_parent->resolved_type, nullptr, force_runtime, non_null_comptime, true); + IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, + peer_parent->resolved_type, nullptr, force_runtime, true); if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || parent_result_loc->value->type->id == ZigTypeIdUnreachable) { @@ -17386,30 +18454,27 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe return result_loc->resolved_loc; } case ResultLocIdCast: { - if (value != nullptr && value->value->special != ConstValSpecialRuntime && !non_null_comptime) - return nullptr; ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (dest_type == ira->codegen->builtin_types.entry_var) { - return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, - force_runtime, non_null_comptime); + return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type); } - IrInstruction *casted_value; + IrInstGen *casted_value; if (value != nullptr) { - casted_value = ir_implicit_cast(ira, value, dest_type); + casted_value = ir_implicit_cast2(ira, suspend_source_instr, value, dest_type); if (type_is_invalid(casted_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; dest_type = casted_value->value->type; } else { casted_value = nullptr; } - IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent, - dest_type, casted_value, force_runtime, non_null_comptime, true); + IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent, + dest_type, casted_value, force_runtime, true); if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || parent_result_loc->value->type->id == ZigTypeIdUnreachable) { @@ -17422,11 +18487,11 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (!type_has_bits(value_type)) { parent_ptr_align = 0; @@ -17449,9 +18514,9 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe ConstCastOnly const_cast_result = types_match_const_cast_only(ira, parent_result_loc->value->type, ptr_type, - result_cast->base.source_instruction->source_node, false); + result_cast->base.source_instruction->base.source_node, false); if (const_cast_result.id == ConstCastResultIdInvalid) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (const_cast_result.id != ConstCastResultIdOk) { if (allow_discard) { return parent_result_loc; @@ -17459,59 +18524,59 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe // We will not be able to provide a result location for this value. Create // a new result location. result_cast->parent->written = false; - return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, - force_runtime, non_null_comptime); + return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type); } result_loc->written = true; result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, - ptr_type, result_cast->base.source_instruction, false); + &parent_result_loc->base, ptr_type, &result_cast->base.source_instruction->base, false); return result_loc->resolved_loc; } case ResultLocIdBitCast: { ResultLocBitCast *result_bit_cast = reinterpret_cast<ResultLocBitCast *>(result_loc); ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child); if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (get_codegen_ptr_type(dest_type) != nullptr) { - ir_add_error(ira, result_loc->source_instruction, + ir_add_error(ira, &result_loc->source_instruction->base, buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (!type_can_bit_cast(dest_type)) { - ir_add_error(ira, result_loc->source_instruction, + ir_add_error(ira, &result_loc->source_instruction->base, buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (get_codegen_ptr_type(value_type) != nullptr) { ir_add_error(ira, suspend_source_instr, buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&value_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (!type_can_bit_cast(value_type)) { ir_add_error(ira, suspend_source_instr, buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&value_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *bitcasted_value; + IrInstGen *bitcasted_value; if (value != nullptr) { - bitcasted_value = ir_analyze_bit_cast(ira, result_loc->source_instruction, value, dest_type); + bitcasted_value = ir_analyze_bit_cast(ira, &result_loc->source_instruction->base, value, dest_type); dest_type = bitcasted_value->value->type; } else { bitcasted_value = nullptr; } - if (bitcasted_value == nullptr || type_is_invalid(bitcasted_value->value->type)) { + if (bitcasted_value != nullptr && type_is_invalid(bitcasted_value->value->type)) { return bitcasted_value; } - IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent, - dest_type, bitcasted_value, force_runtime, non_null_comptime, true); + bool parent_was_written = result_bit_cast->parent->written; + IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent, + dest_type, bitcasted_value, force_runtime, true); if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || parent_result_loc->value->type->id == ZigTypeIdUnreachable) { @@ -17521,55 +18586,59 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe assert(parent_ptr_type->id == ZigTypeIdPointer); ZigType *child_type = parent_ptr_type->data.pointer.child_type; - bool has_bits; - if ((err = type_has_bits2(ira->codegen, child_type, &has_bits))) { - return ira->codegen->invalid_instruction; - } - - // This happens when the bitCast result is assigned to _ - if (!has_bits) { + if (result_loc_is_discard(result_bit_cast->parent)) { assert(allow_discard); return parent_result_loc; } - if ((err = type_resolve(ira->codegen, child_type, ResolveStatusAlignmentKnown))) { - return ira->codegen->invalid_instruction; + if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) { + return ira->codegen->invalid_inst_gen; } - uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); - if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { - return ira->codegen->invalid_instruction; + if ((err = type_resolve(ira->codegen, value_type, ResolveStatusSizeKnown))) { + return ira->codegen->invalid_inst_gen; } + + if (child_type != ira->codegen->builtin_types.entry_var) { + if (type_size(ira->codegen, child_type) != type_size(ira->codegen, value_type)) { + // pointer cast won't work; we need a temporary location. + result_bit_cast->parent->written = parent_was_written; + result_loc->written = true; + result_loc->resolved_loc = ir_resolve_result(ira, suspend_source_instr, no_result_loc(), + value_type, bitcasted_value, force_runtime, true); + return result_loc->resolved_loc; + } + } + uint64_t parent_ptr_align = 0; + if (type_has_bits(value_type)) parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); result_loc->written = true; result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, - ptr_type, result_bit_cast->base.source_instruction, false); + &parent_result_loc->base, ptr_type, &result_bit_cast->base.source_instruction->base, false); return result_loc->resolved_loc; } } zig_unreachable(); } -static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, - ResultLoc *result_loc_pass1, ZigType *value_type, IrInstruction *value, bool force_runtime, - bool non_null_comptime, bool allow_discard) +static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr, + ResultLoc *result_loc_pass1, ZigType *value_type, IrInstGen *value, bool force_runtime, + bool allow_discard) { - Error err; - if (!allow_discard && result_loc_pass1->id == ResultLocIdInstruction && - instr_is_comptime(result_loc_pass1->source_instruction) && - result_loc_pass1->source_instruction->value->type->id == ZigTypeIdPointer && - result_loc_pass1->source_instruction->value->data.x_ptr.special == ConstPtrSpecialDiscard) - { + if (!allow_discard && result_loc_is_discard(result_loc_pass1)) { result_loc_pass1 = no_result_loc(); } - bool was_already_resolved = result_loc_pass1->resolved_loc != nullptr; - IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, - value, force_runtime, non_null_comptime, allow_discard); - if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value->type))) + bool was_written = result_loc_pass1->written; + IrInstGen *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, + value, force_runtime, allow_discard); + if (result_loc == nullptr || result_loc->value->type->id == ZigTypeIdUnreachable || + type_is_invalid(result_loc->value->type)) + { return result_loc; + } if ((force_runtime || (value != nullptr && !instr_is_comptime(value))) && result_loc_pass1->written && result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) @@ -17578,56 +18647,63 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s } InferredStructField *isf = result_loc->value->type->data.pointer.inferred_struct_field; - if (!was_already_resolved && isf != nullptr) { - // Now it's time to add the field to the struct type. - uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count; - uint32_t new_field_count = old_field_count + 1; - isf->inferred_struct_type->data.structure.src_field_count = new_field_count; - isf->inferred_struct_type->data.structure.fields = realloc_type_struct_fields( - isf->inferred_struct_type->data.structure.fields, old_field_count, new_field_count); - - TypeStructField *field = isf->inferred_struct_type->data.structure.fields[old_field_count]; - field->name = isf->field_name; - field->type_entry = value_type; - field->type_val = create_const_type(ira->codegen, field->type_entry); - field->src_index = old_field_count; - field->decl_node = value ? value->source_node : suspend_source_instr->source_node; - if (value && instr_is_comptime(value)) { - ZigValue *val = ir_resolve_const(ira, value, UndefOk); - if (!val) - return ira->codegen->invalid_instruction; - field->is_comptime = true; - field->init_val = create_const_vals(1); - copy_const_val(field->init_val, val); - return result_loc; - } - - ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false); - IrInstruction *casted_ptr; - if (instr_is_comptime(result_loc)) { - casted_ptr = ir_const(ira, suspend_source_instr, struct_ptr_type); - copy_const_val(casted_ptr->value, result_loc->value); - casted_ptr->value->type = struct_ptr_type; - } else { + if (isf != nullptr) { + TypeStructField *field; + IrInstGen *casted_ptr; + if (isf->already_resolved) { + field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); casted_ptr = result_loc; - } - if (instr_is_comptime(casted_ptr)) { - ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad); - if (!ptr_val) - return ira->codegen->invalid_instruction; - if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { - ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, - suspend_source_instr->source_node); - struct_val->special = ConstValSpecialStatic; - struct_val->data.x_struct.fields = realloc_const_vals_ptrs(struct_val->data.x_struct.fields, - old_field_count, new_field_count); + } else { + isf->already_resolved = true; + // Now it's time to add the field to the struct type. + uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count; + uint32_t new_field_count = old_field_count + 1; + isf->inferred_struct_type->data.structure.src_field_count = new_field_count; + isf->inferred_struct_type->data.structure.fields = realloc_type_struct_fields( + isf->inferred_struct_type->data.structure.fields, old_field_count, new_field_count); + + field = isf->inferred_struct_type->data.structure.fields[old_field_count]; + field->name = isf->field_name; + field->type_entry = value_type; + field->type_val = create_const_type(ira->codegen, field->type_entry); + field->src_index = old_field_count; + field->decl_node = value ? value->base.source_node : suspend_source_instr->source_node; + if (value && instr_is_comptime(value)) { + ZigValue *val = ir_resolve_const(ira, value, UndefOk); + if (!val) + return ira->codegen->invalid_inst_gen; + field->is_comptime = true; + field->init_val = create_const_vals(1); + copy_const_val(field->init_val, val); + return result_loc; + } - ZigValue *field_val = struct_val->data.x_struct.fields[old_field_count]; - field_val->special = ConstValSpecialUndef; - field_val->type = field->type_entry; - field_val->parent.id = ConstParentIdStruct; - field_val->parent.data.p_struct.struct_val = struct_val; - field_val->parent.data.p_struct.field_index = old_field_count; + ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false); + if (instr_is_comptime(result_loc)) { + casted_ptr = ir_const(ira, suspend_source_instr, struct_ptr_type); + copy_const_val(casted_ptr->value, result_loc->value); + casted_ptr->value->type = struct_ptr_type; + } else { + casted_ptr = result_loc; + } + if (instr_is_comptime(casted_ptr)) { + ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad); + if (!ptr_val) + return ira->codegen->invalid_inst_gen; + if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { + ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, + suspend_source_instr->source_node); + struct_val->special = ConstValSpecialStatic; + struct_val->data.x_struct.fields = realloc_const_vals_ptrs(struct_val->data.x_struct.fields, + old_field_count, new_field_count); + + ZigValue *field_val = struct_val->data.x_struct.fields[old_field_count]; + field_val->special = ConstValSpecialUndef; + field_val->type = field->type_entry; + field_val->parent.id = ConstParentIdStruct; + field_val->parent.data.p_struct.struct_val = struct_val; + field_val->parent.data.p_struct.field_index = old_field_count; + } } } @@ -17636,73 +18712,70 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s result_loc_pass1->resolved_loc = result_loc; } + if (was_written) { + return result_loc; + } ir_assert(result_loc->value->type->id == ZigTypeIdPointer, suspend_source_instr); ZigType *actual_elem_type = result_loc->value->type->data.pointer.child_type; if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && - value_type->id != ZigTypeIdNull) + value_type->id != ZigTypeIdNull && value_type->id != ZigTypeIdUndefined) { - bool has_bits; - if ((err = type_has_bits2(ira->codegen, value_type, &has_bits))) - return ira->codegen->invalid_instruction; - if (has_bits) { - result_loc_pass1->written = false; + bool same_comptime_repr = types_have_same_zig_comptime_repr(ira->codegen, actual_elem_type, value_type); + if (!same_comptime_repr) { + result_loc_pass1->written = was_written; return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); } - } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) { - bool has_bits; - if ((err = type_has_bits2(ira->codegen, value_type, &has_bits))) - return ira->codegen->invalid_instruction; - if (has_bits) { - if (value_type->id == ZigTypeIdErrorSet) { - return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); + } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion && + value_type->id != ZigTypeIdUndefined) + { + if (value_type->id == ZigTypeIdErrorSet) { + return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); + } else { + IrInstGen *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, + result_loc, false, true); + ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; + if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && + value_type->id != ZigTypeIdNull && value_type->id != ZigTypeIdUndefined) + { + return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); } else { - IrInstruction *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, - result_loc, false, true); - ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; - if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && - value_type->id != ZigTypeIdNull) { - return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); - } else { - return unwrapped_err_ptr; - } + return unwrapped_err_ptr; } } } return result_loc; } -static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, - IrInstructionResolveResult *instruction) -{ +static IrInstGen *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstSrcResolveResult *instruction) { ZigType *implicit_elem_type; if (instruction->ty == nullptr) { if (instruction->result_loc->id == ResultLocIdCast) { implicit_elem_type = ir_resolve_type(ira, instruction->result_loc->source_instruction->child); if (type_is_invalid(implicit_elem_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (instruction->result_loc->id == ResultLocIdReturn) { implicit_elem_type = ira->explicit_return_type; if (type_is_invalid(implicit_elem_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { implicit_elem_type = ira->codegen->builtin_types.entry_var; } if (implicit_elem_type == ira->codegen->builtin_types.entry_var) { Buf *bare_name = buf_alloc(); Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), - instruction->base.scope, instruction->base.source_node, bare_name); + instruction->base.base.scope, instruction->base.base.source_node, bare_name); StructSpecial struct_special = StructSpecialInferredStruct; - if (instruction->base.source_node->type == NodeTypeContainerInitExpr && - instruction->base.source_node->data.container_init_expr.kind == ContainerInitKindArray) + if (instruction->base.base.source_node->type == NodeTypeContainerInitExpr && + instruction->base.base.source_node->data.container_init_expr.kind == ContainerInitKindArray) { struct_special = StructSpecialInferredTuple; } ZigType *inferred_struct_type = get_partial_container_type(ira->codegen, - instruction->base.scope, ContainerKindStruct, instruction->base.source_node, + instruction->base.base.scope, ContainerKindStruct, instruction->base.base.source_node, buf_ptr(name), bare_name, ContainerLayoutAuto); inferred_struct_type->data.structure.special = struct_special; inferred_struct_type->data.structure.resolve_status = ResolveStatusBeingInferred; @@ -17711,21 +18784,21 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, } else { implicit_elem_type = ir_resolve_type(ira, instruction->ty->child); if (type_is_invalid(implicit_elem_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, - implicit_elem_type, nullptr, false, true, true); + IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, + implicit_elem_type, nullptr, false, true); if (result_loc != nullptr) return result_loc; - ZigFn *fn = exec_fn_entry(ira->new_irb.exec); + ZigFn *fn = ira->new_irb.exec->fn_entry; if (fn != nullptr && fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync && instruction->result_loc->id == ResultLocIdReturn) { - result_loc = ir_resolve_result(ira, &instruction->base, no_result_loc(), - implicit_elem_type, nullptr, false, true, true); + result_loc = ir_resolve_result(ira, &instruction->base.base, no_result_loc(), + implicit_elem_type, nullptr, false, true); if (result_loc != nullptr && - (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc))) + (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) { return result_loc; } @@ -17733,9 +18806,9 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, return result_loc; } - IrInstruction *result = ir_const(ira, &instruction->base, implicit_elem_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, implicit_elem_type); result->value->special = ConstValSpecialUndef; - IrInstruction *ptr = ir_get_ref(ira, &instruction->base, result, false, false); + IrInstGen *ptr = ir_get_ref(ira, &instruction->base.base, result, false, false); ptr->value->data.x_ptr.mut = ConstPtrMutComptimeVar; return ptr; } @@ -17759,8 +18832,7 @@ static void ir_reset_result(ResultLoc *result_loc) { break; } case ResultLocIdVar: { - IrInstructionAllocaSrc *alloca_src = - reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction); + IrInstSrcAlloca *alloca_src = reinterpret_cast<IrInstSrcAlloca *>(result_loc->source_instruction); alloca_src->base.child = nullptr; break; } @@ -17776,18 +18848,18 @@ static void ir_reset_result(ResultLoc *result_loc) { } } -static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInstructionResetResult *instruction) { +static IrInstGen *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInstSrcResetResult *instruction) { ir_reset_result(instruction->result_loc); - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *get_async_call_result_loc(IrAnalyze *ira, IrInstruction *source_instr, - ZigType *fn_ret_type, bool is_async_call_builtin, IrInstruction **args_ptr, size_t args_len, - IrInstruction *ret_ptr_uncasted) +static IrInstGen *get_async_call_result_loc(IrAnalyze *ira, IrInst* source_instr, + ZigType *fn_ret_type, bool is_async_call_builtin, IrInstGen **args_ptr, size_t args_len, + IrInstGen *ret_ptr_uncasted) { ir_assert(is_async_call_builtin, source_instr); if (type_is_invalid(ret_ptr_uncasted->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (ret_ptr_uncasted->value->type->id == ZigTypeIdVoid) { // Result location will be inside the async frame. return nullptr; @@ -17795,57 +18867,58 @@ static IrInstruction *get_async_call_result_loc(IrAnalyze *ira, IrInstruction *s return ir_implicit_cast(ira, ret_ptr_uncasted, get_pointer_to_type(ira->codegen, fn_ret_type, false)); } -static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstruction *source_instr, ZigFn *fn_entry, - ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, - IrInstruction *casted_new_stack, bool is_async_call_builtin, IrInstruction *ret_ptr_uncasted, +static IrInstGen *ir_analyze_async_call(IrAnalyze *ira, IrInst* source_instr, ZigFn *fn_entry, + ZigType *fn_type, IrInstGen *fn_ref, IrInstGen **casted_args, size_t arg_count, + IrInstGen *casted_new_stack, bool is_async_call_builtin, IrInstGen *ret_ptr_uncasted, ResultLoc *call_result_loc) { if (fn_entry == nullptr) { if (fn_type->data.fn.fn_type_id.cc != CallingConventionAsync) { - ir_add_error(ira, fn_ref, + ir_add_error(ira, &fn_ref->base, buf_sprintf("expected async function, found '%s'", buf_ptr(&fn_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (casted_new_stack == nullptr) { - ir_add_error(ira, fn_ref, buf_sprintf("function is not comptime-known; @asyncCall required")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &fn_ref->base, buf_sprintf("function is not comptime-known; @asyncCall required")); + return ira->codegen->invalid_inst_gen; } } if (casted_new_stack != nullptr) { ZigType *fn_ret_type = fn_type->data.fn.fn_type_id.return_type; - IrInstruction *ret_ptr = get_async_call_result_loc(ira, source_instr, fn_ret_type, is_async_call_builtin, + IrInstGen *ret_ptr = get_async_call_result_loc(ira, source_instr, fn_ret_type, is_async_call_builtin, casted_args, arg_count, ret_ptr_uncasted); if (ret_ptr != nullptr && type_is_invalid(ret_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *anyframe_type = get_any_frame_type(ira->codegen, fn_ret_type); - IrInstructionCallGen *call_gen = ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, + IrInstGenCall *call_gen = ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, arg_count, casted_args, CallModifierAsync, casted_new_stack, is_async_call_builtin, ret_ptr, anyframe_type); return &call_gen->base; } else { ZigType *frame_type = get_fn_frame_type(ira->codegen, fn_entry); - IrInstruction *result_loc = ir_resolve_result(ira, source_instr, call_result_loc, - frame_type, nullptr, true, true, false); - if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { + IrInstGen *result_loc = ir_resolve_result(ira, source_instr, call_result_loc, + frame_type, nullptr, true, false); + if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { return result_loc; } - result_loc = ir_implicit_cast(ira, result_loc, get_pointer_to_type(ira->codegen, frame_type, false)); + result_loc = ir_implicit_cast2(ira, &call_result_loc->source_instruction->base, result_loc, + get_pointer_to_type(ira->codegen, frame_type, false)); if (type_is_invalid(result_loc->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return &ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, arg_count, casted_args, CallModifierAsync, casted_new_stack, is_async_call_builtin, result_loc, frame_type)->base; } } static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, - IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) + IrInstGen *arg, Scope **exec_scope, size_t *next_proto_i) { AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); assert(param_decl_node->type == NodeTypeParamDecl); - IrInstruction *casted_arg; + IrInstGen *casted_arg; if (param_decl_node->data.param_decl.var_token == nullptr) { AstNode *param_type_node = param_decl_node->data.param_decl.type; ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node); @@ -17873,15 +18946,15 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node } static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node, - IrInstruction *arg, Scope **child_scope, size_t *next_proto_i, - GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstruction **casted_args, + IrInstGen *arg, IrInst *arg_src, Scope **child_scope, size_t *next_proto_i, + GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstGen **casted_args, ZigFn *impl_fn) { AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); assert(param_decl_node->type == NodeTypeParamDecl); bool is_var_args = param_decl_node->data.param_decl.is_var_args; bool arg_part_of_generic_id = false; - IrInstruction *casted_arg; + IrInstGen *casted_arg; if (is_var_args) { arg_part_of_generic_id = true; casted_arg = arg; @@ -17892,7 +18965,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod if (type_is_invalid(param_type)) return false; - casted_arg = ir_implicit_cast(ira, arg, param_type); + casted_arg = ir_implicit_cast2(ira, arg_src, arg, param_type); if (type_is_invalid(casted_arg->value->type)) return false; } else { @@ -17941,7 +19014,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod } else if (casted_arg->value->type->id == ZigTypeIdComptimeInt || casted_arg->value->type->id == ZigTypeIdComptimeFloat) { - ir_add_error(ira, casted_arg, + ir_add_error(ira, &casted_arg->base, buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/ziglang/zig/issues/557")); return false; } @@ -17958,47 +19031,33 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod return true; } -static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var) { +static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *var) { while (var->next_var != nullptr) { var = var->next_var; } - if (var->mem_slot_index != SIZE_MAX && var->owner_exec->analysis == nullptr) { - assert(ira->codegen->errors.length != 0); - return ira->codegen->invalid_instruction; - } if (var->var_type == nullptr || type_is_invalid(var->var_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - ZigValue *mem_slot = nullptr; - - bool comptime_var_mem = ir_get_var_is_comptime(var); - bool linkage_makes_it_runtime = var->decl_node->data.variable_declaration.is_extern; bool is_volatile = false; - - IrInstruction *result = ir_build_var_ptr(&ira->new_irb, - instruction->scope, instruction->source_node, var); - result->value->type = get_pointer_to_type_extra(ira->codegen, var->var_type, + ZigType *var_ptr_type = get_pointer_to_type_extra(ira->codegen, var->var_type, var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0, false); - if (linkage_makes_it_runtime || var->is_thread_local) - goto no_mem_slot; - - if (value_is_comptime(var->const_value)) { - mem_slot = var->const_value; - } else if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { - // find the relevant exec_context - assert(var->owner_exec != nullptr); - assert(var->owner_exec->analysis != nullptr); - IrExecContext *exec_context = &var->owner_exec->analysis->exec_context; - assert(var->mem_slot_index < exec_context->mem_slot_list.length); - mem_slot = exec_context->mem_slot_list.at(var->mem_slot_index); + if (var->ptr_instruction != nullptr) { + return ir_implicit_cast(ira, var->ptr_instruction, var_ptr_type); } - if (mem_slot != nullptr) { - switch (mem_slot->special) { + bool comptime_var_mem = ir_get_var_is_comptime(var); + bool linkage_makes_it_runtime = var->decl_node->data.variable_declaration.is_extern; + + IrInstGen *result = ir_build_var_ptr_gen(ira, source_instr, var); + result->value->type = var_ptr_type; + + if (!linkage_makes_it_runtime && !var->is_thread_local && value_is_comptime(var->const_value)) { + ZigValue *val = var->const_value; + switch (val->special) { case ConstValSpecialRuntime: - goto no_mem_slot; + break; case ConstValSpecialStatic: // fallthrough case ConstValSpecialLazy: // fallthrough case ConstValSpecialUndef: { @@ -18014,15 +19073,12 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, result->value->special = ConstValSpecialStatic; result->value->data.x_ptr.mut = ptr_mut; result->value->data.x_ptr.special = ConstPtrSpecialRef; - result->value->data.x_ptr.data.ref.pointee = mem_slot; + result->value->data.x_ptr.data.ref.pointee = val; return result; } } - zig_unreachable(); } -no_mem_slot: - bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr); result->value->data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack; @@ -18030,7 +19086,7 @@ no_mem_slot: } // This function is called when a comptime value becomes accessible at runtime. -static void mark_comptime_value_escape(IrAnalyze *ira, IrInstruction *source_instr, ZigValue *val) { +static void mark_comptime_value_escape(IrAnalyze *ira, IrInst* source_instr, ZigValue *val) { ir_assert(value_is_comptime(val), source_instr); if (val->special == ConstValSpecialUndef) return; @@ -18043,8 +19099,8 @@ static void mark_comptime_value_escape(IrAnalyze *ira, IrInstruction *source_ins } } -static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const) +static IrInstGen *ir_analyze_store_ptr(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *ptr, IrInstGen *uncasted_value, bool allow_write_through_const) { assert(ptr->value->type->id == ZigTypeIdPointer); @@ -18053,24 +19109,24 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source uncasted_value->value->type->id == ZigTypeIdErrorSet) { ir_add_error(ira, source_instr, buf_sprintf("error is discarded")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return ir_const_void(ira, source_instr); } if (ptr->value->type->data.pointer.is_const && !allow_write_through_const) { ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *child_type = ptr->value->type->data.pointer.child_type; - IrInstruction *value = ir_implicit_cast(ira, uncasted_value, child_type); - if (value == ira->codegen->invalid_instruction) - return ira->codegen->invalid_instruction; + IrInstGen *value = ir_implicit_cast(ira, uncasted_value, child_type); + if (type_is_invalid(value->value->type)) + return ira->codegen->invalid_inst_gen; switch (type_has_one_possible_value(ira->codegen, child_type)) { case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueYes: return ir_const_void(ira, source_instr); case OnePossibleValueNo: @@ -18080,7 +19136,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source if (instr_is_comptime(ptr) && ptr->value->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { if (!allow_write_through_const && ptr->value->data.x_ptr.mut == ConstPtrMutComptimeConst) { ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if ((allow_write_through_const && ptr->value->data.x_ptr.mut == ConstPtrMutComptimeConst) || ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar || @@ -18089,7 +19145,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source if (instr_is_comptime(value)) { ZigValue *dest_val = const_ptr_pointee(ira, ira->codegen, ptr->value, source_instr->source_node); if (dest_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (dest_val->special != ConstValSpecialRuntime) { copy_const_val(dest_val, value->value); @@ -18109,7 +19165,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source ZigValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, ptr->value); dest_val->type = ira->codegen->builtin_types.entry_invalid; - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } } @@ -18122,15 +19178,15 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source switch (type_requires_comptime(ira->codegen, child_type)) { case ReqCompTimeInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case ReqCompTimeYes: switch (type_has_one_possible_value(ira->codegen, ptr->value->type)) { case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueNo: ir_add_error(ira, source_instr, buf_sprintf("cannot store runtime value in type '%s'", buf_ptr(&child_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueYes: return ir_const_void(ira, source_instr); } @@ -18144,30 +19200,28 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source } // If this is a store to a pointer with a runtime-known vector index, - // we have to figure out the IrInstruction which represents the index and - // emit a IrInstructionVectorStoreElem, or emit a compile error + // we have to figure out the IrInstGen which represents the index and + // emit a IrInstGenVectorStoreElem, or emit a compile error // explaining why it is impossible for this store to work. Which is that // the pointer address is of the vector; without the element index being known // we cannot properly perform the insertion. if (ptr->value->type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) { - if (ptr->id == IrInstructionIdElemPtr) { - IrInstructionElemPtr *elem_ptr = (IrInstructionElemPtr *)ptr; + if (ptr->id == IrInstGenIdElemPtr) { + IrInstGenElemPtr *elem_ptr = (IrInstGenElemPtr *)ptr; return ir_build_vector_store_elem(ira, source_instr, elem_ptr->array_ptr, elem_ptr->elem_index, value); } - ir_add_error(ira, ptr, + ir_add_error(ira, &ptr->base, buf_sprintf("unable to determine vector element index of type '%s'", buf_ptr(&ptr->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstructionStorePtr *store_ptr = ir_build_store_ptr(&ira->new_irb, source_instr->scope, - source_instr->source_node, ptr, value); - return &store_ptr->base; + return ir_build_store_ptr_gen(ira, source_instr, ptr, value); } -static IrInstruction *analyze_casted_new_stack(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *new_stack, bool is_async_call_builtin, ZigFn *fn_entry) +static IrInstGen *analyze_casted_new_stack(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *new_stack, IrInst *new_stack_src, bool is_async_call_builtin, ZigFn *fn_entry) { if (new_stack == nullptr) return nullptr; @@ -18192,15 +19246,15 @@ static IrInstruction *analyze_casted_new_stack(IrAnalyze *ira, IrInstruction *so false, false, PtrLenUnknown, target_fn_align(ira->codegen->zig_target), 0, 0, false); ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); ira->codegen->need_frame_size_prefix_data = true; - return ir_implicit_cast(ira, new_stack, u8_slice); + return ir_implicit_cast2(ira, new_stack_src, new_stack, u8_slice); } } -static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_instr, - ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, - IrInstruction *first_arg_ptr, CallModifier modifier, - IrInstruction *new_stack, bool is_async_call_builtin, - IrInstruction **args_ptr, size_t args_len, IrInstruction *ret_ptr, ResultLoc *call_result_loc) +static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, + ZigFn *fn_entry, ZigType *fn_type, IrInstGen *fn_ref, + IrInstGen *first_arg_ptr, IrInst *first_arg_ptr_src, CallModifier modifier, + IrInstGen *new_stack, IrInst *new_stack_src, bool is_async_call_builtin, + IrInstGen **args_ptr, size_t args_len, IrInstGen *ret_ptr, ResultLoc *call_result_loc) { Error err; FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; @@ -18221,11 +19275,11 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i AstNode *fn_proto_node = fn_entry ? fn_entry->proto_node : nullptr;; if (fn_type_id->cc == CallingConventionNaked) { - ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("unable to call function with naked calling convention")); + ErrorMsg *msg = ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to call function with naked calling convention")); if (fn_proto_node) { add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); } - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (fn_type_id->is_var_args) { @@ -18236,7 +19290,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); } - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else if (src_param_count != call_param_count) { ErrorMsg *msg = ir_add_error_node(ira, source_node, @@ -18245,18 +19299,18 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); } - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (modifier == CallModifierCompileTime) { // No special handling is needed for compile time evaluation of generic functions. if (!fn_entry || fn_entry->body_node == nullptr) { - ir_add_error(ira, fn_ref, buf_sprintf("unable to evaluate constant expression")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression")); + return ira->codegen->invalid_inst_gen; } if (!ir_emit_backward_branch(ira, source_instr)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // Fork a scope of the function with known values for the parameters. Scope *exec_scope = &fn_entry->fndef_scope->base; @@ -18269,47 +19323,40 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i if (fn_type_id->next_param_index >= 1) { ZigType *param_type = fn_type_id->param_info[next_proto_i].type; if (type_is_invalid(param_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; first_arg_known_bare = param_type->id != ZigTypeIdPointer; } - IrInstruction *first_arg; + IrInstGen *first_arg; if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) { first_arg = first_arg_ptr; } else { - first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); + first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); if (type_is_invalid(first_arg->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, first_arg, &exec_scope, &next_proto_i)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - if (fn_proto_node->data.fn_proto.is_var_args) { - ir_add_error(ira, source_instr, - buf_sprintf("compiler bug: unable to call var args function at compile time. https://github.com/ziglang/zig/issues/313")); - return ira->codegen->invalid_instruction; - } - - for (size_t call_i = 0; call_i < args_len; call_i += 1) { - IrInstruction *old_arg = args_ptr[call_i]; + IrInstGen *old_arg = args_ptr[call_i]; if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_proto_i)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; ZigType *specified_return_type = ir_analyze_type_expr(ira, exec_scope, return_type_node); if (type_is_invalid(specified_return_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *return_type; ZigType *inferred_err_set_type = nullptr; if (fn_proto_node->data.fn_proto.auto_err_set) { inferred_err_set_type = get_auto_err_set_type(ira->codegen, fn_entry); if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); } else { return_type = specified_return_type; @@ -18326,10 +19373,17 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i if (result == nullptr) { // Analyze the fn body block like any other constant expression. AstNode *body_node = fn_entry->body_node; - result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, - ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, - nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node, - UndefOk); + ZigValue *result_ptr; + create_result_ptr(ira->codegen, return_type, &result, &result_ptr); + if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr, + ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, + fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node, + UndefOk))) + { + return ira->codegen->invalid_inst_gen; + } + destroy(result_ptr, "ZigValue"); + result_ptr = nullptr; if (inferred_err_set_type != nullptr) { inferred_err_set_type->data.error_set.incomplete = false; @@ -18354,24 +19408,24 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i } if (type_is_invalid(result->type)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } - IrInstruction *new_instruction = ir_const_move(ira, source_instr, result); + IrInstGen *new_instruction = ir_const_move(ira, source_instr, result); return ir_finish_anal(ira, new_instruction); } if (fn_type->data.fn.is_generic) { if (!fn_entry) { - ir_add_error(ira, fn_ref, + ir_add_error(ira, &fn_ref->base, buf_sprintf("calling a generic function requires compile-time known function value")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } size_t new_fn_arg_count = first_arg_1_or_0 + args_len; - IrInstruction **casted_args = allocate<IrInstruction *>(new_fn_arg_count); + IrInstGen **casted_args = allocate<IrInstGen *>(new_fn_arg_count); // Fork a scope of the function with known values for the parameters. Scope *parent_scope = fn_entry->fndef_scope->base.parent; @@ -18400,50 +19454,57 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i if (fn_type_id->next_param_index >= 1) { ZigType *param_type = fn_type_id->param_info[next_proto_i].type; if (type_is_invalid(param_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; first_arg_known_bare = param_type->id != ZigTypeIdPointer; } - IrInstruction *first_arg; + IrInstGen *first_arg; if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) { first_arg = first_arg_ptr; } else { - first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); + first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); if (type_is_invalid(first_arg->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, first_arg, &impl_fn->child_scope, - &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) + if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, first_arg, first_arg_ptr_src, + &impl_fn->child_scope, &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } - ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); + ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry; assert(parent_fn_entry); for (size_t call_i = 0; call_i < args_len; call_i += 1) { - IrInstruction *arg = args_ptr[call_i]; + IrInstGen *arg = args_ptr[call_i]; AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); assert(param_decl_node->type == NodeTypeParamDecl); - if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope, + if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &arg->base, &impl_fn->child_scope, &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } if (fn_proto_node->data.fn_proto.align_expr != nullptr) { - ZigValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, - fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), - ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, - nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, - nullptr, UndefBad); - IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, + ZigValue *align_result; + ZigValue *result_ptr; + create_result_ptr(ira->codegen, get_align_amt_type(ira->codegen), &align_result, &result_ptr); + if ((err = ir_eval_const_value(ira->codegen, impl_fn->child_scope, + fn_proto_node->data.fn_proto.align_expr, result_ptr, + ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, + nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, + nullptr, UndefBad))) + { + return ira->codegen->invalid_inst_gen; + } + IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb, impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); - copy_const_val(const_instruction->base.value, align_result); + const_instruction->base.value = align_result; + destroy(result_ptr, "ZigValue"); uint32_t align_bytes = 0; ir_resolve_align(ira, &const_instruction->base, nullptr, &align_bytes); @@ -18455,11 +19516,11 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node); if (type_is_invalid(specified_return_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (fn_proto_node->data.fn_proto.auto_err_set) { ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn); if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; inst_fn_type_id.return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); } else { inst_fn_type_id.return_type = specified_return_type; @@ -18469,10 +19530,10 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i case ReqCompTimeYes: // Throw out our work and call the function as if it were comptime. return ir_analyze_fn_call(ira, source_instr, fn_entry, fn_type, fn_ref, first_arg_ptr, - CallModifierCompileTime, new_stack, is_async_call_builtin, args_ptr, args_len, - ret_ptr, call_result_loc); + first_arg_ptr_src, CallModifierCompileTime, new_stack, new_stack_src, is_async_call_builtin, + args_ptr, args_len, ret_ptr, call_result_loc); case ReqCompTimeInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case ReqCompTimeNo: break; } @@ -18486,7 +19547,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i // finish instantiating the function impl_fn->type_entry = get_fn_type(ira->codegen, &inst_fn_type_id); if (type_is_invalid(impl_fn->type_entry)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; impl_fn->ir_executable->source_node = source_instr->source_node; impl_fn->ir_executable->parent_exec = ira->new_irb.exec; @@ -18504,25 +19565,25 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i parent_fn_entry->calls_or_awaits_errorable_fn = true; } - IrInstruction *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack, - is_async_call_builtin, impl_fn); + IrInstGen *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack, + new_stack_src, is_async_call_builtin, impl_fn); if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; size_t impl_param_count = impl_fn_type_id->param_count; if (modifier == CallModifierAsync) { - IrInstruction *result = ir_analyze_async_call(ira, source_instr, impl_fn, impl_fn->type_entry, + IrInstGen *result = ir_analyze_async_call(ira, source_instr, impl_fn, impl_fn->type_entry, nullptr, casted_args, impl_param_count, casted_new_stack, is_async_call_builtin, ret_ptr, call_result_loc); return ir_finish_anal(ira, result); } - IrInstruction *result_loc; + IrInstGen *result_loc; if (handle_is_ptr(impl_fn_type_id->return_type)) { result_loc = ir_resolve_result(ira, source_instr, call_result_loc, - impl_fn_type_id->return_type, nullptr, true, true, false); + impl_fn_type_id->return_type, nullptr, true, false); if (result_loc != nullptr) { - if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { + if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { return result_loc; } ZigType *res_child_type = result_loc->value->type->data.pointer.child_type; @@ -18538,7 +19599,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i result_loc = get_async_call_result_loc(ira, source_instr, impl_fn_type_id->return_type, is_async_call_builtin, args_ptr, args_len, ret_ptr); if (result_loc != nullptr && type_is_invalid(result_loc->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { result_loc = nullptr; } @@ -18547,11 +19608,11 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i parent_fn_entry->inferred_async_node == nullptr && modifier != CallModifierNoAsync) { - parent_fn_entry->inferred_async_node = fn_ref->source_node; + parent_fn_entry->inferred_async_node = fn_ref->base.source_node; parent_fn_entry->inferred_async_fn = impl_fn; } - IrInstructionCallGen *new_call_instruction = ir_build_call_gen(ira, source_instr, + IrInstGenCall *new_call_instruction = ir_build_call_gen(ira, source_instr, impl_fn, nullptr, impl_param_count, casted_args, modifier, casted_new_stack, is_async_call_builtin, result_loc, impl_fn_type_id->return_type); @@ -18562,7 +19623,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i return ir_finish_anal(ira, &new_call_instruction->base); } - ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); + ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry; assert(fn_type_id->return_type != nullptr); assert(parent_fn_entry != nullptr); if (fn_type_can_fail(fn_type_id)) { @@ -18570,46 +19631,46 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i } - IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count); + IrInstGen **casted_args = allocate<IrInstGen *>(call_param_count); size_t next_arg_index = 0; if (first_arg_ptr) { assert(first_arg_ptr->value->type->id == ZigTypeIdPointer); ZigType *param_type = fn_type_id->param_info[next_arg_index].type; if (type_is_invalid(param_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *first_arg; + IrInstGen *first_arg; if (param_type->id == ZigTypeIdPointer && handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) { first_arg = first_arg_ptr; } else { - first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr); + first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); if (type_is_invalid(first_arg->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *casted_arg = ir_implicit_cast(ira, first_arg, param_type); + IrInstGen *casted_arg = ir_implicit_cast2(ira, first_arg_ptr_src, first_arg, param_type); if (type_is_invalid(casted_arg->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; casted_args[next_arg_index] = casted_arg; next_arg_index += 1; } for (size_t call_i = 0; call_i < args_len; call_i += 1) { - IrInstruction *old_arg = args_ptr[call_i]; + IrInstGen *old_arg = args_ptr[call_i]; if (type_is_invalid(old_arg->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_arg; + IrInstGen *casted_arg; if (next_arg_index < src_param_count) { ZigType *param_type = fn_type_id->param_info[next_arg_index].type; if (type_is_invalid(param_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; casted_arg = ir_implicit_cast(ira, old_arg, param_type); if (type_is_invalid(casted_arg->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { casted_arg = old_arg; } @@ -18622,21 +19683,21 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i ZigType *return_type = fn_type_id->return_type; if (type_is_invalid(return_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && modifier == CallModifierNeverInline) { ir_add_error(ira, source_instr, buf_sprintf("no-inline call of inline function")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack, + IrInstGen *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack, new_stack_src, is_async_call_builtin, fn_entry); if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (modifier == CallModifierAsync) { - IrInstruction *result = ir_analyze_async_call(ira, source_instr, fn_entry, fn_type, fn_ref, + IrInstGen *result = ir_analyze_async_call(ira, source_instr, fn_entry, fn_type, fn_ref, casted_args, call_param_count, casted_new_stack, is_async_call_builtin, ret_ptr, call_result_loc); return ir_finish_anal(ira, result); } @@ -18645,16 +19706,16 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i parent_fn_entry->inferred_async_node == nullptr && modifier != CallModifierNoAsync) { - parent_fn_entry->inferred_async_node = fn_ref->source_node; + parent_fn_entry->inferred_async_node = fn_ref->base.source_node; parent_fn_entry->inferred_async_fn = fn_entry; } - IrInstruction *result_loc; + IrInstGen *result_loc; if (handle_is_ptr(return_type)) { result_loc = ir_resolve_result(ira, source_instr, call_result_loc, - return_type, nullptr, true, true, false); + return_type, nullptr, true, false); if (result_loc != nullptr) { - if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { + if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { return result_loc; } ZigType *res_child_type = result_loc->value->type->data.pointer.child_type; @@ -18670,12 +19731,12 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i result_loc = get_async_call_result_loc(ira, source_instr, return_type, is_async_call_builtin, args_ptr, args_len, ret_ptr); if (result_loc != nullptr && type_is_invalid(result_loc->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { result_loc = nullptr; } - IrInstructionCallGen *new_call_instruction = ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, + IrInstGenCall *new_call_instruction = ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, call_param_count, casted_args, modifier, casted_new_stack, is_async_call_builtin, result_loc, return_type); if (get_scope_typeof(source_instr->scope) == nullptr) { @@ -18684,62 +19745,65 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i return ir_finish_anal(ira, &new_call_instruction->base); } -static IrInstruction *ir_analyze_fn_call_src(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, - ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, - IrInstruction *first_arg_ptr, CallModifier modifier) +static IrInstGen *ir_analyze_fn_call_src(IrAnalyze *ira, IrInstSrcCall *call_instruction, + ZigFn *fn_entry, ZigType *fn_type, IrInstGen *fn_ref, + IrInstGen *first_arg_ptr, IrInst *first_arg_ptr_src, CallModifier modifier) { - IrInstruction *new_stack = nullptr; + IrInstGen *new_stack = nullptr; + IrInst *new_stack_src = nullptr; if (call_instruction->new_stack) { new_stack = call_instruction->new_stack->child; if (type_is_invalid(new_stack->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; + new_stack_src = &call_instruction->new_stack->base; } - IrInstruction **args_ptr = allocate<IrInstruction *>(call_instruction->arg_count, "IrInstruction *"); + IrInstGen **args_ptr = allocate<IrInstGen *>(call_instruction->arg_count, "IrInstGen *"); for (size_t i = 0; i < call_instruction->arg_count; i += 1) { args_ptr[i] = call_instruction->args[i]->child; if (type_is_invalid(args_ptr[i]->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *ret_ptr = nullptr; + IrInstGen *ret_ptr = nullptr; if (call_instruction->ret_ptr != nullptr) { ret_ptr = call_instruction->ret_ptr->child; if (type_is_invalid(ret_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *result = ir_analyze_fn_call(ira, &call_instruction->base, fn_entry, fn_type, fn_ref, - first_arg_ptr, modifier, new_stack, call_instruction->is_async_call_builtin, - args_ptr, call_instruction->arg_count, ret_ptr, call_instruction->result_loc); - deallocate(args_ptr, call_instruction->arg_count, "IrInstruction *"); + IrInstGen *result = ir_analyze_fn_call(ira, &call_instruction->base.base, fn_entry, fn_type, fn_ref, + first_arg_ptr, first_arg_ptr_src, modifier, new_stack, new_stack_src, + call_instruction->is_async_call_builtin, args_ptr, call_instruction->arg_count, ret_ptr, + call_instruction->result_loc); + deallocate(args_ptr, call_instruction->arg_count, "IrInstGen *"); return result; } -static IrInstruction *ir_analyze_call_extra(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *pass1_options, IrInstruction *pass1_fn_ref, IrInstruction **args_ptr, size_t args_len, +static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr, + IrInstSrc *pass1_options, IrInstSrc *pass1_fn_ref, IrInstGen **args_ptr, size_t args_len, ResultLoc *result_loc) { - IrInstruction *options = pass1_options->child; + IrInstGen *options = pass1_options->child; if (type_is_invalid(options->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *fn_ref = pass1_fn_ref->child; + IrInstGen *fn_ref = pass1_fn_ref->child; if (type_is_invalid(fn_ref->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; TypeStructField *modifier_field = find_struct_type_field(options->value->type, buf_create_from_str("modifier")); ir_assert(modifier_field != nullptr, source_instr); - IrInstruction *modifier_inst = ir_analyze_struct_value_field_value(ira, source_instr, options, modifier_field); + IrInstGen *modifier_inst = ir_analyze_struct_value_field_value(ira, source_instr, options, modifier_field); ZigValue *modifier_val = ir_resolve_const(ira, modifier_inst, UndefBad); if (modifier_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; CallModifier modifier = (CallModifier)bigint_as_u32(&modifier_val->data.x_enum_tag); - if (ir_should_inline(ira->new_irb.exec, source_instr->scope)) { + if (ir_should_inline(ira->old_irb.exec, source_instr->scope)) { switch (modifier) { case CallModifierBuiltin: zig_unreachable(); case CallModifierAsync: ir_add_error(ira, source_instr, buf_sprintf("TODO: comptime @call with async modifier")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case CallModifierCompileTime: case CallModifierNone: case CallModifierAlwaysInline: @@ -18750,23 +19814,25 @@ static IrInstruction *ir_analyze_call_extra(IrAnalyze *ira, IrInstruction *sourc case CallModifierNeverInline: ir_add_error(ira, source_instr, buf_sprintf("unable to perform 'never_inline' call at compile-time")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case CallModifierNeverTail: ir_add_error(ira, source_instr, buf_sprintf("unable to perform 'never_tail' call at compile-time")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } - IrInstruction *first_arg_ptr = nullptr; + IrInstGen *first_arg_ptr = nullptr; + IrInst *first_arg_ptr_src = nullptr; ZigFn *fn = nullptr; if (instr_is_comptime(fn_ref)) { if (fn_ref->value->type->id == ZigTypeIdBoundFn) { assert(fn_ref->value->special == ConstValSpecialStatic); fn = fn_ref->value->data.x_bound_fn.fn; first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg; + first_arg_ptr_src = fn_ref->value->data.x_bound_fn.first_arg_src; if (type_is_invalid(first_arg_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { fn = ir_resolve_fn(ira, fn_ref); } @@ -18778,9 +19844,9 @@ static IrInstruction *ir_analyze_call_extra(IrAnalyze *ira, IrInstruction *sourc case CallModifierAlwaysInline: case CallModifierAsync: if (fn == nullptr) { - ir_add_error(ira, modifier_inst, + ir_add_error(ira, &modifier_inst->base, buf_sprintf("the specified modifier requires a comptime-known function")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } default: break; @@ -18790,120 +19856,121 @@ static IrInstruction *ir_analyze_call_extra(IrAnalyze *ira, IrInstruction *sourc TypeStructField *stack_field = find_struct_type_field(options->value->type, buf_create_from_str("stack")); ir_assert(stack_field != nullptr, source_instr); - IrInstruction *opt_stack = ir_analyze_struct_value_field_value(ira, source_instr, options, stack_field); + IrInstGen *opt_stack = ir_analyze_struct_value_field_value(ira, source_instr, options, stack_field); if (type_is_invalid(opt_stack->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *stack_is_non_null_inst = ir_analyze_test_non_null(ira, source_instr, opt_stack); + IrInstGen *stack_is_non_null_inst = ir_analyze_test_non_null(ira, source_instr, opt_stack); bool stack_is_non_null; if (!ir_resolve_bool(ira, stack_is_non_null_inst, &stack_is_non_null)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *stack = nullptr; + IrInstGen *stack = nullptr; if (stack_is_non_null) { stack = ir_analyze_optional_value_payload_value(ira, source_instr, opt_stack, false); if (type_is_invalid(stack->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - return ir_analyze_fn_call(ira, source_instr, fn, fn_type, fn_ref, first_arg_ptr, - modifier, stack, false, args_ptr, args_len, nullptr, result_loc); + return ir_analyze_fn_call(ira, source_instr, fn, fn_type, fn_ref, first_arg_ptr, first_arg_ptr_src, + modifier, stack, &stack->base, false, args_ptr, args_len, nullptr, result_loc); } -static IrInstruction *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstructionCallExtra *instruction) { - IrInstruction *args = instruction->args->child; +static IrInstGen *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstSrcCallExtra *instruction) { + IrInstGen *args = instruction->args->child; ZigType *args_type = args->value->type; if (type_is_invalid(args_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (args_type->id != ZigTypeIdStruct) { - ir_add_error(ira, args, + ir_add_error(ira, &args->base, buf_sprintf("expected tuple or struct, found '%s'", buf_ptr(&args_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction **args_ptr = nullptr; + IrInstGen **args_ptr = nullptr; size_t args_len = 0; if (is_tuple(args_type)) { args_len = args_type->data.structure.src_field_count; - args_ptr = allocate<IrInstruction *>(args_len, "IrInstruction *"); + args_ptr = allocate<IrInstGen *>(args_len, "IrInstGen *"); for (size_t i = 0; i < args_len; i += 1) { TypeStructField *arg_field = args_type->data.structure.fields[i]; - args_ptr[i] = ir_analyze_struct_value_field_value(ira, &instruction->base, args, arg_field); + args_ptr[i] = ir_analyze_struct_value_field_value(ira, &instruction->base.base, args, arg_field); if (type_is_invalid(args_ptr[i]->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else { - ir_add_error(ira, args, buf_sprintf("TODO: struct args")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &args->base, buf_sprintf("TODO: struct args")); + return ira->codegen->invalid_inst_gen; } - IrInstruction *result = ir_analyze_call_extra(ira, &instruction->base, instruction->options, + IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options, instruction->fn_ref, args_ptr, args_len, instruction->result_loc); - deallocate(args_ptr, args_len, "IrInstruction *"); + deallocate(args_ptr, args_len, "IrInstGen *"); return result; } -static IrInstruction *ir_analyze_instruction_call_args(IrAnalyze *ira, IrInstructionCallSrcArgs *instruction) { - IrInstruction **args_ptr = allocate<IrInstruction *>(instruction->args_len, "IrInstruction *"); +static IrInstGen *ir_analyze_instruction_call_args(IrAnalyze *ira, IrInstSrcCallArgs *instruction) { + IrInstGen **args_ptr = allocate<IrInstGen *>(instruction->args_len, "IrInstGen *"); for (size_t i = 0; i < instruction->args_len; i += 1) { args_ptr[i] = instruction->args_ptr[i]->child; if (type_is_invalid(args_ptr[i]->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *result = ir_analyze_call_extra(ira, &instruction->base, instruction->options, + IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options, instruction->fn_ref, args_ptr, instruction->args_len, instruction->result_loc); - deallocate(args_ptr, instruction->args_len, "IrInstruction *"); + deallocate(args_ptr, instruction->args_len, "IrInstGen *"); return result; } -static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) { - IrInstruction *fn_ref = call_instruction->fn_ref->child; +static IrInstGen *ir_analyze_instruction_call(IrAnalyze *ira, IrInstSrcCall *call_instruction) { + IrInstGen *fn_ref = call_instruction->fn_ref->child; if (type_is_invalid(fn_ref->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; bool is_comptime = (call_instruction->modifier == CallModifierCompileTime) || - ir_should_inline(ira->new_irb.exec, call_instruction->base.scope); + ir_should_inline(ira->old_irb.exec, call_instruction->base.base.scope); CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; if (is_comptime || instr_is_comptime(fn_ref)) { if (fn_ref->value->type->id == ZigTypeIdMetaType) { ZigType *ty = ir_resolve_type(ira, fn_ref); if (ty == nullptr) - return ira->codegen->invalid_instruction; - ErrorMsg *msg = ir_add_error_node(ira, fn_ref->source_node, + return ira->codegen->invalid_inst_gen; + ErrorMsg *msg = ir_add_error(ira, &fn_ref->base, buf_sprintf("type '%s' not a function", buf_ptr(&ty->name))); - add_error_note(ira->codegen, msg, call_instruction->base.source_node, + add_error_note(ira->codegen, msg, call_instruction->base.base.source_node, buf_sprintf("use @as builtin for type coercion")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (fn_ref->value->type->id == ZigTypeIdFn) { ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref); ZigType *fn_type = fn_table_entry ? fn_table_entry->type_entry : fn_ref->value->type; CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; return ir_analyze_fn_call_src(ira, call_instruction, fn_table_entry, fn_type, - fn_ref, nullptr, modifier); + fn_ref, nullptr, nullptr, modifier); } else if (fn_ref->value->type->id == ZigTypeIdBoundFn) { assert(fn_ref->value->special == ConstValSpecialStatic); ZigFn *fn_table_entry = fn_ref->value->data.x_bound_fn.fn; - IrInstruction *first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg; + IrInstGen *first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg; + IrInst *first_arg_ptr_src = fn_ref->value->data.x_bound_fn.first_arg_src; CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; return ir_analyze_fn_call_src(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, - fn_ref, first_arg_ptr, modifier); + fn_ref, first_arg_ptr, first_arg_ptr_src, modifier); } else { - ir_add_error_node(ira, fn_ref->source_node, + ir_add_error(ira, &fn_ref->base, buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } if (fn_ref->value->type->id == ZigTypeIdFn) { return ir_analyze_fn_call_src(ira, call_instruction, nullptr, fn_ref->value->type, - fn_ref, nullptr, modifier); + fn_ref, nullptr, nullptr, modifier); } else { - ir_add_error_node(ira, fn_ref->source_node, + ir_add_error(ira, &fn_ref->base, buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } @@ -18992,8 +20059,8 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source zig_unreachable(); } -static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp *instruction) { - IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); +static IrInstGen *ir_analyze_optional_type(IrAnalyze *ira, IrInstSrcUnOp *instruction) { + IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); result->value->special = ConstValSpecialLazy; LazyValueOptType *lazy_opt_type = allocate<LazyValueOptType>(1, "LazyValueOptType"); @@ -19003,12 +20070,12 @@ static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp lazy_opt_type->payload_type = instruction->value->child; if (ir_resolve_type_lazy(ira, lazy_opt_type->payload_type) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return result; } -static ErrorMsg *ir_eval_negation_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *scalar_type, +static ErrorMsg *ir_eval_negation_scalar(IrAnalyze *ira, IrInst* source_instr, ZigType *scalar_type, ZigValue *operand_val, ZigValue *scalar_out_val, bool is_wrap_op) { bool is_float = (scalar_type->id == ZigTypeIdFloat || scalar_type->id == ZigTypeIdComptimeFloat); @@ -19043,19 +20110,19 @@ static ErrorMsg *ir_eval_negation_scalar(IrAnalyze *ira, IrInstruction *source_i return nullptr; } -static IrInstruction *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *instruction) { - IrInstruction *value = instruction->value->child; +static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction) { + IrInstGen *value = instruction->value->child; ZigType *expr_type = value->value->type; if (type_is_invalid(expr_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!(expr_type->id == ZigTypeIdInt || expr_type->id == ZigTypeIdComptimeInt || expr_type->id == ZigTypeIdFloat || expr_type->id == ZigTypeIdComptimeFloat || expr_type->id == ZigTypeIdVector)) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("negation of type '%s'", buf_ptr(&expr_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap); @@ -19065,9 +20132,9 @@ static IrInstruction *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *ins if (instr_is_comptime(value)) { ZigValue *operand_val = ir_resolve_const(ira, value, UndefBad); if (!operand_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result_instruction = ir_const(ira, &instruction->base, expr_type); + IrInstGen *result_instruction = ir_const(ira, &instruction->base.base, expr_type); ZigValue *out_val = result_instruction->value; if (expr_type->id == ZigTypeIdVector) { expand_undef_array(ira->codegen, operand_val); @@ -19079,63 +20146,60 @@ static IrInstruction *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *ins ZigValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; assert(scalar_operand_val->type == scalar_type); assert(scalar_out_val->type == scalar_type); - ErrorMsg *msg = ir_eval_negation_scalar(ira, &instruction->base, scalar_type, + ErrorMsg *msg = ir_eval_negation_scalar(ira, &instruction->base.base, scalar_type, scalar_operand_val, scalar_out_val, is_wrap_op); if (msg != nullptr) { - add_error_note(ira->codegen, msg, instruction->base.source_node, + add_error_note(ira->codegen, msg, instruction->base.base.source_node, buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } out_val->type = expr_type; out_val->special = ConstValSpecialStatic; } else { - if (ir_eval_negation_scalar(ira, &instruction->base, scalar_type, operand_val, out_val, + if (ir_eval_negation_scalar(ira, &instruction->base.base, scalar_type, operand_val, out_val, is_wrap_op) != nullptr) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } return result_instruction; } - IrInstruction *result = ir_build_un_op(&ira->new_irb, - instruction->base.scope, instruction->base.source_node, - instruction->op_id, value); - result->value->type = expr_type; - return result; + if (is_wrap_op) { + return ir_build_negation_wrapping(ira, &instruction->base.base, value, expr_type); + } else { + return ir_build_negation(ira, &instruction->base.base, value, expr_type); + } } -static IrInstruction *ir_analyze_bin_not(IrAnalyze *ira, IrInstructionUnOp *instruction) { - IrInstruction *value = instruction->value->child; +static IrInstGen *ir_analyze_bin_not(IrAnalyze *ira, IrInstSrcUnOp *instruction) { + IrInstGen *value = instruction->value->child; ZigType *expr_type = value->value->type; if (type_is_invalid(expr_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (expr_type->id == ZigTypeIdInt) { if (instr_is_comptime(value)) { ZigValue *target_const_val = ir_resolve_const(ira, value, UndefBad); if (target_const_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result = ir_const(ira, &instruction->base, expr_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, expr_type); bigint_not(&result->value->data.x_bigint, &target_const_val->data.x_bigint, expr_type->data.integral.bit_count, expr_type->data.integral.is_signed); return result; } - IrInstruction *result = ir_build_un_op(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, IrUnOpBinNot, value); - result->value->type = expr_type; - return result; + return ir_build_binary_not(ira, &instruction->base.base, value, expr_type); } - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("unable to perform binary not operation on type '%s'", buf_ptr(&expr_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } -static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructionUnOp *instruction) { +static IrInstGen *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstSrcUnOp *instruction) { IrUnOp op_id = instruction->op_id; switch (op_id) { case IrUnOpInvalid: @@ -19146,26 +20210,26 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction case IrUnOpNegationWrap: return ir_analyze_negation(ira, instruction); case IrUnOpDereference: { - IrInstruction *ptr = instruction->value->child; + IrInstGen *ptr = instruction->value->child; if (type_is_invalid(ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *ptr_type = ptr->value->type; if (ptr_type->id == ZigTypeIdPointer && ptr_type->data.pointer.ptr_len == PtrLenUnknown) { - ir_add_error_node(ira, instruction->base.source_node, + ir_add_error_node(ira, instruction->base.base.source_node, buf_sprintf("index syntax required for unknown-length pointer type '%s'", buf_ptr(&ptr_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr, instruction->result_loc); - if (result == ira->codegen->invalid_instruction) - return ira->codegen->invalid_instruction; + IrInstGen *result = ir_get_deref(ira, &instruction->base.base, ptr, instruction->result_loc); + if (type_is_invalid(result->value->type)) + return ira->codegen->invalid_inst_gen; // If the result needs to be an lvalue, type check it if (instruction->lval == LValPtr && result->value->type->id != ZigTypeIdPointer) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("attempt to dereference non-pointer type '%s'", buf_ptr(&result->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return result; @@ -19177,42 +20241,40 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction } static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) { - IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index); + IrBasicBlockSrc *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index); if (old_bb->in_resume_stack) return; ira->resume_stack.append(pos); old_bb->in_resume_stack = true; } -static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlock *old_bb) { +static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlockSrc *old_bb) { if (ira->resume_stack.length != 0) { ir_push_resume(ira, {old_bb->index, 0}); } } -static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { - IrBasicBlock *old_dest_block = br_instruction->dest_block; +static IrInstGen *ir_analyze_instruction_br(IrAnalyze *ira, IrInstSrcBr *br_instruction) { + IrBasicBlockSrc *old_dest_block = br_instruction->dest_block; bool is_comptime; if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) return ir_unreach_error(ira); if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) - return ir_inline_bb(ira, &br_instruction->base, old_dest_block); + return ir_inline_bb(ira, &br_instruction->base.base, old_dest_block); - IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base); + IrBasicBlockGen *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base.base); if (new_bb == nullptr) return ir_unreach_error(ira); ir_push_resume_block(ira, old_dest_block); - IrInstruction *result = ir_build_br(&ira->new_irb, - br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr); - result->value->type = ira->codegen->builtin_types.entry_unreachable; + IrInstGen *result = ir_build_br_gen(ira, &br_instruction->base.base, new_bb); return ir_finish_anal(ira, result); } -static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructionCondBr *cond_br_instruction) { - IrInstruction *condition = cond_br_instruction->condition->child; +static IrInstGen *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstSrcCondBr *cond_br_instruction) { + IrInstGen *condition = cond_br_instruction->condition->child; if (type_is_invalid(condition->value->type)) return ir_unreach_error(ira); @@ -19221,7 +20283,7 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi return ir_unreach_error(ira); ZigType *bool_type = ira->codegen->builtin_types.entry_bool; - IrInstruction *casted_condition = ir_implicit_cast(ira, condition, bool_type); + IrInstGen *casted_condition = ir_implicit_cast(ira, condition, bool_type); if (type_is_invalid(casted_condition->value->type)) return ir_unreach_error(ira); @@ -19230,67 +20292,61 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi if (!ir_resolve_bool(ira, casted_condition, &cond_is_true)) return ir_unreach_error(ira); - IrBasicBlock *old_dest_block = cond_is_true ? + IrBasicBlockSrc *old_dest_block = cond_is_true ? cond_br_instruction->then_block : cond_br_instruction->else_block; if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) - return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); + return ir_inline_bb(ira, &cond_br_instruction->base.base, old_dest_block); - IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base); + IrBasicBlockGen *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base.base); if (new_dest_block == nullptr) return ir_unreach_error(ira); ir_push_resume_block(ira, old_dest_block); - IrInstruction *result = ir_build_br(&ira->new_irb, - cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr); - result->value->type = ira->codegen->builtin_types.entry_unreachable; + IrInstGen *result = ir_build_br_gen(ira, &cond_br_instruction->base.base, new_dest_block); return ir_finish_anal(ira, result); } assert(cond_br_instruction->then_block != cond_br_instruction->else_block); - IrBasicBlock *new_then_block = ir_get_new_bb_runtime(ira, cond_br_instruction->then_block, &cond_br_instruction->base); + IrBasicBlockGen *new_then_block = ir_get_new_bb_runtime(ira, cond_br_instruction->then_block, &cond_br_instruction->base.base); if (new_then_block == nullptr) return ir_unreach_error(ira); - IrBasicBlock *new_else_block = ir_get_new_bb_runtime(ira, cond_br_instruction->else_block, &cond_br_instruction->base); + IrBasicBlockGen *new_else_block = ir_get_new_bb_runtime(ira, cond_br_instruction->else_block, &cond_br_instruction->base.base); if (new_else_block == nullptr) return ir_unreach_error(ira); ir_push_resume_block(ira, cond_br_instruction->else_block); ir_push_resume_block(ira, cond_br_instruction->then_block); - IrInstruction *result = ir_build_cond_br(&ira->new_irb, - cond_br_instruction->base.scope, cond_br_instruction->base.source_node, - casted_condition, new_then_block, new_else_block, nullptr); - result->value->type = ira->codegen->builtin_types.entry_unreachable; + IrInstGen *result = ir_build_cond_br_gen(ira, &cond_br_instruction->base.base, + casted_condition, new_then_block, new_else_block); return ir_finish_anal(ira, result); } -static IrInstruction *ir_analyze_instruction_unreachable(IrAnalyze *ira, - IrInstructionUnreachable *unreachable_instruction) +static IrInstGen *ir_analyze_instruction_unreachable(IrAnalyze *ira, + IrInstSrcUnreachable *unreachable_instruction) { - IrInstruction *result = ir_build_unreachable(&ira->new_irb, - unreachable_instruction->base.scope, unreachable_instruction->base.source_node); - result->value->type = ira->codegen->builtin_types.entry_unreachable; + IrInstGen *result = ir_build_unreachable_gen(ira, &unreachable_instruction->base.base); return ir_finish_anal(ira, result); } -static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) { +static IrInstGen *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstSrcPhi *phi_instruction) { Error err; if (ira->const_predecessor_bb) { for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { - IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; + IrBasicBlockSrc *predecessor = phi_instruction->incoming_blocks[i]; if (predecessor != ira->const_predecessor_bb) continue; - IrInstruction *value = phi_instruction->incoming_values[i]->child; + IrInstGen *value = phi_instruction->incoming_values[i]->child; assert(value->value->type); if (type_is_invalid(value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (value->value->special != ConstValSpecialRuntime) { - IrInstruction *result = ir_const(ira, &phi_instruction->base, nullptr); + IrInstGen *result = ir_const(ira, &phi_instruction->base.base, nullptr); copy_const_val(result->value, value->value); return result; } else { @@ -19305,17 +20361,17 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh peer_parent->peers.length >= 2) { if (peer_parent->resolved_type == nullptr) { - IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peers.length); + IrInstGen **instructions = allocate<IrInstGen *>(peer_parent->peers.length); for (size_t i = 0; i < peer_parent->peers.length; i += 1) { ResultLocPeer *this_peer = peer_parent->peers.at(i); - IrInstruction *gen_instruction = this_peer->base.gen_instruction; + IrInstGen *gen_instruction = this_peer->base.gen_instruction; if (gen_instruction == nullptr) { // unreachable instructions will cause implicit_elem_type to be null if (this_peer->base.implicit_elem_type == nullptr) { - instructions[i] = ir_const_unreachable(ira, this_peer->base.source_instruction); + instructions[i] = ir_const_unreachable(ira, &this_peer->base.source_instruction->base); } else { - instructions[i] = ir_const(ira, this_peer->base.source_instruction, + instructions[i] = ir_const(ira, &this_peer->base.source_instruction->base, this_peer->base.implicit_elem_type); instructions[i]->value->special = ConstValSpecialRuntime; } @@ -19324,34 +20380,34 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh } } - ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base, peer_parent->parent); + ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base.base, peer_parent->parent); peer_parent->resolved_type = ir_resolve_peer_types(ira, - peer_parent->base.source_instruction->source_node, expected_type, instructions, + peer_parent->base.source_instruction->base.source_node, expected_type, instructions, peer_parent->peers.length); if (type_is_invalid(peer_parent->resolved_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // the logic below assumes there are no instructions in the new current basic block yet - ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base); + ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base.base); // In case resolving the parent activates a suspend, do it now - IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent, - peer_parent->resolved_type, nullptr, false, false, true); + IrInstGen *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base.base, peer_parent->parent, + peer_parent->resolved_type, nullptr, false, true); if (parent_result_loc != nullptr && - (type_is_invalid(parent_result_loc->value->type) || instr_is_unreachable(parent_result_loc))) + (type_is_invalid(parent_result_loc->value->type) || parent_result_loc->value->type->id == ZigTypeIdUnreachable)) { return parent_result_loc; } // If the above code generated any instructions in the current basic block, we need // to move them to the peer parent predecessor. - ZigList<IrInstruction *> instrs_to_move = {}; + ZigList<IrInstGen *> instrs_to_move = {}; while (ira->new_irb.current_basic_block->instruction_list.length != 0) { instrs_to_move.append(ira->new_irb.current_basic_block->instruction_list.pop()); } if (instrs_to_move.length != 0) { - IrBasicBlock *predecessor = peer_parent->base.source_instruction->child->owner_bb; - IrInstruction *branch_instruction = predecessor->instruction_list.pop(); - ir_assert(branch_instruction->value->type->id == ZigTypeIdUnreachable, &phi_instruction->base); + IrBasicBlockGen *predecessor = peer_parent->base.source_instruction->child->owner_bb; + IrInstGen *branch_instruction = predecessor->instruction_list.pop(); + ir_assert(branch_instruction->value->type->id == ZigTypeIdUnreachable, &phi_instruction->base.base); while (instrs_to_move.length != 0) { predecessor->instruction_list.append(instrs_to_move.pop()); } @@ -19360,7 +20416,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh } IrSuspendPosition suspend_pos; - ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos); + ira_suspend(ira, &phi_instruction->base.base, nullptr, &suspend_pos); ir_push_resume(ira, suspend_pos); for (size_t i = 0; i < peer_parent->peers.length; i += 1) { @@ -19376,34 +20432,32 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh return ira_resume(ira); } - ZigList<IrBasicBlock*> new_incoming_blocks = {0}; - ZigList<IrInstruction*> new_incoming_values = {0}; + ZigList<IrBasicBlockGen*> new_incoming_blocks = {0}; + ZigList<IrInstGen*> new_incoming_values = {0}; for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { - IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; + IrBasicBlockSrc *predecessor = phi_instruction->incoming_blocks[i]; if (predecessor->ref_count == 0) continue; - IrInstruction *old_value = phi_instruction->incoming_values[i]; + IrInstSrc *old_value = phi_instruction->incoming_values[i]; assert(old_value); - IrInstruction *new_value = old_value->child; - if (!new_value || new_value->value->type->id == ZigTypeIdUnreachable || predecessor->other == nullptr) + IrInstGen *new_value = old_value->child; + if (!new_value || new_value->value->type->id == ZigTypeIdUnreachable || predecessor->child == nullptr) continue; if (type_is_invalid(new_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - assert(predecessor->other); - new_incoming_blocks.append(predecessor->other); + assert(predecessor->child); + new_incoming_blocks.append(predecessor->child); new_incoming_values.append(new_value); } if (new_incoming_blocks.length == 0) { - IrInstruction *result = ir_build_unreachable(&ira->new_irb, - phi_instruction->base.scope, phi_instruction->base.source_node); - result->value->type = ira->codegen->builtin_types.entry_unreachable; + IrInstGen *result = ir_build_unreachable_gen(ira, &phi_instruction->base.base); return ir_finish_anal(ira, result); } @@ -19415,7 +20469,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh if (peer_parent != nullptr) { bool peer_parent_has_type; if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (peer_parent_has_type) { if (peer_parent->parent->id == ResultLocIdReturn) { resolved_type = ira->explicit_return_type; @@ -19423,27 +20477,27 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child); } else if (peer_parent->parent->resolved_loc) { ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value->type; - ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base); + ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base.base); resolved_type = resolved_loc_ptr_type->data.pointer.child_type; } if (resolved_type != nullptr && type_is_invalid(resolved_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } if (resolved_type == nullptr) { - resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr, + resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.base.source_node, nullptr, new_incoming_values.items, new_incoming_values.length); if (type_is_invalid(resolved_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } switch (type_has_one_possible_value(ira->codegen, resolved_type)) { case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueYes: - return ir_const_move(ira, &phi_instruction->base, + return ir_const_move(ira, &phi_instruction->base.base, get_the_one_possible_value(ira->codegen, resolved_type)); case OnePossibleValueNo: break; @@ -19451,11 +20505,11 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh switch (type_requires_comptime(ira->codegen, resolved_type)) { case ReqCompTimeInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case ReqCompTimeYes: - ir_add_error_node(ira, phi_instruction->base.source_node, + ir_add_error(ira, &phi_instruction->base.base, buf_sprintf("values of type '%s' must be comptime known", buf_ptr(&resolved_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case ReqCompTimeNo: break; } @@ -19465,16 +20519,16 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh // cast all values to the resolved type. however we can't put cast instructions in front of the phi instruction. // so we go back and insert the casts as the last instruction in the corresponding predecessor blocks, and // then make sure the branch instruction is preserved. - IrBasicBlock *cur_bb = ira->new_irb.current_basic_block; + IrBasicBlockGen *cur_bb = ira->new_irb.current_basic_block; for (size_t i = 0; i < new_incoming_values.length; i += 1) { - IrInstruction *new_value = new_incoming_values.at(i); - IrBasicBlock *predecessor = new_incoming_blocks.at(i); - ir_assert(predecessor->instruction_list.length != 0, &phi_instruction->base); - IrInstruction *branch_instruction = predecessor->instruction_list.pop(); - ir_set_cursor_at_end(&ira->new_irb, predecessor); - IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); + IrInstGen *new_value = new_incoming_values.at(i); + IrBasicBlockGen *predecessor = new_incoming_blocks.at(i); + ir_assert(predecessor->instruction_list.length != 0, &phi_instruction->base.base); + IrInstGen *branch_instruction = predecessor->instruction_list.pop(); + ir_set_cursor_at_end_gen(&ira->new_irb, predecessor); + IrInstGen *casted_value = ir_implicit_cast(ira, new_value, resolved_type); if (type_is_invalid(casted_value->value->type)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } new_incoming_values.items[i] = casted_value; predecessor->instruction_list.append(branch_instruction); @@ -19485,12 +20539,10 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh all_stack_ptrs = false; } } - ir_set_cursor_at_end(&ira->new_irb, cur_bb); + ir_set_cursor_at_end_gen(&ira->new_irb, cur_bb); - IrInstruction *result = ir_build_phi(&ira->new_irb, - phi_instruction->base.scope, phi_instruction->base.source_node, - new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items, nullptr); - result->value->type = resolved_type; + IrInstGen *result = ir_build_phi_gen(ira, &phi_instruction->base.base, + new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items, resolved_type); if (all_stack_ptrs) { assert(result->value->special == ConstValSpecialRuntime); @@ -19500,17 +20552,17 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh return result; } -static IrInstruction *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *instruction) { +static IrInstGen *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstSrcVarPtr *instruction) { ZigVar *var = instruction->var; - IrInstruction *result = ir_get_var_ptr(ira, &instruction->base, var); + IrInstGen *result = ir_get_var_ptr(ira, &instruction->base.base, var); if (instruction->crossed_fndef_scope != nullptr && !instr_is_comptime(result)) { - ErrorMsg *msg = ir_add_error(ira, &instruction->base, + ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, buf_sprintf("'%s' not accessible from inner function", var->name)); add_error_note(ira->codegen, msg, instruction->crossed_fndef_scope->base.source_node, buf_sprintf("crossed function definition here")); add_error_note(ira->codegen, msg, var->decl_node, buf_sprintf("declared here")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return result; } @@ -19561,17 +20613,17 @@ static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) { ptr_type->data.pointer.allow_zero); } -static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) { +static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemPtr *elem_ptr_instruction) { Error err; - IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->child; + IrInstGen *array_ptr = elem_ptr_instruction->array_ptr->child; if (type_is_invalid(array_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *orig_array_ptr_val = array_ptr->value; - IrInstruction *elem_index = elem_ptr_instruction->elem_index->child; + IrInstGen *elem_index = elem_ptr_instruction->elem_index->child; if (type_is_invalid(elem_index->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *ptr_type = orig_array_ptr_val->type; assert(ptr_type->id == ZigTypeIdPointer); @@ -19583,7 +20635,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct ZigType *return_type; if (type_is_invalid(array_type)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (array_type->id == ZigTypeIdArray || (array_type->id == ZigTypeIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle && @@ -19594,15 +20646,15 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct ptr_type = ptr_type->data.pointer.child_type; if (orig_array_ptr_val->special != ConstValSpecialRuntime) { orig_array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val, - elem_ptr_instruction->base.source_node); + elem_ptr_instruction->base.base.source_node); if (orig_array_ptr_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } if (array_type->data.array.len == 0) { - ir_add_error_node(ira, elem_ptr_instruction->base.source_node, + ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, buf_sprintf("index 0 outside array of size 0")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *child_type = array_type->data.array.child_type; if (ptr_type->data.pointer.host_int_bytes == 0) { @@ -19613,7 +20665,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct } else { uint64_t elem_val_scalar; if (!ir_resolve_usize(ira, elem_index, &elem_val_scalar)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; size_t bit_width = type_size_bits(ira->codegen, child_type); size_t bit_offset = bit_width * elem_val_scalar; @@ -19625,9 +20677,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct } } else if (array_type->id == ZigTypeIdPointer) { if (array_type->data.pointer.ptr_len == PtrLenSingle) { - ir_add_error_node(ira, elem_ptr_instruction->base.source_node, + ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, buf_sprintf("index of single-item pointer")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len); } else if (is_slice(array_type)) { @@ -19641,38 +20693,38 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct array_type->data.structure.resolve_status == ResolveStatusBeingInferred) { ZigType *usize = ira->codegen->builtin_types.entry_usize; - IrInstruction *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); + IrInstGen *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); if (type_is_invalid(casted_elem_index->value->type)) - return ira->codegen->invalid_instruction; - ir_assert(instr_is_comptime(casted_elem_index), &elem_ptr_instruction->base); + return ira->codegen->invalid_inst_gen; + ir_assert(instr_is_comptime(casted_elem_index), &elem_ptr_instruction->base.base); Buf *field_name = buf_alloc(); bigint_append_buf(field_name, &casted_elem_index->value->data.x_bigint, 10); - return ir_analyze_inferred_field_ptr(ira, field_name, &elem_ptr_instruction->base, + return ir_analyze_inferred_field_ptr(ira, field_name, &elem_ptr_instruction->base.base, array_ptr, array_type); } else if (is_tuple(array_type)) { uint64_t elem_index_scalar; if (!ir_resolve_usize(ira, elem_index, &elem_index_scalar)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (elem_index_scalar >= array_type->data.structure.src_field_count) { - ir_add_error(ira, &elem_ptr_instruction->base, buf_sprintf( + ir_add_error(ira, &elem_ptr_instruction->base.base, buf_sprintf( "field index %" ZIG_PRI_u64 " outside tuple '%s' which has %" PRIu32 " fields", elem_index_scalar, buf_ptr(&array_type->name), array_type->data.structure.src_field_count)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } TypeStructField *field = array_type->data.structure.fields[elem_index_scalar]; - return ir_analyze_struct_field_ptr(ira, &elem_ptr_instruction->base, field, array_ptr, + return ir_analyze_struct_field_ptr(ira, &elem_ptr_instruction->base.base, field, array_ptr, array_type, false); } else { - ir_add_error_node(ira, elem_ptr_instruction->base.source_node, + ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *usize = ira->codegen->builtin_types.entry_usize; - IrInstruction *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); - if (casted_elem_index == ira->codegen->invalid_instruction) - return ira->codegen->invalid_instruction; + IrInstGen *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); + if (type_is_invalid(casted_elem_index->value->type)) + return ira->codegen->invalid_inst_gen; bool safety_check_on = elem_ptr_instruction->safety_check_on; if (instr_is_comptime(casted_elem_index)) { @@ -19681,15 +20733,15 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct uint64_t array_len = array_type->data.array.len; if (index == array_len && array_type->data.array.sentinel != nullptr) { ZigType *elem_type = array_type->data.array.child_type; - IrInstruction *sentinel_elem = ir_const(ira, &elem_ptr_instruction->base, elem_type); + IrInstGen *sentinel_elem = ir_const(ira, &elem_ptr_instruction->base.base, elem_type); copy_const_val(sentinel_elem->value, array_type->data.array.sentinel); - return ir_get_ref(ira, &elem_ptr_instruction->base, sentinel_elem, true, false); + return ir_get_ref(ira, &elem_ptr_instruction->base.base, sentinel_elem, true, false); } if (index >= array_len) { - ir_add_error_node(ira, elem_ptr_instruction->base.source_node, + ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, buf_sprintf("index %" ZIG_PRI_u64 " outside array of size %" ZIG_PRI_u64, index, array_len)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } safety_check_on = false; } @@ -19705,7 +20757,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct // figure out the largest alignment possible if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); @@ -19729,15 +20781,17 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct return_type = adjust_ptr_align(ira->codegen, return_type, chosen_align); } + // TODO The `array_type->id == ZigTypeIdArray` exception here should not be an exception; + // the `orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar` clause should be omitted completely. + // However there are bugs to fix before this improvement can be made. if (orig_array_ptr_val->special != ConstValSpecialRuntime && orig_array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && - (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || - array_type->id == ZigTypeIdArray)) + (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == ZigTypeIdArray)) { ZigValue *array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val, - elem_ptr_instruction->base.source_node); + elem_ptr_instruction->base.base.source_node); if (array_ptr_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (array_ptr_val->special == ConstValSpecialUndef && elem_ptr_instruction->init_array_type_source_node != nullptr) @@ -19755,16 +20809,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct elem_val->parent.data.p_array.elem_index = i; } } else if (is_slice(array_type)) { - ir_assert(array_ptr->value->type->id == ZigTypeIdPointer, &elem_ptr_instruction->base); + ir_assert(array_ptr->value->type->id == ZigTypeIdPointer, &elem_ptr_instruction->base.base); ZigType *actual_array_type = array_ptr->value->type->data.pointer.child_type; if (type_is_invalid(actual_array_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (actual_array_type->id != ZigTypeIdArray) { ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", buf_ptr(&actual_array_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigValue *array_init_val = create_const_vals(1); @@ -19789,7 +20843,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, buf_sprintf("expected array type or [_], found '%s'", buf_ptr(&array_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } @@ -19797,8 +20851,13 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct (array_type->id != ZigTypeIdPointer || array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) { + if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, + elem_ptr_instruction->base.base.source_node, array_ptr_val, UndefOk))) + { + return ira->codegen->invalid_inst_gen; + } if (array_type->id == ZigTypeIdPointer) { - IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); + IrInstGen *result = ir_const(ira, &elem_ptr_instruction->base.base, return_type); ZigValue *out_val = result->value; out_val->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; size_t new_index; @@ -19867,33 +20926,31 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct zig_panic("TODO elem ptr on a null pointer"); } if (new_index >= mem_size) { - ir_add_error_node(ira, elem_ptr_instruction->base.source_node, + ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, buf_sprintf("index %" ZIG_PRI_u64 " outside pointer of size %" ZIG_PRI_usize "", index, old_size)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return result; } else if (is_slice(array_type)) { ZigValue *ptr_field = array_ptr_val->data.x_struct.fields[slice_ptr_index]; - ir_assert(ptr_field != nullptr, &elem_ptr_instruction->base); + ir_assert(ptr_field != nullptr, &elem_ptr_instruction->base.base); if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { - IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, - elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, false, - elem_ptr_instruction->ptr_len, nullptr); - result->value->type = return_type; - return result; + return ir_build_elem_ptr_gen(ira, elem_ptr_instruction->base.base.scope, + elem_ptr_instruction->base.base.source_node, array_ptr, casted_elem_index, false, + return_type); } ZigValue *len_field = array_ptr_val->data.x_struct.fields[slice_len_index]; - IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); + IrInstGen *result = ir_const(ira, &elem_ptr_instruction->base.base, return_type); ZigValue *out_val = result->value; ZigType *slice_ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; uint64_t slice_len = bigint_as_u64(&len_field->data.x_bigint); uint64_t full_slice_len = slice_len + ((slice_ptr_type->data.pointer.sentinel != nullptr) ? 1 : 0); if (index >= full_slice_len) { - ir_add_error_node(ira, elem_ptr_instruction->base.source_node, + ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, buf_sprintf("index %" ZIG_PRI_u64 " outside slice of size %" ZIG_PRI_u64, index, slice_len)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut; switch (ptr_field->data.x_ptr.special) { @@ -19913,7 +20970,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct { ir_assert(new_index < ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len, - &elem_ptr_instruction->base); + &elem_ptr_instruction->base.base); } out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; out_val->data.x_ptr.data.base_array.array_val = @@ -19938,15 +20995,14 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct } return result; } else if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) { - IrInstruction *result; + IrInstGen *result; if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { - result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, - elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, - false, elem_ptr_instruction->ptr_len, nullptr); - result->value->type = return_type; + result = ir_build_elem_ptr_gen(ira, elem_ptr_instruction->base.base.scope, + elem_ptr_instruction->base.base.source_node, array_ptr, casted_elem_index, + false, return_type); result->value->special = ConstValSpecialStatic; } else { - result = ir_const(ira, &elem_ptr_instruction->base, return_type); + result = ir_const(ira, &elem_ptr_instruction->base.base, return_type); } ZigValue *out_val = result->value; out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; @@ -19972,19 +21028,19 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct // runtime known element index switch (type_requires_comptime(ira->codegen, return_type)) { case ReqCompTimeYes: - ir_add_error(ira, elem_index, + ir_add_error(ira, &elem_index->base, buf_sprintf("values of type '%s' must be comptime known, but index value is runtime known", buf_ptr(&return_type->data.pointer.child_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case ReqCompTimeInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case ReqCompTimeNo: break; } if (return_type->data.pointer.explicit_alignment != 0) { if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); @@ -20002,16 +21058,13 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct } } - IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, - elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, safety_check_on, - elem_ptr_instruction->ptr_len, nullptr); - result->value->type = return_type; - return result; + return ir_build_elem_ptr_gen(ira, elem_ptr_instruction->base.base.scope, + elem_ptr_instruction->base.base.source_node, array_ptr, casted_elem_index, safety_check_on, return_type); } -static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, - ZigType *bare_struct_type, Buf *field_name, IrInstruction *source_instr, - IrInstruction *container_ptr, ZigType *container_type) +static IrInstGen *ir_analyze_container_member_access_inner(IrAnalyze *ira, + ZigType *bare_struct_type, Buf *field_name, IrInst* source_instr, + IrInstGen *container_ptr, IrInst *container_ptr_src, ZigType *container_type) { if (!is_slice(bare_struct_type)) { ScopeDecls *container_scope = get_container_scope(bare_struct_type); @@ -20021,29 +21074,39 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, if (tld->id == TldIdFn) { resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); if (tld->resolution == TldResolutionInvalid) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; + if (tld->resolution == TldResolutionResolving) + return ir_error_dependency_loop(ira, source_instr); + TldFn *tld_fn = (TldFn *)tld; ZigFn *fn_entry = tld_fn->fn_entry; + assert(fn_entry != nullptr); + if (type_is_invalid(fn_entry->type_entry)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope, - source_instr->source_node, fn_entry, container_ptr); + IrInstGen *bound_fn_value = ir_const_bound_fn(ira, source_instr, fn_entry, container_ptr, + container_ptr_src); return ir_get_ref(ira, source_instr, bound_fn_value, true, false); } else if (tld->id == TldIdVar) { resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); if (tld->resolution == TldResolutionInvalid) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; + if (tld->resolution == TldResolutionResolving) + return ir_error_dependency_loop(ira, source_instr); + TldVar *tld_var = (TldVar *)tld; ZigVar *var = tld_var->var; + assert(var != nullptr); + if (type_is_invalid(var->var_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (var->const_value->type->id == ZigTypeIdFn) { ir_assert(var->const_value->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); ZigFn *fn = var->const_value->data.x_ptr.data.fn.fn_entry; - IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope, - source_instr->source_node, fn, container_ptr); + IrInstGen *bound_fn_value = ir_const_bound_fn(ira, source_instr, fn, container_ptr, + container_ptr_src); return ir_get_ref(ira, source_instr, bound_fn_value, true, false); } } @@ -20063,7 +21126,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, } ir_add_error_node(ira, source_instr->source_node, buf_sprintf("no member named '%s' in %s'%s'", buf_ptr(field_name), prefix_name, buf_ptr(&bare_struct_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field) { @@ -20078,24 +21141,24 @@ static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, Ty field->type_entry, nullptr, UndefOk); } -static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, - TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing) +static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_instr, + TypeStructField *field, IrInstGen *struct_ptr, ZigType *struct_type, bool initializing) { Error err; ZigType *field_type = resolve_struct_field_type(ira->codegen, field); if (field_type == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (field->is_comptime) { - IrInstruction *elem = ir_const(ira, source_instr, field_type); + IrInstGen *elem = ir_const(ira, source_instr, field_type); memoize_field_init_val(ira->codegen, struct_type, field); copy_const_val(elem->value, field->init_val); - return ir_get_ref(ira, source_instr, elem, true, false); + return ir_get_ref2(ira, source_instr, elem, field_type, true, false); } switch (type_has_one_possible_value(ira->codegen, field_type)) { case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueYes: { - IrInstruction *elem = ir_const_move(ira, source_instr, + IrInstGen *elem = ir_const_move(ira, source_instr, get_the_one_possible_value(ira->codegen, field_type)); return ir_get_ref(ira, source_instr, elem, false, false); } @@ -20113,7 +21176,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction (struct_type->data.structure.layout == ContainerLayoutAuto) ? ResolveStatusZeroBitsKnown : ResolveStatusSizeKnown; if ((err = type_resolve(ira->codegen, struct_type, needed_resolve_status))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; assert(struct_ptr->value->type->id == ZigTypeIdPointer); uint32_t ptr_bit_offset = struct_ptr->value->type->data.pointer.bit_offset_in_host; uint32_t ptr_host_int_bytes = struct_ptr->value->type->data.pointer.host_int_bytes; @@ -20127,14 +21190,14 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction if (instr_is_comptime(struct_ptr)) { ZigValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad); if (!ptr_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); if (struct_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (type_is_invalid(struct_val->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (initializing && struct_val->special == ConstValSpecialUndef) { struct_val->data.x_struct.fields = alloc_const_vals_ptrs(struct_type->data.structure.src_field_count); struct_val->special = ConstValSpecialStatic; @@ -20148,11 +21211,9 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction field_val->parent.data.p_struct.field_index = i; } } - IrInstruction *result; + IrInstGen *result; if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { - result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, - source_instr->source_node, struct_ptr, field); - result->value->type = ptr_type; + result = ir_build_struct_field_ptr(ira, source_instr, struct_ptr, field, ptr_type); result->value->special = ConstValSpecialStatic; } else { result = ir_const(ira, source_instr, ptr_type); @@ -20165,14 +21226,11 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction return result; } } - IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, - struct_ptr, field); - result->value->type = ptr_type; - return result; + return ir_build_struct_field_ptr(ira, source_instr, struct_ptr, field, ptr_type); } -static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, - IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type) +static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, + IrInst* source_instr, IrInstGen *container_ptr, ZigType *container_type) { // The type of the field is not available until a store using this pointer happens. // So, here we create a special pointer type which has the inferred struct type and @@ -20195,12 +21253,11 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n if (instr_is_comptime(container_ptr)) { ZigValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); if (ptr_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result; + IrInstGen *result; if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { - result = ir_build_cast(&ira->new_irb, source_instr->scope, - source_instr->source_node, container_ptr_type, container_ptr, CastOpNoop); + result = ir_build_cast(ira, source_instr, container_ptr_type, container_ptr, CastOpNoop); } else { result = ir_const(ira, source_instr, field_ptr_type); } @@ -20209,14 +21266,12 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n return result; } - IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, - source_instr->source_node, field_ptr_type, container_ptr, CastOpNoop); - result->value->type = field_ptr_type; - return result; + return ir_build_cast(ira, source_instr, field_ptr_type, container_ptr, CastOpNoop); } -static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, - IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing) +static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, + IrInst* source_instr, IrInstGen *container_ptr, IrInst *container_ptr_src, + ZigType *container_type, bool initializing) { Error err; @@ -20229,7 +21284,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ } if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; assert(container_ptr->value->type->id == ZigTypeIdPointer); if (bare_type->id == ZigTypeIdStruct) { @@ -20238,13 +21293,13 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); } else { return ir_analyze_container_member_access_inner(ira, bare_type, field_name, - source_instr, container_ptr, container_type); + source_instr, container_ptr, container_ptr_src, container_type); } } if (bare_type->id == ZigTypeIdEnum) { return ir_analyze_container_member_access_inner(ira, bare_type, field_name, - source_instr, container_ptr, container_type); + source_instr, container_ptr, container_ptr_src, container_type); } if (bare_type->id == ZigTypeIdUnion) { @@ -20254,27 +21309,27 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ TypeUnionField *field = find_union_type_field(bare_type, field_name); if (field == nullptr) { return ir_analyze_container_member_access_inner(ira, bare_type, field_name, - source_instr, container_ptr, container_type); + source_instr, container_ptr, container_ptr_src, container_type); } ZigType *field_type = resolve_union_field_type(ira->codegen, field); if (field_type == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); if (instr_is_comptime(container_ptr)) { ZigValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); if (!ptr_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { ZigValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); if (union_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (type_is_invalid(union_val->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (initializing) { ZigValue *payload_val = create_const_vals(1); @@ -20295,17 +21350,16 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ ir_add_error_node(ira, source_instr->source_node, buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), buf_ptr(actual_field->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } ZigValue *payload_val = union_val->data.x_union.payload; - IrInstruction *result; + IrInstGen *result; if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { - result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, - source_instr->source_node, container_ptr, field, true, initializing); - result->value->type = ptr_type; + result = ir_build_union_field_ptr(ira, source_instr, container_ptr, field, true, + initializing, ptr_type); result->value->special = ConstValSpecialStatic; } else { result = ir_const(ira, source_instr, ptr_type); @@ -20318,10 +21372,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ } } - IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, - source_instr->source_node, container_ptr, field, true, initializing); - result->value->type = ptr_type; - return result; + return ir_build_union_field_ptr(ira, source_instr, container_ptr, field, true, initializing, ptr_type); } zig_unreachable(); @@ -20362,16 +21413,18 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, link_lib->symbols.append(symbol_name); } -static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) { +static IrInstGen *ir_error_dependency_loop(IrAnalyze *ira, IrInst* source_instr) { ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } -static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { +static IrInstGen *ir_analyze_decl_ref(IrAnalyze *ira, IrInst* source_instruction, Tld *tld) { resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node, true); if (tld->resolution == TldResolutionInvalid) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } + if (tld->resolution == TldResolutionResolving) + return ir_error_dependency_loop(ira, source_instruction); switch (tld->id) { case TldIdContainer: @@ -20381,9 +21434,8 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ case TldIdVar: { TldVar *tld_var = (TldVar *)tld; ZigVar *var = tld_var->var; - if (var == nullptr) { - return ir_error_dependency_loop(ira, source_instruction); - } + assert(var != nullptr); + if (tld_var->extern_lib_name != nullptr) { add_link_lib_symbol(ira, tld_var->extern_lib_name, buf_create_from_str(var->name), source_instruction->source_node); @@ -20394,17 +21446,16 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_ case TldIdFn: { TldFn *tld_fn = (TldFn *)tld; ZigFn *fn_entry = tld_fn->fn_entry; - assert(fn_entry->type_entry); + assert(fn_entry->type_entry != nullptr); if (type_is_invalid(fn_entry->type_entry)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (tld_fn->extern_lib_name != nullptr) { add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); } - IrInstruction *fn_inst = ir_create_const_fn(&ira->new_irb, source_instruction->scope, - source_instruction->source_node, fn_entry); + IrInstGen *fn_inst = ir_const_fn(ira, source_instruction, fn_entry); return ir_get_ref(ira, source_instruction, fn_inst, true, false); } } @@ -20422,40 +21473,44 @@ static ErrorTableEntry *find_err_table_entry(ZigType *err_set_type, Buf *field_n return nullptr; } -static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) { +static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFieldPtr *field_ptr_instruction) { Error err; - IrInstruction *container_ptr = field_ptr_instruction->container_ptr->child; + IrInstGen *container_ptr = field_ptr_instruction->container_ptr->child; if (type_is_invalid(container_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *container_type = container_ptr->value->type->data.pointer.child_type; Buf *field_name = field_ptr_instruction->field_name_buffer; if (!field_name) { - IrInstruction *field_name_expr = field_ptr_instruction->field_name_expr->child; + IrInstGen *field_name_expr = field_ptr_instruction->field_name_expr->child; field_name = ir_resolve_str(ira, field_name_expr); if (!field_name) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - AstNode *source_node = field_ptr_instruction->base.source_node; + AstNode *source_node = field_ptr_instruction->base.base.source_node; if (type_is_invalid(container_type)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (is_tuple(container_type) && !field_ptr_instruction->initializing && buf_eql_str(field_name, "len")) { - IrInstruction *len_inst = ir_const_unsigned(ira, &field_ptr_instruction->base, + IrInstGen *len_inst = ir_const_unsigned(ira, &field_ptr_instruction->base.base, container_type->data.structure.src_field_count); - return ir_get_ref(ira, &field_ptr_instruction->base, len_inst, true, false); + return ir_get_ref(ira, &field_ptr_instruction->base.base, len_inst, true, false); } else if (is_slice(container_type) || is_container_ref(container_type)) { assert(container_ptr->value->type->id == ZigTypeIdPointer); if (container_type->id == ZigTypeIdPointer) { ZigType *bare_type = container_ref_type(container_type); - IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr, nullptr); - IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type, field_ptr_instruction->initializing); + IrInstGen *container_child = ir_get_deref(ira, &field_ptr_instruction->base.base, container_ptr, nullptr); + IrInstGen *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base.base, + container_child, &field_ptr_instruction->container_ptr->base, bare_type, + field_ptr_instruction->initializing); return result; } else { - IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type, field_ptr_instruction->initializing); + IrInstGen *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base.base, + container_ptr, &field_ptr_instruction->container_ptr->base, container_type, + field_ptr_instruction->initializing); return result; } } else if (is_array_ref(container_type) && !field_ptr_instruction->initializing) { @@ -20470,42 +21525,42 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc ZigType *usize = ira->codegen->builtin_types.entry_usize; bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, len_val, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, len_val, usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } else { ir_add_error_node(ira, source_node, buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else if (container_type->id == ZigTypeIdMetaType) { ZigValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); if (!container_ptr_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; assert(container_ptr->value->type->id == ZigTypeIdPointer); ZigValue *child_val = const_ptr_pointee(ira, ira->codegen, container_ptr_val, source_node); if (child_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, - field_ptr_instruction->base.source_node, child_val, UndefBad))) + field_ptr_instruction->base.base.source_node, child_val, UndefBad))) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *child_type = child_val->data.x_type; if (type_is_invalid(child_type)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (is_container(child_type)) { if (child_type->id == ZigTypeIdEnum) { if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; TypeEnumField *field = find_enum_type_field(child_type, field_name); if (field) { bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_enum(child_type, &field->value), child_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } @@ -20514,37 +21569,37 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc Tld *tld = find_container_decl(ira->codegen, container_scope, field_name); if (tld) { if (tld->visib_mod == VisibModPrivate && - tld->import != get_scope_import(field_ptr_instruction->base.scope)) + tld->import != get_scope_import(field_ptr_instruction->base.base.scope)) { - ErrorMsg *msg = ir_add_error(ira, &field_ptr_instruction->base, + ErrorMsg *msg = ir_add_error(ira, &field_ptr_instruction->base.base, buf_sprintf("'%s' is private", buf_ptr(field_name))); add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, tld); + return ir_analyze_decl_ref(ira, &field_ptr_instruction->base.base, tld); } if (child_type->id == ZigTypeIdUnion && (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr || child_type->data.unionation.decl_node->data.container_decl.auto_enum)) { if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; TypeUnionField *field = find_union_type_field(child_type, field_name); if (field) { ZigType *enum_type = child_type->data.unionation.tag_type; bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_enum(enum_type, &field->enum_field->value), enum_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } } const char *container_name = (child_type == ira->codegen->root_import) ? "root source file" : buf_ptr(buf_sprintf("container '%s'", buf_ptr(&child_type->name))); - ir_add_error(ira, &field_ptr_instruction->base, + ir_add_error(ira, &field_ptr_instruction->base.base, buf_sprintf("%s has no member called '%s'", container_name, buf_ptr(field_name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (child_type->id == ZigTypeIdErrorSet) { ErrorTableEntry *err_entry; ZigType *err_set_type; @@ -20554,7 +21609,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc err_entry = existing_entry->value; } else { err_entry = allocate<ErrorTableEntry>(1); - err_entry->decl_node = field_ptr_instruction->base.source_node; + err_entry->decl_node = field_ptr_instruction->base.base.source_node; buf_init_from_buf(&err_entry->name, field_name); size_t error_value_count = ira->codegen->errors_by_index.length; assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count)); @@ -20564,19 +21619,19 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc } if (err_entry->set_with_only_this_in_it == nullptr) { err_entry->set_with_only_this_in_it = make_err_set_with_one_item(ira->codegen, - field_ptr_instruction->base.scope, field_ptr_instruction->base.source_node, + field_ptr_instruction->base.base.scope, field_ptr_instruction->base.base.source_node, err_entry); } err_set_type = err_entry->set_with_only_this_in_it; } else { - if (!resolve_inferred_error_set(ira->codegen, child_type, field_ptr_instruction->base.source_node)) { - return ira->codegen->invalid_instruction; + if (!resolve_inferred_error_set(ira->codegen, child_type, field_ptr_instruction->base.base.source_node)) { + return ira->codegen->invalid_inst_gen; } err_entry = find_err_table_entry(child_type, field_name); if (err_entry == nullptr) { - ir_add_error(ira, &field_ptr_instruction->base, + ir_add_error(ira, &field_ptr_instruction->base.base, buf_sprintf("no error named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&child_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } err_set_type = child_type; } @@ -20587,13 +21642,13 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, const_val, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, const_val, err_set_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } else if (child_type->id == ZigTypeIdInt) { if (buf_eql_str(field_name, "bit_count")) { bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, child_type->data.integral.bit_count, false), ira->codegen->builtin_types.entry_num_lit_int, @@ -20601,36 +21656,36 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc } else if (buf_eql_str(field_name, "is_signed")) { bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_bool(ira->codegen, child_type->data.integral.is_signed), ira->codegen->builtin_types.entry_bool, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } else { - ir_add_error(ira, &field_ptr_instruction->base, + ir_add_error(ira, &field_ptr_instruction->base.base, buf_sprintf("type '%s' has no member called '%s'", buf_ptr(&child_type->name), buf_ptr(field_name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else if (child_type->id == ZigTypeIdFloat) { if (buf_eql_str(field_name, "bit_count")) { bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, child_type->data.floating.bit_count, false), ira->codegen->builtin_types.entry_num_lit_int, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } else { - ir_add_error(ira, &field_ptr_instruction->base, + ir_add_error(ira, &field_ptr_instruction->base.base, buf_sprintf("type '%s' has no member called '%s'", buf_ptr(&child_type->name), buf_ptr(field_name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else if (child_type->id == ZigTypeIdPointer) { if (buf_eql_str(field_name, "Child")) { bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_type(ira->codegen, child_type->data.pointer.child_type), ira->codegen->builtin_types.entry_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); @@ -20640,75 +21695,75 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc if ((err = type_resolve(ira->codegen, child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, get_ptr_align(ira->codegen, child_type), false), ira->codegen->builtin_types.entry_num_lit_int, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } else { - ir_add_error(ira, &field_ptr_instruction->base, + ir_add_error(ira, &field_ptr_instruction->base.base, buf_sprintf("type '%s' has no member called '%s'", buf_ptr(&child_type->name), buf_ptr(field_name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else if (child_type->id == ZigTypeIdArray) { if (buf_eql_str(field_name, "Child")) { bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_type(ira->codegen, child_type->data.array.child_type), ira->codegen->builtin_types.entry_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } else if (buf_eql_str(field_name, "len")) { bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, child_type->data.array.len, false), ira->codegen->builtin_types.entry_num_lit_int, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } else { - ir_add_error(ira, &field_ptr_instruction->base, + ir_add_error(ira, &field_ptr_instruction->base.base, buf_sprintf("type '%s' has no member called '%s'", buf_ptr(&child_type->name), buf_ptr(field_name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else if (child_type->id == ZigTypeIdErrorUnion) { if (buf_eql_str(field_name, "Payload")) { bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_type(ira->codegen, child_type->data.error_union.payload_type), ira->codegen->builtin_types.entry_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } else if (buf_eql_str(field_name, "ErrorSet")) { bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_type(ira->codegen, child_type->data.error_union.err_set_type), ira->codegen->builtin_types.entry_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } else { - ir_add_error(ira, &field_ptr_instruction->base, + ir_add_error(ira, &field_ptr_instruction->base.base, buf_sprintf("type '%s' has no member called '%s'", buf_ptr(&child_type->name), buf_ptr(field_name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else if (child_type->id == ZigTypeIdOptional) { if (buf_eql_str(field_name, "Child")) { bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_type(ira->codegen, child_type->data.maybe.child_type), ira->codegen->builtin_types.entry_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } else { - ir_add_error(ira, &field_ptr_instruction->base, + ir_add_error(ira, &field_ptr_instruction->base.base, buf_sprintf("type '%s' has no member called '%s'", buf_ptr(&child_type->name), buf_ptr(field_name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else if (child_type->id == ZigTypeIdFn) { if (buf_eql_str(field_name, "ReturnType")) { @@ -20716,121 +21771,121 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc // Return type can only ever be null, if the function is generic assert(child_type->data.fn.is_generic); - ir_add_error(ira, &field_ptr_instruction->base, + ir_add_error(ira, &field_ptr_instruction->base.base, buf_sprintf("ReturnType has not been resolved because '%s' is generic", buf_ptr(&child_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_type(ira->codegen, child_type->data.fn.fn_type_id.return_type), ira->codegen->builtin_types.entry_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } else if (buf_eql_str(field_name, "is_var_args")) { bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_bool(ira->codegen, child_type->data.fn.fn_type_id.is_var_args), ira->codegen->builtin_types.entry_bool, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } else if (buf_eql_str(field_name, "arg_count")) { bool ptr_is_const = true; bool ptr_is_volatile = false; - return ir_get_const_ptr(ira, &field_ptr_instruction->base, + return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, create_const_usize(ira->codegen, child_type->data.fn.fn_type_id.param_count), ira->codegen->builtin_types.entry_usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); } else { - ir_add_error(ira, &field_ptr_instruction->base, + ir_add_error(ira, &field_ptr_instruction->base.base, buf_sprintf("type '%s' has no member called '%s'", buf_ptr(&child_type->name), buf_ptr(field_name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else { - ir_add_error(ira, &field_ptr_instruction->base, + ir_add_error(ira, &field_ptr_instruction->base.base, buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else if (field_ptr_instruction->initializing) { - ir_add_error(ira, &field_ptr_instruction->base, + ir_add_error(ira, &field_ptr_instruction->base.base, buf_sprintf("type '%s' does not support struct initialization syntax", buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { - ir_add_error_node(ira, field_ptr_instruction->base.source_node, + ir_add_error_node(ira, field_ptr_instruction->base.base.source_node, buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } -static IrInstruction *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstructionStorePtr *instruction) { - IrInstruction *ptr = instruction->ptr->child; +static IrInstGen *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstSrcStorePtr *instruction) { + IrInstGen *ptr = instruction->ptr->child; if (type_is_invalid(ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *value = instruction->value->child; + IrInstGen *value = instruction->value->child; if (type_is_invalid(value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_store_ptr(ira, &instruction->base, ptr, value, instruction->allow_write_through_const); + return ir_analyze_store_ptr(ira, &instruction->base.base, ptr, value, instruction->allow_write_through_const); } -static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *instruction) { - IrInstruction *ptr = instruction->ptr->child; +static IrInstGen *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstSrcLoadPtr *instruction) { + IrInstGen *ptr = instruction->ptr->child; if (type_is_invalid(ptr->value->type)) - return ira->codegen->invalid_instruction; - return ir_get_deref(ira, &instruction->base, ptr, nullptr); + return ira->codegen->invalid_inst_gen; + return ir_get_deref(ira, &instruction->base.base, ptr, nullptr); } -static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) { - IrInstruction *expr_value = typeof_instruction->value->child; +static IrInstGen *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstSrcTypeOf *typeof_instruction) { + IrInstGen *expr_value = typeof_instruction->value->child; ZigType *type_entry = expr_value->value->type; if (type_is_invalid(type_entry)) - return ira->codegen->invalid_instruction; - return ir_const_type(ira, &typeof_instruction->base, type_entry); + return ira->codegen->invalid_inst_gen; + return ir_const_type(ira, &typeof_instruction->base.base, type_entry); } -static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) { +static IrInstGen *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstSrcSetCold *instruction) { if (ira->new_irb.exec->is_inline) { // ignore setCold when running functions at compile time - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } - IrInstruction *is_cold_value = instruction->is_cold->child; + IrInstGen *is_cold_value = instruction->is_cold->child; bool want_cold; if (!ir_resolve_bool(ira, is_cold_value, &want_cold)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - ZigFn *fn_entry = scope_fn_entry(instruction->base.scope); + ZigFn *fn_entry = scope_fn_entry(instruction->base.base.scope); if (fn_entry == nullptr) { - ir_add_error(ira, &instruction->base, buf_sprintf("@setCold outside function")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("@setCold outside function")); + return ira->codegen->invalid_inst_gen; } if (fn_entry->set_cold_node != nullptr) { - ErrorMsg *msg = ir_add_error(ira, &instruction->base, buf_sprintf("cold set twice in same function")); + ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, buf_sprintf("cold set twice in same function")); add_error_note(ira->codegen, msg, fn_entry->set_cold_node, buf_sprintf("first set here")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - fn_entry->set_cold_node = instruction->base.source_node; + fn_entry->set_cold_node = instruction->base.base.source_node; fn_entry->is_cold = want_cold; - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira, - IrInstructionSetRuntimeSafety *set_runtime_safety_instruction) +static IrInstGen *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira, + IrInstSrcSetRuntimeSafety *set_runtime_safety_instruction) { if (ira->new_irb.exec->is_inline) { // ignore setRuntimeSafety when running functions at compile time - return ir_const_void(ira, &set_runtime_safety_instruction->base); + return ir_const_void(ira, &set_runtime_safety_instruction->base.base); } bool *safety_off_ptr; AstNode **safety_set_node_ptr; - Scope *scope = set_runtime_safety_instruction->base.scope; + Scope *scope = set_runtime_safety_instruction->base.base.scope; while (scope != nullptr) { if (scope->id == ScopeIdBlock) { ScopeBlock *block_scope = (ScopeBlock *)scope; @@ -20856,36 +21911,36 @@ static IrInstruction *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira, } assert(scope != nullptr); - IrInstruction *safety_on_value = set_runtime_safety_instruction->safety_on->child; + IrInstGen *safety_on_value = set_runtime_safety_instruction->safety_on->child; bool want_runtime_safety; if (!ir_resolve_bool(ira, safety_on_value, &want_runtime_safety)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - AstNode *source_node = set_runtime_safety_instruction->base.source_node; + AstNode *source_node = set_runtime_safety_instruction->base.base.source_node; if (*safety_set_node_ptr) { ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("runtime safety set twice for same scope")); add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } *safety_set_node_ptr = source_node; *safety_off_ptr = !want_runtime_safety; - return ir_const_void(ira, &set_runtime_safety_instruction->base); + return ir_const_void(ira, &set_runtime_safety_instruction->base.base); } -static IrInstruction *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, - IrInstructionSetFloatMode *instruction) +static IrInstGen *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, + IrInstSrcSetFloatMode *instruction) { if (ira->new_irb.exec->is_inline) { // ignore setFloatMode when running functions at compile time - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } bool *fast_math_on_ptr; AstNode **fast_math_set_node_ptr; - Scope *scope = instruction->base.scope; + Scope *scope = instruction->base.base.scope; while (scope != nullptr) { if (scope->id == ScopeIdBlock) { ScopeBlock *block_scope = (ScopeBlock *)scope; @@ -20911,42 +21966,38 @@ static IrInstruction *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, } assert(scope != nullptr); - IrInstruction *float_mode_value = instruction->mode_value->child; + IrInstGen *float_mode_value = instruction->mode_value->child; FloatMode float_mode_scalar; if (!ir_resolve_float_mode(ira, float_mode_value, &float_mode_scalar)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - AstNode *source_node = instruction->base.source_node; + AstNode *source_node = instruction->base.base.source_node; if (*fast_math_set_node_ptr) { ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("float mode set twice for same scope")); add_error_note(ira->codegen, msg, *fast_math_set_node_ptr, buf_sprintf("first set here")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } *fast_math_set_node_ptr = source_node; *fast_math_on_ptr = (float_mode_scalar == FloatModeOptimized); - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_any_frame_type(IrAnalyze *ira, - IrInstructionAnyFrameType *instruction) -{ +static IrInstGen *ir_analyze_instruction_any_frame_type(IrAnalyze *ira, IrInstSrcAnyFrameType *instruction) { ZigType *payload_type = nullptr; if (instruction->payload_type != nullptr) { payload_type = ir_resolve_type(ira, instruction->payload_type->child); if (type_is_invalid(payload_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *any_frame_type = get_any_frame_type(ira->codegen, payload_type); - return ir_const_type(ira, &instruction->base, any_frame_type); + return ir_const_type(ira, &instruction->base.base, any_frame_type); } -static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, - IrInstructionSliceType *slice_type_instruction) -{ - IrInstruction *result = ir_const(ira, &slice_type_instruction->base, ira->codegen->builtin_types.entry_type); +static IrInstGen *ir_analyze_instruction_slice_type(IrAnalyze *ira, IrInstSrcSliceType *slice_type_instruction) { + IrInstGen *result = ir_const(ira, &slice_type_instruction->base.base, ira->codegen->builtin_types.entry_type); result->value->special = ConstValSpecialLazy; LazyValueSliceType *lazy_slice_type = allocate<LazyValueSliceType>(1, "LazyValueSliceType"); @@ -20957,18 +22008,18 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, if (slice_type_instruction->align_value != nullptr) { lazy_slice_type->align_inst = slice_type_instruction->align_value->child; if (ir_resolve_const(ira, lazy_slice_type->align_inst, LazyOk) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (slice_type_instruction->sentinel != nullptr) { lazy_slice_type->sentinel = slice_type_instruction->sentinel->child; if (ir_resolve_const(ira, lazy_slice_type->sentinel, LazyOk) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } lazy_slice_type->elem_type = slice_type_instruction->child_type->child; if (ir_resolve_type_lazy(ira, lazy_slice_type->elem_type) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; lazy_slice_type->is_const = slice_type_instruction->is_const; lazy_slice_type->is_volatile = slice_type_instruction->is_volatile; @@ -20977,31 +22028,31 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, return result; } -static IrInstruction *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAsmSrc *asm_instruction) { +static IrInstGen *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstSrcAsm *asm_instruction) { Error err; - assert(asm_instruction->base.source_node->type == NodeTypeAsmExpr); + assert(asm_instruction->base.base.source_node->type == NodeTypeAsmExpr); - AstNode *node = asm_instruction->base.source_node; - AstNodeAsmExpr *asm_expr = &asm_instruction->base.source_node->data.asm_expr; + AstNode *node = asm_instruction->base.base.source_node; + AstNodeAsmExpr *asm_expr = &asm_instruction->base.base.source_node->data.asm_expr; Buf *template_buf = ir_resolve_str(ira, asm_instruction->asm_template->child); if (template_buf == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (asm_instruction->is_global) { buf_append_char(&ira->codegen->global_asm, '\n'); buf_append_buf(&ira->codegen->global_asm, template_buf); - return ir_const_void(ira, &asm_instruction->base); + return ir_const_void(ira, &asm_instruction->base.base); } - if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base)) - return ira->codegen->invalid_instruction; + if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base.base)) + return ira->codegen->invalid_inst_gen; ZigList<AsmToken> tok_list = {}; if ((err = parse_asm_template(ira, node, template_buf, &tok_list))) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } for (size_t token_i = 0; token_i < tok_list.length; token_i += 1) { @@ -21015,15 +22066,15 @@ static IrInstruction *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAs add_node_error(ira->codegen, node, buf_sprintf("could not find '%.*s' in the inputs or outputs", len, ptr)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } } // TODO validate the output types and variable types - IrInstruction **input_list = allocate<IrInstruction *>(asm_expr->input_list.length); - IrInstruction **output_types = allocate<IrInstruction *>(asm_expr->output_list.length); + IrInstGen **input_list = allocate<IrInstGen *>(asm_expr->input_list.length); + IrInstGen **output_types = allocate<IrInstGen *>(asm_expr->output_list.length); ZigType *return_type = ira->codegen->builtin_types.entry_void; for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { @@ -21032,39 +22083,34 @@ static IrInstruction *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAs output_types[i] = asm_instruction->output_types[i]->child; return_type = ir_resolve_type(ira, output_types[i]); if (type_is_invalid(return_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { - IrInstruction *const input_value = asm_instruction->input_list[i]->child; + IrInstGen *const input_value = asm_instruction->input_list[i]->child; if (type_is_invalid(input_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (instr_is_comptime(input_value) && (input_value->value->type->id == ZigTypeIdComptimeInt || input_value->value->type->id == ZigTypeIdComptimeFloat)) { - ir_add_error_node(ira, input_value->source_node, + ir_add_error(ira, &input_value->base, buf_sprintf("expected sized integer or sized float, found %s", buf_ptr(&input_value->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } input_list[i] = input_value; } - IrInstruction *result = ir_build_asm_gen(ira, - asm_instruction->base.scope, asm_instruction->base.source_node, + return ir_build_asm_gen(ira, &asm_instruction->base.base, template_buf, tok_list.items, tok_list.length, input_list, output_types, asm_instruction->output_vars, asm_instruction->return_count, - asm_instruction->has_side_effects); - result->value->type = return_type; - return result; + asm_instruction->has_side_effects, return_type); } -static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, - IrInstructionArrayType *array_type_instruction) -{ - IrInstruction *result = ir_const(ira, &array_type_instruction->base, ira->codegen->builtin_types.entry_type); +static IrInstGen *ir_analyze_instruction_array_type(IrAnalyze *ira, IrInstSrcArrayType *array_type_instruction) { + IrInstGen *result = ir_const(ira, &array_type_instruction->base.base, ira->codegen->builtin_types.entry_type); result->value->special = ConstValSpecialLazy; LazyValueArrayType *lazy_array_type = allocate<LazyValueArrayType>(1, "LazyValueArrayType"); @@ -21074,22 +22120,22 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, lazy_array_type->elem_type = array_type_instruction->child_type->child; if (ir_resolve_type_lazy(ira, lazy_array_type->elem_type) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!ir_resolve_usize(ira, array_type_instruction->size->child, &lazy_array_type->length)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (array_type_instruction->sentinel != nullptr) { lazy_array_type->sentinel = array_type_instruction->sentinel->child; if (ir_resolve_const(ira, lazy_array_type->sentinel, LazyOk) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return result; } -static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstructionSizeOf *instruction) { - IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); +static IrInstGen *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstSrcSizeOf *instruction) { + IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); result->value->special = ConstValSpecialLazy; LazyValueSizeOf *lazy_size_of = allocate<LazyValueSizeOf>(1, "LazyValueSizeOf"); @@ -21100,19 +22146,19 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstructi lazy_size_of->target_type = instruction->type_value->child; if (ir_resolve_type_lazy(ira, lazy_size_of->target_type) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return result; } -static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) { +static IrInstGen *ir_analyze_test_non_null(IrAnalyze *ira, IrInst *source_inst, IrInstGen *value) { ZigType *type_entry = value->value->type; if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.allow_zero) { if (instr_is_comptime(value)) { ZigValue *c_ptr_val = ir_resolve_const(ira, value, UndefOk); if (c_ptr_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (c_ptr_val->special == ConstValSpecialUndef) return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || @@ -21121,25 +22167,19 @@ static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *so return ir_const_bool(ira, source_inst, !is_null); } - IrInstruction *result = ir_build_test_nonnull(&ira->new_irb, - source_inst->scope, source_inst->source_node, value); - result->value->type = ira->codegen->builtin_types.entry_bool; - return result; + return ir_build_test_non_null_gen(ira, source_inst, value); } else if (type_entry->id == ZigTypeIdOptional) { if (instr_is_comptime(value)) { ZigValue *maybe_val = ir_resolve_const(ira, value, UndefOk); if (maybe_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (maybe_val->special == ConstValSpecialUndef) return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); return ir_const_bool(ira, source_inst, !optional_value_is_null(maybe_val)); } - IrInstruction *result = ir_build_test_nonnull(&ira->new_irb, - source_inst->scope, source_inst->source_node, value); - result->value->type = ira->codegen->builtin_types.entry_bool; - return result; + return ir_build_test_non_null_gen(ira, source_inst, value); } else if (type_entry->id == ZigTypeIdNull) { return ir_const_bool(ira, source_inst, false); } else { @@ -21147,51 +22187,53 @@ static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *so } } -static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrInstructionTestNonNull *instruction) { - IrInstruction *value = instruction->value->child; +static IrInstGen *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrInstSrcTestNonNull *instruction) { + IrInstGen *value = instruction->value->child; if (type_is_invalid(value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_test_non_null(ira, &instruction->base, value); + return ir_analyze_test_non_null(ira, &instruction->base.base, value); } -static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *base_ptr, bool safety_check_on, bool initializing) +static IrInstGen *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *base_ptr, bool safety_check_on, bool initializing) { + Error err; + ZigType *type_entry = get_ptr_elem_type(ira->codegen, base_ptr); if (type_is_invalid(type_entry)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.ptr_len == PtrLenC) { if (instr_is_comptime(base_ptr)) { ZigValue *val = ir_resolve_const(ira, base_ptr, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { ZigValue *c_ptr_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); if (c_ptr_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); if (is_null) { ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return base_ptr; } } if (!safety_check_on) return base_ptr; - IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr); + IrInstGen *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr); ir_build_assert_non_null(ira, source_instr, c_ptr_val); return base_ptr; } if (type_entry->id != ZigTypeIdOptional) { - ir_add_error_node(ira, base_ptr->source_node, + ir_add_error(ira, &base_ptr->base, buf_sprintf("expected optional type, found '%s'", buf_ptr(&type_entry->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *child_type = type_entry->data.maybe.child_type; @@ -21203,17 +22245,17 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr if (instr_is_comptime(base_ptr)) { ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); - if (!ptr_val) - return ira->codegen->invalid_instruction; + if (ptr_val == nullptr) + return ira->codegen->invalid_inst_gen; if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { ZigValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); if (optional_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (initializing) { switch (type_has_one_possible_value(ira->codegen, child_type)) { case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueNo: if (!same_comptime_repr) { ZigValue *payload_val = create_const_vals(1); @@ -21227,27 +22269,25 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr } break; case OnePossibleValueYes: { - ZigValue *pointee = create_const_vals(1); - pointee->special = ConstValSpecialStatic; - pointee->type = child_type; - pointee->parent.id = ConstParentIdOptionalPayload; - pointee->parent.data.p_optional_payload.optional_val = optional_val; - optional_val->special = ConstValSpecialStatic; - optional_val->data.x_optional = pointee; + optional_val->data.x_optional = get_the_one_possible_value(ira->codegen, child_type); break; } } - } else if (optional_value_is_null(optional_val)) { - ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); - return ira->codegen->invalid_instruction; + } else { + if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, + source_instr->source_node, optional_val, UndefBad))) + return ira->codegen->invalid_inst_gen; + if (optional_value_is_null(optional_val)) { + ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); + return ira->codegen->invalid_inst_gen; + } } - IrInstruction *result; + IrInstGen *result; if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { - result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, - source_instr->source_node, base_ptr, false, initializing); - result->value->type = result_type; + result = ir_build_optional_unwrap_ptr_gen(ira, source_instr, base_ptr, false, + initializing, result_type); result->value->special = ConstValSpecialStatic; } else { result = ir_const(ira, source_instr, result_type); @@ -21257,7 +22297,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; switch (type_has_one_possible_value(ira->codegen, child_type)) { case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueNo: if (same_comptime_repr) { result_val->data.x_ptr.data.ref.pointee = optional_val; @@ -21275,131 +22315,120 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr } } - IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, - source_instr->source_node, base_ptr, safety_check_on, initializing); - result->value->type = result_type; - return result; + return ir_build_optional_unwrap_ptr_gen(ira, source_instr, base_ptr, safety_check_on, + initializing, result_type); } -static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, - IrInstructionOptionalUnwrapPtr *instruction) +static IrInstGen *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, + IrInstSrcOptionalUnwrapPtr *instruction) { - IrInstruction *base_ptr = instruction->base_ptr->child; + IrInstGen *base_ptr = instruction->base_ptr->child; if (type_is_invalid(base_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, + return ir_analyze_unwrap_optional_payload(ira, &instruction->base.base, base_ptr, instruction->safety_check_on, false); } -static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) { +static IrInstGen *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstSrcCtz *instruction) { ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); if (type_is_invalid(int_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type); + IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); if (type_is_invalid(op->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (int_type->data.integral.bit_count == 0) - return ir_const_unsigned(ira, &instruction->base, 0); + return ir_const_unsigned(ira, &instruction->base.base, 0); if (instr_is_comptime(op)) { ZigValue *val = ir_resolve_const(ira, op, UndefOk); if (val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (val->special == ConstValSpecialUndef) - return ir_const_undef(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); + return ir_const_undef(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); size_t result_usize = bigint_ctz(&op->value->data.x_bigint, int_type->data.integral.bit_count); - return ir_const_unsigned(ira, &instruction->base, result_usize); + return ir_const_unsigned(ira, &instruction->base.base, result_usize); } ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); - IrInstruction *result = ir_build_ctz(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, nullptr, op); - result->value->type = return_type; - return result; + return ir_build_ctz_gen(ira, &instruction->base.base, return_type, op); } -static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *instruction) { +static IrInstGen *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstSrcClz *instruction) { ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); if (type_is_invalid(int_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type); + IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); if (type_is_invalid(op->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (int_type->data.integral.bit_count == 0) - return ir_const_unsigned(ira, &instruction->base, 0); + return ir_const_unsigned(ira, &instruction->base.base, 0); if (instr_is_comptime(op)) { ZigValue *val = ir_resolve_const(ira, op, UndefOk); if (val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (val->special == ConstValSpecialUndef) - return ir_const_undef(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); + return ir_const_undef(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); size_t result_usize = bigint_clz(&op->value->data.x_bigint, int_type->data.integral.bit_count); - return ir_const_unsigned(ira, &instruction->base, result_usize); + return ir_const_unsigned(ira, &instruction->base.base, result_usize); } ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); - IrInstruction *result = ir_build_clz(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, nullptr, op); - result->value->type = return_type; - return result; + return ir_build_clz_gen(ira, &instruction->base.base, return_type, op); } -static IrInstruction *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) { +static IrInstGen *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstSrcPopCount *instruction) { ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); if (type_is_invalid(int_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type); + IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); if (type_is_invalid(op->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (int_type->data.integral.bit_count == 0) - return ir_const_unsigned(ira, &instruction->base, 0); + return ir_const_unsigned(ira, &instruction->base.base, 0); if (instr_is_comptime(op)) { ZigValue *val = ir_resolve_const(ira, op, UndefOk); if (val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (val->special == ConstValSpecialUndef) - return ir_const_undef(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); + return ir_const_undef(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { size_t result = bigint_popcount_unsigned(&val->data.x_bigint); - return ir_const_unsigned(ira, &instruction->base, result); + return ir_const_unsigned(ira, &instruction->base.base, result); } size_t result = bigint_popcount_signed(&val->data.x_bigint, int_type->data.integral.bit_count); - return ir_const_unsigned(ira, &instruction->base, result); + return ir_const_unsigned(ira, &instruction->base.base, result); } ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); - IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, nullptr, op); - result->value->type = return_type; - return result; + return ir_build_pop_count_gen(ira, &instruction->base.base, return_type, op); } -static IrInstruction *ir_analyze_union_tag(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value) { +static IrInstGen *ir_analyze_union_tag(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, bool is_gen) { if (type_is_invalid(value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (value->value->type->id != ZigTypeIdUnion) { - ir_add_error(ira, value, + ir_add_error(ira, &value->base, buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - if (!value->value->type->data.unionation.have_explicit_tag_type && !source_instr->is_gen) { + if (!value->value->type->data.unionation.have_explicit_tag_type && !is_gen) { ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum")); if (value->value->type->data.unionation.decl_node != nullptr) { add_error_note(ira->codegen, msg, value->value->type->data.unionation.decl_node, buf_sprintf("declared here")); } - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *tag_type = value->value->type->data.unionation.tag_type; @@ -21408,9 +22437,9 @@ static IrInstruction *ir_analyze_union_tag(IrAnalyze *ira, IrInstruction *source if (instr_is_comptime(value)) { ZigValue *val = ir_resolve_const(ira, value, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, + IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, source_instr->scope, source_instr->source_node); const_instruction->base.value->type = tag_type; const_instruction->base.value->special = ConstValSpecialStatic; @@ -21418,15 +22447,13 @@ static IrInstruction *ir_analyze_union_tag(IrAnalyze *ira, IrInstruction *source return &const_instruction->base; } - IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope, source_instr->source_node, value); - result->value->type = tag_type; - return result; + return ir_build_union_tag(ira, source_instr, value, tag_type); } -static IrInstruction *ir_analyze_instruction_switch_br(IrAnalyze *ira, - IrInstructionSwitchBr *switch_br_instruction) +static IrInstGen *ir_analyze_instruction_switch_br(IrAnalyze *ira, + IrInstSrcSwitchBr *switch_br_instruction) { - IrInstruction *target_value = switch_br_instruction->target_value->child; + IrInstGen *target_value = switch_br_instruction->target_value->child; if (type_is_invalid(target_value->value->type)) return ir_unreach_error(ira); @@ -21441,21 +22468,21 @@ static IrInstruction *ir_analyze_instruction_switch_br(IrAnalyze *ira, bool is_comptime; if (!ir_resolve_comptime(ira, switch_br_instruction->is_comptime->child, &is_comptime)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (is_comptime || instr_is_comptime(target_value)) { ZigValue *target_val = ir_resolve_const(ira, target_value, UndefBad); if (!target_val) return ir_unreach_error(ira); - IrBasicBlock *old_dest_block = switch_br_instruction->else_block; + IrBasicBlockSrc *old_dest_block = switch_br_instruction->else_block; for (size_t i = 0; i < case_count; i += 1) { - IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; - IrInstruction *case_value = old_case->value->child; + IrInstSrcSwitchBrCase *old_case = &switch_br_instruction->cases[i]; + IrInstGen *case_value = old_case->value->child; if (type_is_invalid(case_value->value->type)) return ir_unreach_error(ira); - IrInstruction *casted_case_value = ir_implicit_cast(ira, case_value, target_value->value->type); + IrInstGen *casted_case_value = ir_implicit_cast(ira, case_value, target_value->value->type); if (type_is_invalid(casted_case_value->value->type)) return ir_unreach_error(ira); @@ -21470,23 +22497,20 @@ static IrInstruction *ir_analyze_instruction_switch_br(IrAnalyze *ira, } if (is_comptime || old_dest_block->ref_count == 1) { - return ir_inline_bb(ira, &switch_br_instruction->base, old_dest_block); + return ir_inline_bb(ira, &switch_br_instruction->base.base, old_dest_block); } else { - IrBasicBlock *new_dest_block = ir_get_new_bb(ira, old_dest_block, &switch_br_instruction->base); - IrInstruction *result = ir_build_br(&ira->new_irb, - switch_br_instruction->base.scope, switch_br_instruction->base.source_node, - new_dest_block, nullptr); - result->value->type = ira->codegen->builtin_types.entry_unreachable; + IrBasicBlockGen *new_dest_block = ir_get_new_bb(ira, old_dest_block, &switch_br_instruction->base.base); + IrInstGen *result = ir_build_br_gen(ira, &switch_br_instruction->base.base, new_dest_block); return ir_finish_anal(ira, result); } } - IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(case_count); + IrInstGenSwitchBrCase *cases = allocate<IrInstGenSwitchBrCase>(case_count); for (size_t i = 0; i < case_count; i += 1) { - IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; - IrInstructionSwitchBrCase *new_case = &cases[i]; - new_case->block = ir_get_new_bb(ira, old_case->block, &switch_br_instruction->base); - new_case->value = ira->codegen->invalid_instruction; + IrInstSrcSwitchBrCase *old_case = &switch_br_instruction->cases[i]; + IrInstGenSwitchBrCase *new_case = &cases[i]; + new_case->block = ir_get_new_bb(ira, old_case->block, &switch_br_instruction->base.base); + new_case->value = ira->codegen->invalid_inst_gen; // Calling ir_get_new_bb set the ref_instruction on the new basic block. // However a switch br may branch to the same basic block which would trigger an @@ -21494,12 +22518,12 @@ static IrInstruction *ir_analyze_instruction_switch_br(IrAnalyze *ira, // it back after the loop. new_case->block->ref_instruction = nullptr; - IrInstruction *old_value = old_case->value; - IrInstruction *new_value = old_value->child; + IrInstSrc *old_value = old_case->value; + IrInstGen *new_value = old_value->child; if (type_is_invalid(new_value->value->type)) continue; - IrInstruction *casted_new_value = ir_implicit_cast(ira, new_value, target_value->value->type); + IrInstGen *casted_new_value = ir_implicit_cast(ira, new_value, target_value->value->type); if (type_is_invalid(casted_new_value->value->type)) continue; @@ -21510,47 +22534,45 @@ static IrInstruction *ir_analyze_instruction_switch_br(IrAnalyze *ira, } for (size_t i = 0; i < case_count; i += 1) { - IrInstructionSwitchBrCase *new_case = &cases[i]; - if (new_case->value == ira->codegen->invalid_instruction) + IrInstGenSwitchBrCase *new_case = &cases[i]; + if (type_is_invalid(new_case->value->value->type)) return ir_unreach_error(ira); - new_case->block->ref_instruction = &switch_br_instruction->base; + new_case->block->ref_instruction = &switch_br_instruction->base.base; } - IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base); - IrInstructionSwitchBr *switch_br = ir_build_switch_br(&ira->new_irb, - switch_br_instruction->base.scope, switch_br_instruction->base.source_node, - target_value, new_else_block, case_count, cases, nullptr, nullptr); - switch_br->base.value->type = ira->codegen->builtin_types.entry_unreachable; + IrBasicBlockGen *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base.base); + IrInstGenSwitchBr *switch_br = ir_build_switch_br_gen(ira, &switch_br_instruction->base.base, + target_value, new_else_block, case_count, cases); return ir_finish_anal(ira, &switch_br->base); } -static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, - IrInstructionSwitchTarget *switch_target_instruction) +static IrInstGen *ir_analyze_instruction_switch_target(IrAnalyze *ira, + IrInstSrcSwitchTarget *switch_target_instruction) { Error err; - IrInstruction *target_value_ptr = switch_target_instruction->target_value_ptr->child; + IrInstGen *target_value_ptr = switch_target_instruction->target_value_ptr->child; if (type_is_invalid(target_value_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (target_value_ptr->value->type->id == ZigTypeIdMetaType) { assert(instr_is_comptime(target_value_ptr)); ZigType *ptr_type = target_value_ptr->value->data.x_type; assert(ptr_type->id == ZigTypeIdPointer); - return ir_const_type(ira, &switch_target_instruction->base, ptr_type->data.pointer.child_type); + return ir_const_type(ira, &switch_target_instruction->base.base, ptr_type->data.pointer.child_type); } ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; ZigValue *pointee_val = nullptr; if (instr_is_comptime(target_value_ptr) && target_value_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { - pointee_val = const_ptr_pointee(ira, ira->codegen, target_value_ptr->value, target_value_ptr->source_node); + pointee_val = const_ptr_pointee(ira, ira->codegen, target_value_ptr->value, target_value_ptr->base.source_node); if (pointee_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (pointee_val->special == ConstValSpecialRuntime) pointee_val = nullptr; } if ((err = type_resolve(ira->codegen, target_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; switch (target_type->id) { case ZigTypeIdInvalid: @@ -21567,13 +22589,13 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, case ZigTypeIdFn: case ZigTypeIdErrorSet: { if (pointee_val) { - IrInstruction *result = ir_const(ira, &switch_target_instruction->base, nullptr); + IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, nullptr); copy_const_val(result->value, pointee_val); result->value->type = target_type; return result; } - IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); + IrInstGen *result = ir_get_deref(ira, &switch_target_instruction->base.base, target_value_ptr, nullptr); result->value->type = target_type; return result; } @@ -21582,52 +22604,49 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, if (!decl_node->data.container_decl.auto_enum && decl_node->data.container_decl.init_arg_expr == nullptr) { - ErrorMsg *msg = ir_add_error(ira, target_value_ptr, + ErrorMsg *msg = ir_add_error(ira, &target_value_ptr->base, buf_sprintf("switch on union which has no attached enum")); add_error_note(ira->codegen, msg, decl_node, buf_sprintf("consider 'union(enum)' here")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *tag_type = target_type->data.unionation.tag_type; assert(tag_type != nullptr); assert(tag_type->id == ZigTypeIdEnum); if (pointee_val) { - IrInstruction *result = ir_const(ira, &switch_target_instruction->base, tag_type); + IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, tag_type); bigint_init_bigint(&result->value->data.x_enum_tag, &pointee_val->data.x_union.tag); return result; } if (tag_type->data.enumeration.src_field_count == 1) { - IrInstruction *result = ir_const(ira, &switch_target_instruction->base, tag_type); + IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, tag_type); TypeEnumField *only_field = &tag_type->data.enumeration.fields[0]; bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value); return result; } - IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); + IrInstGen *union_value = ir_get_deref(ira, &switch_target_instruction->base.base, target_value_ptr, nullptr); union_value->value->type = target_type; - IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope, - switch_target_instruction->base.source_node, union_value); - union_tag_inst->value->type = tag_type; - return union_tag_inst; + return ir_build_union_tag(ira, &switch_target_instruction->base.base, union_value, tag_type); } case ZigTypeIdEnum: { if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (target_type->data.enumeration.src_field_count == 1) { TypeEnumField *only_field = &target_type->data.enumeration.fields[0]; - IrInstruction *result = ir_const(ira, &switch_target_instruction->base, target_type); + IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, target_type); bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value); return result; } if (pointee_val) { - IrInstruction *result = ir_const(ira, &switch_target_instruction->base, target_type); + IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, target_type); bigint_init_bigint(&result->value->data.x_enum_tag, &pointee_val->data.x_enum_tag); return result; } - IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr); + IrInstGen *enum_value = ir_get_deref(ira, &switch_target_instruction->base.base, target_value_ptr, nullptr); enum_value->value->type = target_type; return enum_value; } @@ -21643,17 +22662,17 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, case ZigTypeIdVector: case ZigTypeIdFnFrame: case ZigTypeIdAnyFrame: - ir_add_error(ira, &switch_target_instruction->base, + ir_add_error(ira, &switch_target_instruction->base.base, buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } zig_unreachable(); } -static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstructionSwitchVar *instruction) { - IrInstruction *target_value_ptr = instruction->target_value_ptr->child; +static IrInstGen *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstSrcSwitchVar *instruction) { + IrInstGen *target_value_ptr = instruction->target_value_ptr->child; if (type_is_invalid(target_value_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *ref_type = target_value_ptr->value->type; assert(ref_type->id == ZigTypeIdPointer); @@ -21664,62 +22683,62 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru assert(enum_type->id == ZigTypeIdEnum); assert(instruction->prongs_len > 0); - IrInstruction *first_prong_value = instruction->prongs_ptr[0]->child; + IrInstGen *first_prong_value = instruction->prongs_ptr[0]->child; if (type_is_invalid(first_prong_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *first_casted_prong_value = ir_implicit_cast(ira, first_prong_value, enum_type); + IrInstGen *first_casted_prong_value = ir_implicit_cast(ira, first_prong_value, enum_type); if (type_is_invalid(first_casted_prong_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *first_prong_val = ir_resolve_const(ira, first_casted_prong_value, UndefBad); if (first_prong_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; TypeUnionField *first_field = find_union_field_by_tag(target_type, &first_prong_val->data.x_enum_tag); ErrorMsg *invalid_payload_msg = nullptr; for (size_t prong_i = 1; prong_i < instruction->prongs_len; prong_i += 1) { - IrInstruction *this_prong_inst = instruction->prongs_ptr[prong_i]->child; + IrInstGen *this_prong_inst = instruction->prongs_ptr[prong_i]->child; if (type_is_invalid(this_prong_inst->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *this_casted_prong_value = ir_implicit_cast(ira, this_prong_inst, enum_type); + IrInstGen *this_casted_prong_value = ir_implicit_cast(ira, this_prong_inst, enum_type); if (type_is_invalid(this_casted_prong_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *this_prong = ir_resolve_const(ira, this_casted_prong_value, UndefBad); if (this_prong == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; TypeUnionField *payload_field = find_union_field_by_tag(target_type, &this_prong->data.x_enum_tag); ZigType *payload_type = payload_field->type_entry; if (first_field->type_entry != payload_type) { if (invalid_payload_msg == nullptr) { - invalid_payload_msg = ir_add_error(ira, &instruction->base, + invalid_payload_msg = ir_add_error(ira, &instruction->base.base, buf_sprintf("capture group with incompatible types")); - add_error_note(ira->codegen, invalid_payload_msg, first_prong_value->source_node, + add_error_note(ira->codegen, invalid_payload_msg, first_prong_value->base.source_node, buf_sprintf("type '%s' here", buf_ptr(&first_field->type_entry->name))); } - add_error_note(ira->codegen, invalid_payload_msg, this_prong_inst->source_node, + add_error_note(ira->codegen, invalid_payload_msg, this_prong_inst->base.source_node, buf_sprintf("type '%s' here", buf_ptr(&payload_field->type_entry->name))); } } if (invalid_payload_msg != nullptr) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(target_value_ptr)) { ZigValue *target_val_ptr = ir_resolve_const(ira, target_value_ptr, UndefBad); if (!target_value_ptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - ZigValue *pointee_val = const_ptr_pointee(ira, ira->codegen, target_val_ptr, instruction->base.source_node); + ZigValue *pointee_val = const_ptr_pointee(ira, ira->codegen, target_val_ptr, instruction->base.base.source_node); if (pointee_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result = ir_const(ira, &instruction->base, + IrInstGen *result = ir_const(ira, &instruction->base.base, get_pointer_to_type(ira->codegen, first_field->type_entry, target_val_ptr->type->data.pointer.is_const)); ZigValue *out_val = result->value; @@ -21729,11 +22748,10 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru return result; } - IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, - instruction->base.scope, instruction->base.source_node, target_value_ptr, first_field, false, false); - result->value->type = get_pointer_to_type(ira->codegen, first_field->type_entry, + ZigType *result_type = get_pointer_to_type(ira->codegen, first_field->type_entry, target_value_ptr->value->type->data.pointer.is_const); - return result; + return ir_build_union_field_ptr(ira, &instruction->base.base, target_value_ptr, first_field, + false, false, result_type); } else if (target_type->id == ZigTypeIdErrorSet) { // construct an error set from the prong values ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); @@ -21746,7 +22764,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru for (size_t i = 0; i < instruction->prongs_len; i += 1) { ErrorTableEntry *err = ir_resolve_error(ira, instruction->prongs_ptr[i]->child); if (err == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; error_list.append(err); buf_appendf(&err_set_type->name, "%s,", buf_ptr(&err->name)); } @@ -21762,29 +22780,29 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru ref_type->data.pointer.explicit_alignment, ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, ref_type->data.pointer.allow_zero); - return ir_analyze_ptr_cast(ira, &instruction->base, target_value_ptr, new_target_value_ptr_type, - &instruction->base, false); + return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, + &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false); } else { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } -static IrInstruction *ir_analyze_instruction_switch_else_var(IrAnalyze *ira, - IrInstructionSwitchElseVar *instruction) +static IrInstGen *ir_analyze_instruction_switch_else_var(IrAnalyze *ira, + IrInstSrcSwitchElseVar *instruction) { - IrInstruction *target_value_ptr = instruction->target_value_ptr->child; + IrInstGen *target_value_ptr = instruction->target_value_ptr->child; if (type_is_invalid(target_value_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *ref_type = target_value_ptr->value->type; assert(ref_type->id == ZigTypeIdPointer); ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; if (target_type->id == ZigTypeIdErrorSet) { // make a new set that has the other cases removed - if (!resolve_inferred_error_set(ira->codegen, target_type, instruction->base.source_node)) { - return ira->codegen->invalid_instruction; + if (!resolve_inferred_error_set(ira->codegen, target_type, instruction->base.base.source_node)) { + return ira->codegen->invalid_inst_gen; } if (type_is_global_error_set(target_type)) { // the type of the else capture variable still has to be the global error set. @@ -21793,18 +22811,20 @@ static IrInstruction *ir_analyze_instruction_switch_else_var(IrAnalyze *ira, } // Make note of the errors handled by other cases ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); - for (size_t case_i = 0; case_i < instruction->switch_br->case_count; case_i += 1) { - IrInstructionSwitchBrCase *br_case = &instruction->switch_br->cases[case_i]; - IrInstruction *case_expr = br_case->value->child; + // We may not have any case in the switch if this is a lone else + const size_t switch_cases = instruction->switch_br ? instruction->switch_br->case_count : 0; + for (size_t case_i = 0; case_i < switch_cases; case_i += 1) { + IrInstSrcSwitchBrCase *br_case = &instruction->switch_br->cases[case_i]; + IrInstGen *case_expr = br_case->value->child; if (case_expr->value->type->id == ZigTypeIdErrorSet) { ErrorTableEntry *err = ir_resolve_error(ira, case_expr); if (err == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; errors[err->value] = err; } else if (case_expr->value->type->id == ZigTypeIdMetaType) { ZigType *err_set_type = ir_resolve_type(ira, case_expr); if (type_is_invalid(err_set_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; populate_error_set_table(errors, err_set_type); } else { zig_unreachable(); @@ -21843,27 +22863,22 @@ static IrInstruction *ir_analyze_instruction_switch_else_var(IrAnalyze *ira, ref_type->data.pointer.explicit_alignment, ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, ref_type->data.pointer.allow_zero); - return ir_analyze_ptr_cast(ira, &instruction->base, target_value_ptr, new_target_value_ptr_type, - &instruction->base, false); + return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, + &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false); } return target_value_ptr; } -static IrInstruction *ir_analyze_instruction_union_tag(IrAnalyze *ira, IrInstructionUnionTag *instruction) { - IrInstruction *value = instruction->value->child; - return ir_analyze_union_tag(ira, &instruction->base, value); -} - -static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) { +static IrInstGen *ir_analyze_instruction_import(IrAnalyze *ira, IrInstSrcImport *import_instruction) { Error err; - IrInstruction *name_value = import_instruction->name->child; + IrInstGen *name_value = import_instruction->name->child; Buf *import_target_str = ir_resolve_str(ira, name_value); if (!import_target_str) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - AstNode *source_node = import_instruction->base.source_node; + AstNode *source_node = import_instruction->base.base.source_node; ZigType *import = source_node->owner; ZigType *target_import; @@ -21876,48 +22891,48 @@ static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructio ir_add_error_node(ira, source_node, buf_sprintf("import of file outside package path: '%s'", buf_ptr(import_target_path))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (err == ErrorFileNotFound) { ir_add_error_node(ira, source_node, buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { ir_add_error_node(ira, source_node, buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } - return ir_const_type(ira, &import_instruction->base, target_import); + return ir_const_type(ira, &import_instruction->base.base, target_import); } -static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRef *ref_instruction) { - IrInstruction *value = ref_instruction->value->child; +static IrInstGen *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstSrcRef *ref_instruction) { + IrInstGen *value = ref_instruction->value->child; if (type_is_invalid(value->value->type)) - return ira->codegen->invalid_instruction; - return ir_get_ref(ira, &ref_instruction->base, value, ref_instruction->is_const, ref_instruction->is_volatile); + return ira->codegen->invalid_inst_gen; + return ir_get_ref(ira, &ref_instruction->base.base, value, ref_instruction->is_const, ref_instruction->is_volatile); } -static IrInstruction *ir_analyze_union_init(IrAnalyze *ira, IrInstruction *source_instruction, - AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstruction *field_result_loc, - IrInstruction *result_loc) +static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instruction, + AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstGen *field_result_loc, + IrInstGen *result_loc) { Error err; assert(union_type->id == ZigTypeIdUnion); if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; TypeUnionField *type_field = find_union_type_field(union_type, field_name); if (type_field == nullptr) { ir_add_error_node(ira, field_source_node, buf_sprintf("no member named '%s' in union '%s'", buf_ptr(field_name), buf_ptr(&union_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (type_is_invalid(type_field->type_entry)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { if (instr_is_comptime(field_result_loc) && @@ -21929,42 +22944,42 @@ static IrInstruction *ir_analyze_union_init(IrAnalyze *ira, IrInstruction *sourc } } - bool is_comptime = ir_should_inline(ira->new_irb.exec, source_instruction->scope) + bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instruction->scope) || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes; - IrInstruction *result = ir_get_deref(ira, source_instruction, result_loc, nullptr); + IrInstGen *result = ir_get_deref(ira, source_instruction, result_loc, nullptr); if (is_comptime && !instr_is_comptime(result)) { - ir_add_error(ira, field_result_loc, + ir_add_error(ira, &field_result_loc->base, buf_sprintf("unable to evaluate constant expression")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return result; } -static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, - ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, - IrInstruction *result_loc) +static IrInstGen *ir_analyze_container_init_fields(IrAnalyze *ira, IrInst *source_instr, + ZigType *container_type, size_t instr_field_count, IrInstSrcContainerInitFieldsField *fields, + IrInstGen *result_loc) { Error err; if (container_type->id == ZigTypeIdUnion) { if (instr_field_count != 1) { - ir_add_error(ira, instruction, + ir_add_error(ira, source_instr, buf_sprintf("union initialization expects exactly one field")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstructionContainerInitFieldsField *field = &fields[0]; - IrInstruction *field_result_loc = field->result_loc->child; + IrInstSrcContainerInitFieldsField *field = &fields[0]; + IrInstGen *field_result_loc = field->result_loc->child; if (type_is_invalid(field_result_loc->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_union_init(ira, instruction, field->source_node, container_type, field->name, + return ir_analyze_union_init(ira, source_instr, field->source_node, container_type, field->name, field_result_loc, result_loc); } if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { - ir_add_error(ira, instruction, + ir_add_error(ira, source_instr, buf_sprintf("type '%s' does not support struct initialization syntax", buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (container_type->data.structure.resolve_status == ResolveStatusBeingInferred) { @@ -21973,16 +22988,16 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc } if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; size_t actual_field_count = container_type->data.structure.src_field_count; - IrInstruction *first_non_const_instruction = nullptr; + IrInstGen *first_non_const_instruction = nullptr; AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); - ZigList<IrInstruction *> const_ptrs = {}; + ZigList<IrInstGen *> const_ptrs = {}; - bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) + bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope) || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; @@ -21998,29 +23013,29 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc // comptime-known values. for (size_t i = 0; i < instr_field_count; i += 1) { - IrInstructionContainerInitFieldsField *field = &fields[i]; + IrInstSrcContainerInitFieldsField *field = &fields[i]; - IrInstruction *field_result_loc = field->result_loc->child; + IrInstGen *field_result_loc = field->result_loc->child; if (type_is_invalid(field_result_loc->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; TypeStructField *type_field = find_struct_type_field(container_type, field->name); if (!type_field) { ir_add_error_node(ira, field->source_node, buf_sprintf("no member named '%s' in struct '%s'", buf_ptr(field->name), buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (type_is_invalid(type_field->type_entry)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; size_t field_index = type_field->src_index; AstNode *existing_assign_node = field_assign_nodes[field_index]; if (existing_assign_node) { ErrorMsg *msg = ir_add_error_node(ira, field->source_node, buf_sprintf("duplicate field")); add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } field_assign_nodes[field_index] = field->source_node; @@ -22041,20 +23056,20 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc TypeStructField *field = container_type->data.structure.fields[i]; memoize_field_init_val(ira->codegen, container_type, field); if (field->init_val == nullptr) { - ir_add_error_node(ira, instruction->source_node, + ir_add_error(ira, source_instr, buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i]->name))); any_missing = true; continue; } if (type_is_invalid(field->init_val->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); + IrInstGen *runtime_inst = ir_const(ira, source_instr, field->init_val->type); copy_const_val(runtime_inst->value, field->init_val); - IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc, + IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, result_loc, container_type, true); - ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst, false); + ir_analyze_store_ptr(ira, source_instr, field_ptr, runtime_inst, false); if (instr_is_comptime(field_ptr) && field_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { const_ptrs.append(field_ptr); } else { @@ -22062,39 +23077,39 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc } } if (any_missing) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { if (const_ptrs.length != actual_field_count) { result_loc->value->special = ConstValSpecialRuntime; for (size_t i = 0; i < const_ptrs.length; i += 1) { - IrInstruction *field_result_loc = const_ptrs.at(i); - IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr); + IrInstGen *field_result_loc = const_ptrs.at(i); + IrInstGen *deref = ir_get_deref(ira, &field_result_loc->base, field_result_loc, nullptr); field_result_loc->value->special = ConstValSpecialRuntime; - ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref, false); + ir_analyze_store_ptr(ira, &field_result_loc->base, field_result_loc, deref, false); } } } - IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); + IrInstGen *result = ir_get_deref(ira, source_instr, result_loc, nullptr); if (is_comptime && !instr_is_comptime(result)) { - ir_add_error_node(ira, first_non_const_instruction->source_node, + ir_add_error_node(ira, first_non_const_instruction->base.source_node, buf_sprintf("unable to evaluate constant expression")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return result; } -static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, - IrInstructionContainerInitList *instruction) +static IrInstGen *ir_analyze_instruction_container_init_list(IrAnalyze *ira, + IrInstSrcContainerInitList *instruction) { - ir_assert(instruction->result_loc != nullptr, &instruction->base); - IrInstruction *result_loc = instruction->result_loc->child; + ir_assert(instruction->result_loc != nullptr, &instruction->base.base); + IrInstGen *result_loc = instruction->result_loc->child; if (type_is_invalid(result_loc->value->type)) return result_loc; - ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base); + ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); ZigType *container_type = result_loc->value->type->data.pointer.child_type; @@ -22104,24 +23119,24 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, ir_add_error_node(ira, instruction->init_array_type_source_node, buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (container_type->id == ZigTypeIdVoid) { if (elem_count != 0) { - ir_add_error_node(ira, instruction->base.source_node, + ir_add_error_node(ira, instruction->base.base.source_node, buf_sprintf("void expression expects no arguments")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } if (container_type->id == ZigTypeIdStruct && elem_count == 0) { - ir_assert(instruction->result_loc != nullptr, &instruction->base); - IrInstruction *result_loc = instruction->result_loc->child; + ir_assert(instruction->result_loc != nullptr, &instruction->base.base); + IrInstGen *result_loc = instruction->result_loc->child; if (type_is_invalid(result_loc->value->type)) return result_loc; - return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc); + return ir_analyze_container_init_fields(ira, &instruction->base.base, container_type, 0, nullptr, result_loc); } if (container_type->id == ZigTypeIdArray) { @@ -22129,10 +23144,10 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, if (container_type->data.array.len != elem_count) { ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count, nullptr); - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("expected %s literal, found %s literal", buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } else if (container_type->id == ZigTypeIdStruct && container_type->data.structure.resolve_status == ResolveStatusBeingInferred) @@ -22142,17 +23157,17 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, } else if (container_type->id == ZigTypeIdVector) { // OK } else { - ir_add_error_node(ira, instruction->base.source_node, + ir_add_error(ira, &instruction->base.base, buf_sprintf("type '%s' does not support array initialization", buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } switch (type_has_one_possible_value(ira->codegen, container_type)) { case OnePossibleValueInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case OnePossibleValueYes: - return ir_const_move(ira, &instruction->base, + return ir_const_move(ira, &instruction->base.base, get_the_one_possible_value(ira->codegen, container_type)); case OnePossibleValueNo: break; @@ -22161,16 +23176,16 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, bool is_comptime; switch (type_requires_comptime(ira->codegen, container_type)) { case ReqCompTimeInvalid: - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; case ReqCompTimeNo: - is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); + is_comptime = ir_should_inline(ira->old_irb.exec, instruction->base.base.scope); break; case ReqCompTimeYes: is_comptime = true; break; } - IrInstruction *first_non_const_instruction = nullptr; + IrInstGen *first_non_const_instruction = nullptr; // The Result Location Mechanism has already emitted runtime instructions to // initialize runtime elements and has omitted instructions for the comptime @@ -22179,12 +23194,12 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, // array initialization can be a comptime value, overwrite ConstPtrMutInfer with // ConstPtrMutComptimeConst. Otherwise, emit instructions to runtime-initialize the // elements that have comptime-known values. - ZigList<IrInstruction *> const_ptrs = {}; + ZigList<IrInstGen *> const_ptrs = {}; for (size_t i = 0; i < elem_count; i += 1) { - IrInstruction *elem_result_loc = instruction->elem_result_loc_list[i]->child; + IrInstGen *elem_result_loc = instruction->elem_result_loc_list[i]->child; if (type_is_invalid(elem_result_loc->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; assert(elem_result_loc->value->type->id == ZigTypeIdPointer); @@ -22201,81 +23216,79 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, if (const_ptrs.length != elem_count) { result_loc->value->special = ConstValSpecialRuntime; for (size_t i = 0; i < const_ptrs.length; i += 1) { - IrInstruction *elem_result_loc = const_ptrs.at(i); + IrInstGen *elem_result_loc = const_ptrs.at(i); assert(elem_result_loc->value->special == ConstValSpecialStatic); if (elem_result_loc->value->type->data.pointer.inferred_struct_field != nullptr) { // This field will be generated comptime; no need to do this. continue; } - IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr); + IrInstGen *deref = ir_get_deref(ira, &elem_result_loc->base, elem_result_loc, nullptr); elem_result_loc->value->special = ConstValSpecialRuntime; - ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref, false); + ir_analyze_store_ptr(ira, &elem_result_loc->base, elem_result_loc, deref, false); } } } - IrInstruction *result = ir_get_deref(ira, &instruction->base, result_loc, nullptr); + IrInstGen *result = ir_get_deref(ira, &instruction->base.base, result_loc, nullptr); if (instr_is_comptime(result)) return result; if (is_comptime) { - ir_add_error_node(ira, first_non_const_instruction->source_node, + ir_add_error(ira, &first_non_const_instruction->base, buf_sprintf("unable to evaluate constant expression")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *result_elem_type = result_loc->value->type->data.pointer.child_type; if (is_slice(result_elem_type)) { - ErrorMsg *msg = ir_add_error(ira, &instruction->base, + ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'", buf_ptr(&result_elem_type->name))); - add_error_note(ira->codegen, msg, first_non_const_instruction->source_node, + add_error_note(ira->codegen, msg, first_non_const_instruction->base.source_node, buf_sprintf("this value is not comptime-known")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return result; } -static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, - IrInstructionContainerInitFields *instruction) +static IrInstGen *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, + IrInstSrcContainerInitFields *instruction) { - ir_assert(instruction->result_loc != nullptr, &instruction->base); - IrInstruction *result_loc = instruction->result_loc->child; + ir_assert(instruction->result_loc != nullptr, &instruction->base.base); + IrInstGen *result_loc = instruction->result_loc->child; if (type_is_invalid(result_loc->value->type)) return result_loc; - ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base); + ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); ZigType *container_type = result_loc->value->type->data.pointer.child_type; - return ir_analyze_container_init_fields(ira, &instruction->base, container_type, + return ir_analyze_container_init_fields(ira, &instruction->base.base, container_type, instruction->field_count, instruction->fields, result_loc); } -static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, - IrInstructionCompileErr *instruction) -{ - IrInstruction *msg_value = instruction->msg->child; +static IrInstGen *ir_analyze_instruction_compile_err(IrAnalyze *ira, IrInstSrcCompileErr *instruction) { + IrInstGen *msg_value = instruction->msg->child; Buf *msg_buf = ir_resolve_str(ira, msg_value); if (!msg_buf) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - ir_add_error(ira, &instruction->base, msg_buf); + ir_add_error(ira, &instruction->base.base, msg_buf); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } -static IrInstruction *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInstructionCompileLog *instruction) { +static IrInstGen *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInstSrcCompileLog *instruction) { Buf buf = BUF_INIT; fprintf(stderr, "| "); for (size_t i = 0; i < instruction->msg_count; i += 1) { - IrInstruction *msg = instruction->msg_list[i]->child; + IrInstGen *msg = instruction->msg_list[i]->child; if (type_is_invalid(msg->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; buf_resize(&buf, 0); if (msg->value->special == ConstValSpecialLazy) { // Resolve any lazy value that's passed, we need its value - if (ir_resolve_lazy(ira->codegen, msg->source_node, msg->value)) - return ira->codegen->invalid_instruction; + if (ir_resolve_lazy(ira->codegen, msg->base.source_node, msg->value)) + return ira->codegen->invalid_inst_gen; } render_const_value(ira->codegen, &buf, msg->value); const char *comma_str = (i != 0) ? ", " : ""; @@ -22283,25 +23296,25 @@ static IrInstruction *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInstr } fprintf(stderr, "\n"); - auto *expr = &instruction->base.source_node->data.fn_call_expr; + auto *expr = &instruction->base.base.source_node->data.fn_call_expr; if (!expr->seen) { // Here we bypass higher level functions such as ir_add_error because we do not want // invalidate_exec to be called. - add_node_error(ira->codegen, instruction->base.source_node, buf_sprintf("found compile log statement")); + add_node_error(ira->codegen, instruction->base.base.source_node, buf_sprintf("found compile log statement")); } expr->seen = true; - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstructionErrName *instruction) { - IrInstruction *value = instruction->value->child; +static IrInstGen *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstSrcErrName *instruction) { + IrInstGen *value = instruction->value->child; if (type_is_invalid(value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_global_error_set); + IrInstGen *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_global_error_set); if (type_is_invalid(casted_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, true, false, PtrLenUnknown, 0, 0, 0, false); @@ -22309,13 +23322,13 @@ static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruct if (instr_is_comptime(casted_value)) { ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); if (val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ErrorTableEntry *err = casted_value->value->data.x_err_set; if (!err->cached_error_name_val) { ZigValue *array_val = create_const_str_lit(ira->codegen, &err->name)->data.x_ptr.data.ref.pointee; err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); } - IrInstruction *result = ir_const(ira, &instruction->base, nullptr); + IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); copy_const_val(result->value, err->cached_error_name_val); result->value->type = str_type; return result; @@ -22323,20 +23336,17 @@ static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruct ira->codegen->generate_error_name_table = true; - IrInstruction *result = ir_build_err_name(&ira->new_irb, - instruction->base.scope, instruction->base.source_node, value); - result->value->type = str_type; - return result; + return ir_build_err_name_gen(ira, &instruction->base.base, value, str_type); } -static IrInstruction *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructionTagName *instruction) { +static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrcTagName *instruction) { Error err; - IrInstruction *target = instruction->target->child; + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (target->value->type->id == ZigTypeIdEnumLiteral) { - IrInstruction *result = ir_const(ira, &instruction->base, nullptr); + IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); Buf *field_name = target->value->data.x_enum_literal; ZigValue *array_val = create_const_str_lit(ira->codegen, field_name)->data.x_ptr.data.ref.pointee; init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field_name), true); @@ -22344,86 +23354,88 @@ static IrInstruction *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrIns } if (target->value->type->id == ZigTypeIdUnion) { - target = ir_analyze_union_tag(ira, &instruction->base, target); + target = ir_analyze_union_tag(ira, &instruction->base.base, target, instruction->base.is_gen); if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - assert(target->value->type->id == ZigTypeIdEnum); + if (target->value->type->id != ZigTypeIdEnum) { + ir_add_error(ira, &target->base, + buf_sprintf("expected enum tag, found '%s'", buf_ptr(&target->value->type->name))); + return ira->codegen->invalid_inst_gen; + } if (target->value->type->data.enumeration.src_field_count == 1 && !target->value->type->data.enumeration.non_exhaustive) { TypeEnumField *only_field = &target->value->type->data.enumeration.fields[0]; ZigValue *array_val = create_const_str_lit(ira->codegen, only_field->name)->data.x_ptr.data.ref.pointee; - IrInstruction *result = ir_const(ira, &instruction->base, nullptr); + IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(only_field->name), true); return result; } if (instr_is_comptime(target)) { if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (target->value->type->data.enumeration.non_exhaustive) { - add_node_error(ira->codegen, instruction->base.source_node, + ir_add_error(ira, &instruction->base.base, buf_sprintf("TODO @tagName on non-exhaustive enum https://github.com/ziglang/zig/issues/3991")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } TypeEnumField *field = find_enum_field_by_tag(target->value->type, &target->value->data.x_bigint); ZigValue *array_val = create_const_str_lit(ira->codegen, field->name)->data.x_ptr.data.ref.pointee; - IrInstruction *result = ir_const(ira, &instruction->base, nullptr); + IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field->name), true); return result; } - IrInstruction *result = ir_build_tag_name(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, target); ZigType *u8_ptr_type = get_pointer_to_type_extra( ira->codegen, ira->codegen->builtin_types.entry_u8, true, false, PtrLenUnknown, 0, 0, 0, false); - result->value->type = get_slice_type(ira->codegen, u8_ptr_type); - return result; + ZigType *result_type = get_slice_type(ira->codegen, u8_ptr_type); + return ir_build_tag_name_gen(ira, &instruction->base.base, target, result_type); } -static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, - IrInstructionFieldParentPtr *instruction) +static IrInstGen *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, + IrInstSrcFieldParentPtr *instruction) { Error err; - IrInstruction *type_value = instruction->type_value->child; + IrInstGen *type_value = instruction->type_value->child; ZigType *container_type = ir_resolve_type(ira, type_value); if (type_is_invalid(container_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *field_name_value = instruction->field_name->child; + IrInstGen *field_name_value = instruction->field_name->child; Buf *field_name = ir_resolve_str(ira, field_name_value); if (!field_name) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *field_ptr = instruction->field_ptr->child; + IrInstGen *field_ptr = instruction->field_ptr->child; if (type_is_invalid(field_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (container_type->id != ZigTypeIdStruct) { - ir_add_error(ira, type_value, + ir_add_error(ira, &type_value->base, buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; TypeStructField *field = find_struct_type_field(container_type, field_name); if (field == nullptr) { - ir_add_error(ira, field_name_value, + ir_add_error(ira, &field_name_value->base, buf_sprintf("struct '%s' has no field '%s'", buf_ptr(&container_type->name), buf_ptr(field_name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (field_ptr->value->type->id != ZigTypeIdPointer) { - ir_add_error(ira, field_ptr, + ir_add_error(ira, &field_ptr->base, buf_sprintf("expected pointer, found '%s'", buf_ptr(&field_ptr->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } bool is_packed = (container_type->data.structure.layout == ContainerLayoutPacked); @@ -22435,9 +23447,9 @@ static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, field_ptr->value->type->data.pointer.is_volatile, PtrLenSingle, field_ptr_align, 0, 0, false); - IrInstruction *casted_field_ptr = ir_implicit_cast(ira, field_ptr, field_ptr_type); + IrInstGen *casted_field_ptr = ir_implicit_cast(ira, field_ptr, field_ptr_type); if (type_is_invalid(casted_field_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *result_type = get_pointer_to_type_extra(ira->codegen, container_type, casted_field_ptr->value->type->data.pointer.is_const, @@ -22448,23 +23460,23 @@ static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, if (instr_is_comptime(casted_field_ptr)) { ZigValue *field_ptr_val = ir_resolve_const(ira, casted_field_ptr, UndefBad); if (!field_ptr_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (field_ptr_val->data.x_ptr.special != ConstPtrSpecialBaseStruct) { - ir_add_error(ira, field_ptr, buf_sprintf("pointer value not based on parent struct")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &field_ptr->base, buf_sprintf("pointer value not based on parent struct")); + return ira->codegen->invalid_inst_gen; } size_t ptr_field_index = field_ptr_val->data.x_ptr.data.base_struct.field_index; if (ptr_field_index != field->src_index) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("field '%s' has index %" ZIG_PRI_usize " but pointer value is index %" ZIG_PRI_usize " of struct '%s'", buf_ptr(field->name), field->src_index, ptr_field_index, buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *result = ir_const(ira, &instruction->base, result_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); ZigValue *out_val = result->value; out_val->data.x_ptr.special = ConstPtrSpecialRef; out_val->data.x_ptr.data.ref.pointee = field_ptr_val->data.x_ptr.data.base_struct.struct_val; @@ -22472,15 +23484,12 @@ static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, return result; } - IrInstruction *result = ir_build_field_parent_ptr(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, type_value, field_name_value, casted_field_ptr, field); - result->value->type = result_type; - return result; + return ir_build_field_parent_ptr_gen(ira, &instruction->base.base, casted_field_ptr, field, result_type); } static TypeStructField *validate_byte_offset(IrAnalyze *ira, - IrInstruction *type_value, - IrInstruction *field_name_value, + IrInstGen *type_value, + IrInstGen *field_name_value, size_t *byte_offset) { ZigType *container_type = ir_resolve_type(ira, type_value); @@ -22496,21 +23505,21 @@ static TypeStructField *validate_byte_offset(IrAnalyze *ira, return nullptr; if (container_type->id != ZigTypeIdStruct) { - ir_add_error(ira, type_value, + ir_add_error(ira, &type_value->base, buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); return nullptr; } TypeStructField *field = find_struct_type_field(container_type, field_name); if (field == nullptr) { - ir_add_error(ira, field_name_value, + ir_add_error(ira, &field_name_value->base, buf_sprintf("struct '%s' has no field '%s'", buf_ptr(&container_type->name), buf_ptr(field_name))); return nullptr; } if (!type_has_bits(field->type_entry)) { - ir_add_error(ira, field_name_value, + ir_add_error(ira, &field_name_value->base, buf_sprintf("zero-bit field '%s' in struct '%s' has no offset", buf_ptr(field_name), buf_ptr(&container_type->name))); return nullptr; @@ -22520,36 +23529,32 @@ static TypeStructField *validate_byte_offset(IrAnalyze *ira, return field; } -static IrInstruction *ir_analyze_instruction_byte_offset_of(IrAnalyze *ira, - IrInstructionByteOffsetOf *instruction) -{ - IrInstruction *type_value = instruction->type_value->child; +static IrInstGen *ir_analyze_instruction_byte_offset_of(IrAnalyze *ira, IrInstSrcByteOffsetOf *instruction) { + IrInstGen *type_value = instruction->type_value->child; if (type_is_invalid(type_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *field_name_value = instruction->field_name->child; + IrInstGen *field_name_value = instruction->field_name->child; size_t byte_offset = 0; if (!validate_byte_offset(ira, type_value, field_name_value, &byte_offset)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_const_unsigned(ira, &instruction->base, byte_offset); + return ir_const_unsigned(ira, &instruction->base.base, byte_offset); } -static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, - IrInstructionBitOffsetOf *instruction) -{ - IrInstruction *type_value = instruction->type_value->child; +static IrInstGen *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, IrInstSrcBitOffsetOf *instruction) { + IrInstGen *type_value = instruction->type_value->child; if (type_is_invalid(type_value->value->type)) - return ira->codegen->invalid_instruction; - IrInstruction *field_name_value = instruction->field_name->child; + return ira->codegen->invalid_inst_gen; + IrInstGen *field_name_value = instruction->field_name->child; size_t byte_offset = 0; TypeStructField *field = nullptr; if (!(field = validate_byte_offset(ira, type_value, field_name_value, &byte_offset))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; size_t bit_offset = byte_offset * 8 + field->bit_offset_in_host; - return ir_const_unsigned(ira, &instruction->base, bit_offset); + return ir_const_unsigned(ira, &instruction->base.base, bit_offset); } static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { @@ -22597,7 +23602,7 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, nullptr, var->const_value); } -static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr, ZigValue *out_val, +static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigValue *out_val, ScopeDecls *decls_scope) { Error err; @@ -22628,11 +23633,14 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr while ((curr_entry = decl_it.next()) != nullptr) { // If the declaration is unresolved, force it to be resolved again. - if (curr_entry->value->resolution == TldResolutionUnresolved) { - resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node, false); - if (curr_entry->value->resolution != TldResolutionOk) { - return ErrorSemanticAnalyzeFail; - } + resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node, false); + if (curr_entry->value->resolution == TldResolutionInvalid) { + return ErrorSemanticAnalyzeFail; + } + + if (curr_entry->value->resolution == TldResolutionResolving) { + ir_error_dependency_loop(ira, source_instr); + return ErrorSemanticAnalyzeFail; } // Skip comptime blocks and test functions. @@ -22689,6 +23697,8 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr case TldIdVar: { ZigVar *var = ((TldVar *)curr_entry->value)->var; + assert(var != nullptr); + if ((err = type_resolve(ira->codegen, var->const_value->type, ResolveStatusSizeKnown))) return ErrorSemanticAnalyzeFail; @@ -22719,11 +23729,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; assert(!fn_entry->is_test); - - if (fn_entry->type_entry == nullptr) { - ir_error_dependency_loop(ira, source_instr); - return ErrorSemanticAnalyzeFail; - } + assert(fn_entry->type_entry != nullptr); AstNodeFnProto *fn_node = &fn_entry->proto_node->data.fn_proto; @@ -22955,7 +23961,7 @@ static void make_enum_field_val(IrAnalyze *ira, ZigValue *enum_field_val, TypeEn enum_field_val->data.x_struct.fields = inner_fields; } -static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr, ZigType *type_entry, +static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigType *type_entry, ZigValue **out) { Error err; @@ -23543,22 +24549,20 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr return ErrorNone; } -static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira, - IrInstructionTypeInfo *instruction) -{ +static IrInstGen *ir_analyze_instruction_type_info(IrAnalyze *ira, IrInstSrcTypeInfo *instruction) { Error err; - IrInstruction *type_value = instruction->type_value->child; + IrInstGen *type_value = instruction->type_value->child; ZigType *type_entry = ir_resolve_type(ira, type_value); if (type_is_invalid(type_entry)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *result_type = ir_type_info_get_type(ira, nullptr, nullptr); ZigValue *payload; - if ((err = ir_make_type_info_value(ira, &instruction->base, type_entry, &payload))) - return ira->codegen->invalid_instruction; + if ((err = ir_make_type_info_value(ira, &instruction->base.base, type_entry, &payload))) + return ira->codegen->invalid_inst_gen; - IrInstruction *result = ir_const(ira, &instruction->base, result_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); ZigValue *out_val = result->value; bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry)); out_val->data.x_union.payload = payload; @@ -23582,15 +24586,15 @@ static ZigValue *get_const_field(IrAnalyze *ira, AstNode *source_node, ZigValue return val; } -static Error get_const_field_sentinel(IrAnalyze *ira, IrInstruction *source_instr, ZigValue *struct_value, +static Error get_const_field_sentinel(IrAnalyze *ira, IrInst* source_instr, ZigValue *struct_value, const char *name, size_t field_index, ZigType *elem_type, ZigValue **result) { ZigValue *field_val = get_const_field(ira, source_instr->source_node, struct_value, name, field_index); if (field_val == nullptr) return ErrorSemanticAnalyzeFail; - IrInstruction *field_inst = ir_const_move(ira, source_instr, field_val); - IrInstruction *casted_field_inst = ir_implicit_cast(ira, field_inst, + IrInstGen *field_inst = ir_const_move(ira, source_instr, field_val); + IrInstGen *casted_field_inst = ir_implicit_cast(ira, field_inst, get_optional_type(ira->codegen, elem_type)); if (type_is_invalid(casted_field_inst->value->type)) return ErrorSemanticAnalyzeFail; @@ -23629,12 +24633,12 @@ static ZigType *get_const_field_meta_type(IrAnalyze *ira, AstNode *source_node, { ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); if (value == nullptr) - return ira->codegen->invalid_instruction->value->type; + return ira->codegen->invalid_inst_gen->value->type; assert(value->type == ira->codegen->builtin_types.entry_type); return value->data.x_type; } -static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, ZigTypeId tagTypeId, ZigValue *payload) { +static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeId tagTypeId, ZigValue *payload) { Error err; switch (tagTypeId) { case ZigTypeIdInvalid: @@ -23650,21 +24654,21 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi case ZigTypeIdInt: { assert(payload->special == ConstValSpecialStatic); assert(payload->type == ir_type_info_get_type(ira, "Int", nullptr)); - BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "bits", 1); + BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "bits", 1); if (bi == nullptr) - return ira->codegen->invalid_instruction->value->type; + return ira->codegen->invalid_inst_gen->value->type; bool is_signed; - if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_signed", 0, &is_signed))) - return ira->codegen->invalid_instruction->value->type; + if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_signed", 0, &is_signed))) + return ira->codegen->invalid_inst_gen->value->type; return get_int_type(ira->codegen, is_signed, bigint_as_u32(bi)); } case ZigTypeIdFloat: { assert(payload->special == ConstValSpecialStatic); assert(payload->type == ir_type_info_get_type(ira, "Float", nullptr)); - BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "bits", 0); + BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "bits", 0); if (bi == nullptr) - return ira->codegen->invalid_instruction->value->type; + return ira->codegen->invalid_inst_gen->value->type; uint32_t bits = bigint_as_u32(bi); switch (bits) { case 16: return ira->codegen->builtin_types.entry_f16; @@ -23672,48 +24676,47 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi case 64: return ira->codegen->builtin_types.entry_f64; case 128: return ira->codegen->builtin_types.entry_f128; } - ir_add_error(ira, instruction, - buf_sprintf("%d-bit float unsupported", bits)); - return ira->codegen->invalid_instruction->value->type; + ir_add_error(ira, source_instr, buf_sprintf("%d-bit float unsupported", bits)); + return ira->codegen->invalid_inst_gen->value->type; } case ZigTypeIdPointer: { ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); assert(payload->special == ConstValSpecialStatic); assert(payload->type == type_info_pointer_type); - ZigValue *size_value = get_const_field(ira, instruction->source_node, payload, "size", 0); + ZigValue *size_value = get_const_field(ira, source_instr->source_node, payload, "size", 0); assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type)); BuiltinPtrSize size_enum_index = (BuiltinPtrSize)bigint_as_u32(&size_value->data.x_enum_tag); PtrLen ptr_len = size_enum_index_to_ptr_len(size_enum_index); - ZigType *elem_type = get_const_field_meta_type(ira, instruction->source_node, payload, "child", 4); + ZigType *elem_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 4); if (type_is_invalid(elem_type)) - return ira->codegen->invalid_instruction->value->type; + return ira->codegen->invalid_inst_gen->value->type; ZigValue *sentinel; - if ((err = get_const_field_sentinel(ira, instruction, payload, "sentinel", 6, + if ((err = get_const_field_sentinel(ira, source_instr, payload, "sentinel", 6, elem_type, &sentinel))) { - return ira->codegen->invalid_instruction->value->type; + return ira->codegen->invalid_inst_gen->value->type; } - BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "alignment", 3); + BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "alignment", 3); if (bi == nullptr) - return ira->codegen->invalid_instruction->value->type; + return ira->codegen->invalid_inst_gen->value->type; bool is_const; - if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_const", 1, &is_const))) - return ira->codegen->invalid_instruction->value->type; + if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_const", 1, &is_const))) + return ira->codegen->invalid_inst_gen->value->type; bool is_volatile; - if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_volatile", 2, + if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_volatile", 2, &is_volatile))) { - return ira->codegen->invalid_instruction->value->type; + return ira->codegen->invalid_inst_gen->value->type; } bool is_allowzero; - if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_allowzero", 5, + if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_allowzero", 5, &is_allowzero))) { - return ira->codegen->invalid_instruction->value->type; + return ira->codegen->invalid_inst_gen->value->type; } @@ -23734,18 +24737,18 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi case ZigTypeIdArray: { assert(payload->special == ConstValSpecialStatic); assert(payload->type == ir_type_info_get_type(ira, "Array", nullptr)); - ZigType *elem_type = get_const_field_meta_type(ira, instruction->source_node, payload, "child", 1); + ZigType *elem_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 1); if (type_is_invalid(elem_type)) - return ira->codegen->invalid_instruction->value->type; + return ira->codegen->invalid_inst_gen->value->type; ZigValue *sentinel; - if ((err = get_const_field_sentinel(ira, instruction, payload, "sentinel", 2, + if ((err = get_const_field_sentinel(ira, source_instr, payload, "sentinel", 2, elem_type, &sentinel))) { - return ira->codegen->invalid_instruction->value->type; + return ira->codegen->invalid_inst_gen->value->type; } - BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "len", 0); + BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "len", 0); if (bi == nullptr) - return ira->codegen->invalid_instruction->value->type; + return ira->codegen->invalid_inst_gen->value->type; return get_array_type(ira->codegen, elem_type, bigint_as_u64(bi), sentinel); } case ZigTypeIdComptimeFloat: @@ -23765,78 +24768,77 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi case ZigTypeIdAnyFrame: case ZigTypeIdVector: case ZigTypeIdEnumLiteral: - ir_add_error(ira, instruction, buf_sprintf( + ir_add_error(ira, source_instr, buf_sprintf( "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId))); - return ira->codegen->invalid_instruction->value->type; + return ira->codegen->invalid_inst_gen->value->type; case ZigTypeIdUnion: case ZigTypeIdFn: case ZigTypeIdBoundFn: case ZigTypeIdStruct: - ir_add_error(ira, instruction, buf_sprintf( + ir_add_error(ira, source_instr, buf_sprintf( "@Type not availble for 'TypeInfo.%s'", type_id_name(tagTypeId))); - return ira->codegen->invalid_instruction->value->type; + return ira->codegen->invalid_inst_gen->value->type; } zig_unreachable(); } -static IrInstruction *ir_analyze_instruction_type(IrAnalyze *ira, IrInstructionType *instruction) { - IrInstruction *type_info_ir = instruction->type_info->child; - if (type_is_invalid(type_info_ir->value->type)) - return ira->codegen->invalid_instruction; +static IrInstGen *ir_analyze_instruction_type(IrAnalyze *ira, IrInstSrcType *instruction) { + IrInstGen *uncasted_type_info = instruction->type_info->child; + if (type_is_invalid(uncasted_type_info->value->type)) + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_ir = ir_implicit_cast(ira, type_info_ir, ir_type_info_get_type(ira, nullptr, nullptr)); - if (type_is_invalid(casted_ir->value->type)) - return ira->codegen->invalid_instruction; + IrInstGen *type_info = ir_implicit_cast(ira, uncasted_type_info, ir_type_info_get_type(ira, nullptr, nullptr)); + if (type_is_invalid(type_info->value->type)) + return ira->codegen->invalid_inst_gen; - ZigValue *type_info_value = ir_resolve_const(ira, casted_ir, UndefBad); - if (!type_info_value) - return ira->codegen->invalid_instruction; - ZigTypeId typeId = type_id_at_index(bigint_as_usize(&type_info_value->data.x_union.tag)); - ZigType *type = type_info_to_type(ira, type_info_ir, typeId, type_info_value->data.x_union.payload); + ZigValue *type_info_val = ir_resolve_const(ira, type_info, UndefBad); + if (type_info_val == nullptr) + return ira->codegen->invalid_inst_gen; + ZigTypeId type_id_tag = type_id_at_index(bigint_as_usize(&type_info_val->data.x_union.tag)); + ZigType *type = type_info_to_type(ira, &uncasted_type_info->base, type_id_tag, + type_info_val->data.x_union.payload); if (type_is_invalid(type)) - return ira->codegen->invalid_instruction; - return ir_const_type(ira, &instruction->base, type); + return ira->codegen->invalid_inst_gen; + return ir_const_type(ira, &instruction->base.base, type); } -static IrInstruction *ir_analyze_instruction_type_id(IrAnalyze *ira, - IrInstructionTypeId *instruction) -{ - IrInstruction *type_value = instruction->type_value->child; +static IrInstGen *ir_analyze_instruction_type_id(IrAnalyze *ira, IrInstSrcTypeId *instruction) { + IrInstGen *type_value = instruction->type_value->child; ZigType *type_entry = ir_resolve_type(ira, type_value); if (type_is_invalid(type_entry)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *result_type = get_builtin_type(ira->codegen, "TypeId"); - IrInstruction *result = ir_const(ira, &instruction->base, result_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); bigint_init_unsigned(&result->value->data.x_enum_tag, type_id_index(type_entry)); return result; } -static IrInstruction *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira, - IrInstructionSetEvalBranchQuota *instruction) +static IrInstGen *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira, + IrInstSrcSetEvalBranchQuota *instruction) { uint64_t new_quota; if (!ir_resolve_usize(ira, instruction->new_quota->child, &new_quota)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (new_quota > *ira->new_irb.exec->backward_branch_quota) { *ira->new_irb.exec->backward_branch_quota = new_quota; } - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) { - IrInstruction *type_value = instruction->type_value->child; +static IrInstGen *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstSrcTypeName *instruction) { + IrInstGen *type_value = instruction->type_value->child; ZigType *type_entry = ir_resolve_type(ira, type_value); if (type_is_invalid(type_entry)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!type_entry->cached_const_name_val) { type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, type_bare_name(type_entry)); } - IrInstruction *result = ir_const(ira, &instruction->base, nullptr); + IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); copy_const_val(result->value, type_entry->cached_const_name_val); return result; } @@ -23848,23 +24850,30 @@ static void ir_cimport_cache_paths(Buf *cache_dir, Buf *tmp_c_file_digest, Buf * buf_ptr(cache_dir), buf_ptr(tmp_c_file_digest)); buf_appendf(out_zig_path, "%s" OS_SEP "cimport.zig", buf_ptr(out_zig_dir)); } -static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCImport *instruction) { +static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImport *instruction) { Error err; - AstNode *node = instruction->base.source_node; + AstNode *node = instruction->base.base.source_node; assert(node->type == NodeTypeFnCallExpr); AstNode *block_node = node->data.fn_call_expr.params.at(0); - ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.scope); + ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.base.scope); // Execute the C import block like an inline function ZigType *void_type = ira->codegen->builtin_types.entry_void; - ZigValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, + ZigValue *cimport_result; + ZigValue *result_ptr; + create_result_ptr(ira->codegen, void_type, &cimport_result, &result_ptr); + if ((err = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, result_ptr, ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, - &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, UndefBad); + &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, UndefBad))) + { + return ira->codegen->invalid_inst_gen; + } if (type_is_invalid(cimport_result->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; + destroy(result_ptr, "ZigValue"); - ZigPackage *cur_scope_pkg = scope_package(instruction->base.scope); + ZigPackage *cur_scope_pkg = scope_package(instruction->base.base.scope); Buf *namespace_name = buf_sprintf("%s.cimport:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, buf_ptr(&cur_scope_pkg->pkg_path), node->line + 1, node->column + 1); @@ -23876,7 +24885,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct CacheHash *cache_hash; if ((err = create_c_object_cache(ira->codegen, &cache_hash, false))) { ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to create cache: %s", err_str(err))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } cache_buf(cache_hash, &cimport_scope->buf); @@ -23888,7 +24897,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct if ((err = cache_hit(cache_hash, &tmp_c_file_digest))) { if (err != ErrorInvalidFormat) { ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to check cache: %s", err_str(err))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } ira->codegen->caches_to_release.append(cache_hash); @@ -23907,12 +24916,12 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct if ((err = os_make_path(tmp_c_file_dir))) { ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (ira->codegen->verbose_cimport) { fprintf(stderr, "@cImport source: %s\n", buf_ptr(&tmp_c_file_path)); @@ -23947,7 +24956,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct { if (err != ErrorCCompileErrors) { ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ErrorMsg *parent_err_msg = ir_add_error_node(ira, node, buf_sprintf("C import failed")); @@ -23968,7 +24977,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct } } - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (ira->codegen->verbose_cimport) { fprintf(stderr, "@cImport .d file: %s\n", buf_ptr(tmp_dep_file)); @@ -23976,29 +24985,29 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct if ((err = cache_add_dep_file(cache_hash, tmp_dep_file, false))) { ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to parse .d file: %s", err_str(err))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if ((err = cache_final(cache_hash, &tmp_c_file_digest))) { ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to finalize cache: %s", err_str(err))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); if ((err = os_make_path(out_zig_dir))) { ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make output dir: %s", err_str(err))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } FILE *out_file = fopen(buf_ptr(out_zig_path), "wb"); if (out_file == nullptr) { ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to open output file: %s", strerror(errno))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } stage2_render_ast(ast, out_file); if (fclose(out_file) != 0) { ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (ira->codegen->verbose_cimport) { @@ -24017,90 +25026,90 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct if ((err = file_fetch(ira->codegen, out_zig_path, import_code))) { ir_add_error_node(ira, node, buf_sprintf("unable to open '%s': %s", buf_ptr(out_zig_path), err_str(err))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *child_import = add_source_file(ira->codegen, cimport_pkg, out_zig_path, import_code, SourceKindCImport); - return ir_const_type(ira, &instruction->base, child_import); + return ir_const_type(ira, &instruction->base.base, child_import); } -static IrInstruction *ir_analyze_instruction_c_include(IrAnalyze *ira, IrInstructionCInclude *instruction) { - IrInstruction *name_value = instruction->name->child; +static IrInstGen *ir_analyze_instruction_c_include(IrAnalyze *ira, IrInstSrcCInclude *instruction) { + IrInstGen *name_value = instruction->name->child; if (type_is_invalid(name_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; Buf *include_name = ir_resolve_str(ira, name_value); if (!include_name) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); + Buf *c_import_buf = ira->new_irb.exec->c_import_buf; // We check for this error in pass1 assert(c_import_buf); buf_appendf(c_import_buf, "#include <%s>\n", buf_ptr(include_name)); - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_c_define(IrAnalyze *ira, IrInstructionCDefine *instruction) { - IrInstruction *name = instruction->name->child; +static IrInstGen *ir_analyze_instruction_c_define(IrAnalyze *ira, IrInstSrcCDefine *instruction) { + IrInstGen *name = instruction->name->child; if (type_is_invalid(name->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; Buf *define_name = ir_resolve_str(ira, name); if (!define_name) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *value = instruction->value->child; + IrInstGen *value = instruction->value->child; if (type_is_invalid(value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; Buf *define_value = nullptr; // The second parameter is either a string or void (equivalent to "") if (value->value->type->id != ZigTypeIdVoid) { define_value = ir_resolve_str(ira, value); if (!define_value) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); + Buf *c_import_buf = ira->new_irb.exec->c_import_buf; // We check for this error in pass1 assert(c_import_buf); buf_appendf(c_import_buf, "#define %s %s\n", buf_ptr(define_name), define_value ? buf_ptr(define_value) : ""); - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstructionCUndef *instruction) { - IrInstruction *name = instruction->name->child; +static IrInstGen *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstSrcCUndef *instruction) { + IrInstGen *name = instruction->name->child; if (type_is_invalid(name->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; Buf *undef_name = ir_resolve_str(ira, name); if (!undef_name) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); + Buf *c_import_buf = ira->new_irb.exec->c_import_buf; // We check for this error in pass1 assert(c_import_buf); buf_appendf(c_import_buf, "#undef %s\n", buf_ptr(undef_name)); - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionEmbedFile *instruction) { - IrInstruction *name = instruction->name->child; +static IrInstGen *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstSrcEmbedFile *instruction) { + IrInstGen *name = instruction->name->child; if (type_is_invalid(name->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; Buf *rel_file_path = ir_resolve_str(ira, name); if (!rel_file_path) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - ZigType *import = get_scope_import(instruction->base.scope); + ZigType *import = get_scope_import(instruction->base.base.scope); // figure out absolute path to resource Buf source_dir_path = BUF_INIT; os_path_dirname(import->data.structure.root_struct->path, &source_dir_path); @@ -24117,93 +25126,95 @@ static IrInstruction *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstru Error err; if ((err = file_fetch(ira->codegen, file_path, file_contents))) { if (err == ErrorFileNotFound) { - ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(file_path))); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->name->base, + buf_sprintf("unable to find '%s'", buf_ptr(file_path))); + return ira->codegen->invalid_inst_gen; } else { - ir_add_error(ira, instruction->name, buf_sprintf("unable to open '%s': %s", buf_ptr(file_path), err_str(err))); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->name->base, + buf_sprintf("unable to open '%s': %s", buf_ptr(file_path), err_str(err))); + return ira->codegen->invalid_inst_gen; } } ZigType *result_type = get_array_type(ira->codegen, ira->codegen->builtin_types.entry_u8, buf_len(file_contents), nullptr); - IrInstruction *result = ir_const(ira, &instruction->base, result_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); init_const_str_lit(ira->codegen, result->value, file_contents); return result; } -static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructionCmpxchgSrc *instruction) { +static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxchg *instruction) { ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->type_value->child); if (type_is_invalid(operand_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (operand_type->id == ZigTypeIdFloat) { - ir_add_error(ira, instruction->type_value->child, + ir_add_error(ira, &instruction->type_value->child->base, buf_sprintf("expected integer, enum or pointer type, found '%s'", buf_ptr(&operand_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *ptr = instruction->ptr->child; + IrInstGen *ptr = instruction->ptr->child; if (type_is_invalid(ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // TODO let this be volatile ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); - IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr, ptr_type); + IrInstGen *casted_ptr = ir_implicit_cast2(ira, &instruction->ptr->base, ptr, ptr_type); if (type_is_invalid(casted_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *cmp_value = instruction->cmp_value->child; + IrInstGen *cmp_value = instruction->cmp_value->child; if (type_is_invalid(cmp_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *new_value = instruction->new_value->child; + IrInstGen *new_value = instruction->new_value->child; if (type_is_invalid(new_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *success_order_value = instruction->success_order_value->child; + IrInstGen *success_order_value = instruction->success_order_value->child; if (type_is_invalid(success_order_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; AtomicOrder success_order; if (!ir_resolve_atomic_order(ira, success_order_value, &success_order)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *failure_order_value = instruction->failure_order_value->child; + IrInstGen *failure_order_value = instruction->failure_order_value->child; if (type_is_invalid(failure_order_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; AtomicOrder failure_order; if (!ir_resolve_atomic_order(ira, failure_order_value, &failure_order)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_cmp_value = ir_implicit_cast(ira, cmp_value, operand_type); + IrInstGen *casted_cmp_value = ir_implicit_cast2(ira, &instruction->cmp_value->base, cmp_value, operand_type); if (type_is_invalid(casted_cmp_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_new_value = ir_implicit_cast(ira, new_value, operand_type); + IrInstGen *casted_new_value = ir_implicit_cast2(ira, &instruction->new_value->base, new_value, operand_type); if (type_is_invalid(casted_new_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (success_order < AtomicOrderMonotonic) { - ir_add_error(ira, success_order_value, + ir_add_error(ira, &success_order_value->base, buf_sprintf("success atomic ordering must be Monotonic or stricter")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (failure_order < AtomicOrderMonotonic) { - ir_add_error(ira, failure_order_value, + ir_add_error(ira, &failure_order_value->base, buf_sprintf("failure atomic ordering must be Monotonic or stricter")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (failure_order > success_order) { - ir_add_error(ira, failure_order_value, + ir_add_error(ira, &failure_order_value->base, buf_sprintf("failure atomic ordering must be no stricter than success")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (failure_order == AtomicOrderRelease || failure_order == AtomicOrderAcqRel) { - ir_add_error(ira, failure_order_value, + ir_add_error(ira, &failure_order_value->base, buf_sprintf("failure atomic ordering must not be Release or AcqRel")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar && @@ -24212,152 +25223,146 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi } ZigType *result_type = get_optional_type(ira->codegen, operand_type); - IrInstruction *result_loc; + IrInstGen *result_loc; if (handle_is_ptr(result_type)) { - result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, - result_type, nullptr, true, false, true); - if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { + result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, + result_type, nullptr, true, true); + if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { return result_loc; } } else { result_loc = nullptr; } - return ir_build_cmpxchg_gen(ira, &instruction->base, result_type, + return ir_build_cmpxchg_gen(ira, &instruction->base.base, result_type, casted_ptr, casted_cmp_value, casted_new_value, success_order, failure_order, instruction->is_weak, result_loc); } -static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) { - IrInstruction *order_value = instruction->order_value->child; - if (type_is_invalid(order_value->value->type)) - return ira->codegen->invalid_instruction; +static IrInstGen *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstSrcFence *instruction) { + IrInstGen *order_inst = instruction->order->child; + if (type_is_invalid(order_inst->value->type)) + return ira->codegen->invalid_inst_gen; AtomicOrder order; - if (!ir_resolve_atomic_order(ira, order_value, &order)) - return ira->codegen->invalid_instruction; + if (!ir_resolve_atomic_order(ira, order_inst, &order)) + return ira->codegen->invalid_inst_gen; if (order < AtomicOrderAcquire) { - ir_add_error(ira, order_value, + ir_add_error(ira, &order_inst->base, buf_sprintf("atomic ordering must be Acquire or stricter")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *result = ir_build_fence(&ira->new_irb, - instruction->base.scope, instruction->base.source_node, order_value, order); - result->value->type = ira->codegen->builtin_types.entry_void; - return result; + return ir_build_fence_gen(ira, &instruction->base.base, order); } -static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstructionTruncate *instruction) { - IrInstruction *dest_type_value = instruction->dest_type->child; +static IrInstGen *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstSrcTruncate *instruction) { + IrInstGen *dest_type_value = instruction->dest_type->child; ZigType *dest_type = ir_resolve_type(ira, dest_type_value); if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { - ir_add_error(ira, dest_type_value, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &dest_type_value->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); + return ira->codegen->invalid_inst_gen; } - IrInstruction *target = instruction->target->child; + IrInstGen *target = instruction->target->child; ZigType *src_type = target->value->type; if (type_is_invalid(src_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (src_type->id != ZigTypeIdInt && src_type->id != ZigTypeIdComptimeInt) { - ir_add_error(ira, target, buf_sprintf("expected integer type, found '%s'", buf_ptr(&src_type->name))); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &target->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&src_type->name))); + return ira->codegen->invalid_inst_gen; } if (dest_type->id == ZigTypeIdComptimeInt) { - return ir_implicit_cast(ira, target, dest_type); + return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); } if (instr_is_comptime(target)) { ZigValue *val = ir_resolve_const(ira, target, UndefBad); if (val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result = ir_const(ira, &instruction->base, dest_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, dest_type); bigint_truncate(&result->value->data.x_bigint, &val->data.x_bigint, dest_type->data.integral.bit_count, dest_type->data.integral.is_signed); return result; } if (src_type->data.integral.bit_count == 0 || dest_type->data.integral.bit_count == 0) { - IrInstruction *result = ir_const(ira, &instruction->base, dest_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, dest_type); bigint_init_unsigned(&result->value->data.x_bigint, 0); return result; } if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) { const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned"; - ir_add_error(ira, target, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name))); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &target->base, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name))); + return ira->codegen->invalid_inst_gen; } else if (src_type->data.integral.bit_count < dest_type->data.integral.bit_count) { - ir_add_error(ira, target, buf_sprintf("type '%s' has fewer bits than destination type '%s'", + ir_add_error(ira, &target->base, buf_sprintf("type '%s' has fewer bits than destination type '%s'", buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *new_instruction = ir_build_truncate(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, dest_type_value, target); - new_instruction->value->type = dest_type; - return new_instruction; + return ir_build_truncate_gen(ira, &instruction->base.base, dest_type, target); } -static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstructionIntCast *instruction) { +static IrInstGen *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstSrcIntCast *instruction) { ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { - ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->dest_type->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); + return ira->codegen->invalid_inst_gen; } - IrInstruction *target = instruction->target->child; + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (target->value->type->id != ZigTypeIdInt && target->value->type->id != ZigTypeIdComptimeInt) { - ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'", + ir_add_error(ira, &instruction->target->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&target->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(target)) { - return ir_implicit_cast(ira, target, dest_type); + return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); } if (dest_type->id == ZigTypeIdComptimeInt) { - ir_add_error(ira, instruction->target, buf_sprintf("attempt to cast runtime value to '%s'", + ir_add_error(ira, &instruction->target->base, buf_sprintf("attempt to cast runtime value to '%s'", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); + return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type); } -static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstructionFloatCast *instruction) { +static IrInstGen *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstSrcFloatCast *instruction) { ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (dest_type->id != ZigTypeIdFloat) { - ir_add_error(ira, instruction->dest_type, + ir_add_error(ira, &instruction->dest_type->base, buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *target = instruction->target->child; + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (target->value->type->id == ZigTypeIdComptimeInt || target->value->type->id == ZigTypeIdComptimeFloat) @@ -24369,55 +25374,55 @@ static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstru } else { op = CastOpNumLitToConcrete; } - return ir_resolve_cast(ira, &instruction->base, target, dest_type, op); + return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, op); } else { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } if (target->value->type->id != ZigTypeIdFloat) { - ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", + ir_add_error(ira, &instruction->target->base, buf_sprintf("expected float type, found '%s'", buf_ptr(&target->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); + return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type); } -static IrInstruction *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstructionErrSetCast *instruction) { +static IrInstGen *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstSrcErrSetCast *instruction) { ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (dest_type->id != ZigTypeIdErrorSet) { - ir_add_error(ira, instruction->dest_type, + ir_add_error(ira, &instruction->dest_type->base, buf_sprintf("expected error set type, found '%s'", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *target = instruction->target->child; + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (target->value->type->id != ZigTypeIdErrorSet) { - ir_add_error(ira, instruction->target, + ir_add_error(ira, &instruction->target->base, buf_sprintf("expected error set type, found '%s'", buf_ptr(&target->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - return ir_analyze_err_set_cast(ira, &instruction->base, target, dest_type); + return ir_analyze_err_set_cast(ira, &instruction->base.base, target, dest_type); } -static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstructionFromBytes *instruction) { +static IrInstGen *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstSrcFromBytes *instruction) { Error err; ZigType *dest_child_type = ir_resolve_type(ira, instruction->dest_child_type->child); if (type_is_invalid(dest_child_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *target = instruction->target->child; + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; bool src_ptr_const; bool src_ptr_volatile; @@ -24427,27 +25432,27 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru src_ptr_volatile = target->value->type->data.pointer.is_volatile; if ((err = resolve_ptr_align(ira, target->value->type, &src_ptr_align))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (is_slice(target->value->type)) { ZigType *src_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry; src_ptr_const = src_ptr_type->data.pointer.is_const; src_ptr_volatile = src_ptr_type->data.pointer.is_volatile; if ((err = resolve_ptr_align(ira, src_ptr_type, &src_ptr_align))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { src_ptr_const = true; src_ptr_volatile = false; if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusAlignmentKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; src_ptr_align = get_abi_alignment(ira->codegen, target->value->type); } if (src_ptr_align != 0) { if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusAlignmentKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_child_type, @@ -24460,9 +25465,9 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru src_ptr_align, 0, 0, false); ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); - IrInstruction *casted_value = ir_implicit_cast(ira, target, u8_slice); + IrInstGen *casted_value = ir_implicit_cast2(ira, &instruction->target->base, target, u8_slice); if (type_is_invalid(casted_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; bool have_known_len = false; uint64_t known_len; @@ -24470,7 +25475,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru if (instr_is_comptime(casted_value)) { ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *len_val = val->data.x_struct.fields[slice_len_index]; if (value_is_comptime(len_val)) { @@ -24479,9 +25484,9 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru } } - IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, - dest_slice_type, nullptr, true, false, true); - if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc))) { + IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, + dest_slice_type, nullptr, true, true); + if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) { return result_loc; } @@ -24498,41 +25503,41 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru if (have_known_len) { if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint64_t child_type_size = type_size(ira->codegen, dest_child_type); uint64_t remainder = known_len % child_type_size; if (remainder != 0) { - ErrorMsg *msg = ir_add_error(ira, &instruction->base, + ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, buf_sprintf("unable to convert [%" ZIG_PRI_u64 "]u8 to %s: size mismatch", known_len, buf_ptr(&dest_slice_type->name))); - add_error_note(ira->codegen, msg, instruction->dest_child_type->source_node, + add_error_note(ira->codegen, msg, instruction->dest_child_type->base.source_node, buf_sprintf("%s has size %" ZIG_PRI_u64 "; remaining bytes: %" ZIG_PRI_u64, buf_ptr(&dest_child_type->name), child_type_size, remainder)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } - return ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type, result_loc); + return ir_build_resize_slice(ira, &instruction->base.base, casted_value, dest_slice_type, result_loc); } -static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) { +static IrInstGen *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstSrcToBytes *instruction) { Error err; - IrInstruction *target = instruction->target->child; + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!is_slice(target->value->type)) { - ir_add_error(ira, instruction->target, + ir_add_error(ira, &instruction->target->base, buf_sprintf("expected slice, found '%s'", buf_ptr(&target->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *src_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry; uint32_t alignment; if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, src_ptr_type->data.pointer.is_const, src_ptr_type->data.pointer.is_volatile, PtrLenUnknown, @@ -24542,9 +25547,9 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct if (instr_is_comptime(target)) { ZigValue *target_val = ir_resolve_const(ira, target, UndefBad); if (target_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result = ir_const(ira, &instruction->base, dest_slice_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, dest_slice_type); result->value->data.x_struct.fields = alloc_const_vals_ptrs(2); ZigValue *ptr_val = result->value->data.x_struct.fields[slice_ptr_index]; @@ -24564,13 +25569,13 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct return result; } - IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, - dest_slice_type, nullptr, true, false, true); - if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { + IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, + dest_slice_type, nullptr, true, true); + if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { return result_loc; } - return ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type, result_loc); + return ir_build_resize_slice(ira, &instruction->base.base, target, dest_slice_type, result_loc); } static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { @@ -24587,26 +25592,26 @@ static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_ali return ErrorNone; } -static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstructionIntToFloat *instruction) { +static IrInstGen *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstSrcIntToFloat *instruction) { ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *target = instruction->target->child; + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (target->value->type->id != ZigTypeIdInt && target->value->type->id != ZigTypeIdComptimeInt) { - ir_add_error(ira, instruction->target, buf_sprintf("expected int type, found '%s'", + ir_add_error(ira, &instruction->target->base, buf_sprintf("expected int type, found '%s'", buf_ptr(&target->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat); + return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, CastOpIntToFloat); } -static IrInstruction *ir_analyze_float_to_int(IrAnalyze *ira, IrInstruction *source_instr, - ZigType *dest_type, IrInstruction *operand, AstNode *operand_source_node) +static IrInstGen *ir_analyze_float_to_int(IrAnalyze *ira, IrInst* source_instr, + ZigType *dest_type, IrInstGen *operand, AstNode *operand_source_node) { if (operand->value->type->id == ZigTypeIdComptimeInt) { return ir_implicit_cast(ira, operand, dest_type); @@ -24615,106 +25620,107 @@ static IrInstruction *ir_analyze_float_to_int(IrAnalyze *ira, IrInstruction *sou if (operand->value->type->id != ZigTypeIdFloat && operand->value->type->id != ZigTypeIdComptimeFloat) { ir_add_error_node(ira, operand_source_node, buf_sprintf("expected float type, found '%s'", buf_ptr(&operand->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } return ir_resolve_cast(ira, source_instr, operand, dest_type, CastOpFloatToInt); } -static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { +static IrInstGen *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstSrcFloatToInt *instruction) { ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *operand = instruction->target->child; + IrInstGen *operand = instruction->target->child; if (type_is_invalid(operand->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_float_to_int(ira, &instruction->base, dest_type, operand, instruction->target->source_node); + return ir_analyze_float_to_int(ira, &instruction->base.base, dest_type, operand, + instruction->target->base.source_node); } -static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) { - IrInstruction *target = instruction->target->child; +static IrInstGen *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstSrcErrToInt *instruction) { + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_target; + IrInstGen *casted_target; if (target->value->type->id == ZigTypeIdErrorSet) { casted_target = target; } else { casted_target = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_global_error_set); if (type_is_invalid(casted_target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - return ir_analyze_err_to_int(ira, &instruction->base, casted_target, ira->codegen->err_tag_type); + return ir_analyze_err_to_int(ira, &instruction->base.base, casted_target, ira->codegen->err_tag_type); } -static IrInstruction *ir_analyze_instruction_int_to_err(IrAnalyze *ira, IrInstructionIntToErr *instruction) { - IrInstruction *target = instruction->target->child; +static IrInstGen *ir_analyze_instruction_int_to_err(IrAnalyze *ira, IrInstSrcIntToErr *instruction) { + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_target = ir_implicit_cast(ira, target, ira->codegen->err_tag_type); + IrInstGen *casted_target = ir_implicit_cast(ira, target, ira->codegen->err_tag_type); if (type_is_invalid(casted_target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_int_to_err(ira, &instruction->base, casted_target, ira->codegen->builtin_types.entry_global_error_set); + return ir_analyze_int_to_err(ira, &instruction->base.base, casted_target, ira->codegen->builtin_types.entry_global_error_set); } -static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstructionBoolToInt *instruction) { - IrInstruction *target = instruction->target->child; +static IrInstGen *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstSrcBoolToInt *instruction) { + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (target->value->type->id != ZigTypeIdBool) { - ir_add_error(ira, instruction->target, buf_sprintf("expected bool, found '%s'", + ir_add_error(ira, &instruction->target->base, buf_sprintf("expected bool, found '%s'", buf_ptr(&target->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(target)) { bool is_true; if (!ir_resolve_bool(ira, target, &is_true)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_const_unsigned(ira, &instruction->base, is_true ? 1 : 0); + return ir_const_unsigned(ira, &instruction->base.base, is_true ? 1 : 0); } ZigType *u1_type = get_int_type(ira->codegen, false, 1); - return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt); + return ir_resolve_cast(ira, &instruction->base.base, target, u1_type, CastOpBoolToInt); } -static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { - IrInstruction *is_signed_value = instruction->is_signed->child; +static IrInstGen *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstSrcIntType *instruction) { + IrInstGen *is_signed_value = instruction->is_signed->child; bool is_signed; if (!ir_resolve_bool(ira, is_signed_value, &is_signed)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *bit_count_value = instruction->bit_count->child; + IrInstGen *bit_count_value = instruction->bit_count->child; uint64_t bit_count; if (!ir_resolve_unsigned(ira, bit_count_value, ira->codegen->builtin_types.entry_u16, &bit_count)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_const_type(ira, &instruction->base, get_int_type(ira->codegen, is_signed, (uint32_t)bit_count)); + return ir_const_type(ira, &instruction->base.base, get_int_type(ira->codegen, is_signed, (uint32_t)bit_count)); } -static IrInstruction *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstructionVectorType *instruction) { +static IrInstGen *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstSrcVectorType *instruction) { uint64_t len; if (!ir_resolve_unsigned(ira, instruction->len->child, ira->codegen->builtin_types.entry_u32, &len)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *elem_type = ir_resolve_vector_elem_type(ira, instruction->elem_type->child); if (type_is_invalid(elem_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *vector_type = get_vector_type(ira->codegen, len, elem_type); - return ir_const_type(ira, &instruction->base, vector_type); + return ir_const_type(ira, &instruction->base.base, vector_type); } -static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *source_instr, - ZigType *scalar_type, IrInstruction *a, IrInstruction *b, IrInstruction *mask) +static IrInstGen *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInst* source_instr, + ZigType *scalar_type, IrInstGen *a, IrInstGen *b, IrInstGen *mask) { ir_assert(source_instr && scalar_type && a && b && mask, source_instr); ir_assert(is_valid_vector_elem_type(scalar_type), source_instr); @@ -24725,15 +25731,15 @@ static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *s } else if (mask->value->type->id == ZigTypeIdArray) { len_mask = mask->value->type->data.array.len; } else { - ir_add_error(ira, mask, + ir_add_error(ira, &mask->base, buf_sprintf("expected vector or array, found '%s'", buf_ptr(&mask->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } mask = ir_implicit_cast(ira, mask, get_vector_type(ira->codegen, len_mask, ira->codegen->builtin_types.entry_i32)); if (type_is_invalid(mask->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint32_t len_a; if (a->value->type->id == ZigTypeIdVector) { @@ -24743,11 +25749,11 @@ static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *s } else if (a->value->type->id == ZigTypeIdUndefined) { len_a = UINT32_MAX; } else { - ir_add_error(ira, a, + ir_add_error(ira, &a->base, buf_sprintf("expected vector or array with element type '%s', found '%s'", buf_ptr(&scalar_type->name), buf_ptr(&a->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } uint32_t len_b; @@ -24758,38 +25764,38 @@ static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *s } else if (b->value->type->id == ZigTypeIdUndefined) { len_b = UINT32_MAX; } else { - ir_add_error(ira, b, + ir_add_error(ira, &b->base, buf_sprintf("expected vector or array with element type '%s', found '%s'", buf_ptr(&scalar_type->name), buf_ptr(&b->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (len_a == UINT32_MAX && len_b == UINT32_MAX) { - return ir_const_undef(ira, a, get_vector_type(ira->codegen, len_mask, scalar_type)); + return ir_const_undef(ira, &a->base, get_vector_type(ira->codegen, len_mask, scalar_type)); } if (len_a == UINT32_MAX) { len_a = len_b; - a = ir_const_undef(ira, a, get_vector_type(ira->codegen, len_a, scalar_type)); + a = ir_const_undef(ira, &a->base, get_vector_type(ira->codegen, len_a, scalar_type)); } else { a = ir_implicit_cast(ira, a, get_vector_type(ira->codegen, len_a, scalar_type)); if (type_is_invalid(a->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (len_b == UINT32_MAX) { len_b = len_a; - b = ir_const_undef(ira, b, get_vector_type(ira->codegen, len_b, scalar_type)); + b = ir_const_undef(ira, &b->base, get_vector_type(ira->codegen, len_b, scalar_type)); } else { b = ir_implicit_cast(ira, b, get_vector_type(ira->codegen, len_b, scalar_type)); if (type_is_invalid(b->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigValue *mask_val = ir_resolve_const(ira, mask, UndefOk); if (mask_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; expand_undef_array(ira->codegen, mask_val); @@ -24799,7 +25805,7 @@ static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *s continue; int32_t v_i32 = bigint_as_signed(&mask_elem_val->data.x_bigint); uint32_t v; - IrInstruction *chosen_operand; + IrInstGen *chosen_operand; if (v_i32 >= 0) { v = (uint32_t)v_i32; chosen_operand = a; @@ -24808,16 +25814,16 @@ static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *s chosen_operand = b; } if (v >= chosen_operand->value->type->data.vector.len) { - ErrorMsg *msg = ir_add_error(ira, mask, + ErrorMsg *msg = ir_add_error(ira, &mask->base, buf_sprintf("mask index '%u' has out-of-bounds selection", i)); - add_error_note(ira->codegen, msg, chosen_operand->source_node, + add_error_note(ira->codegen, msg, chosen_operand->base.source_node, buf_sprintf("selected index '%u' out of bounds of %s", v, buf_ptr(&chosen_operand->value->type->name))); if (chosen_operand == a && v < len_a + len_b) { - add_error_note(ira->codegen, msg, b->source_node, + add_error_note(ira->codegen, msg, b->base.source_node, buf_create_from_str("selections from the second vector are specified with negative numbers")); } - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } @@ -24825,16 +25831,16 @@ static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *s if (instr_is_comptime(a) && instr_is_comptime(b)) { ZigValue *a_val = ir_resolve_const(ira, a, UndefOk); if (a_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *b_val = ir_resolve_const(ira, b, UndefOk); if (b_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; expand_undef_array(ira->codegen, a_val); expand_undef_array(ira->codegen, b_val); - IrInstruction *result = ir_const(ira, source_instr, result_type); + IrInstGen *result = ir_const(ira, source_instr, result_type); result->value->data.x_array.data.s_none.elements = create_const_vals(len_mask); for (uint32_t i = 0; i < mask_val->type->data.vector.len; i += 1) { ZigValue *mask_elem_val = &mask_val->data.x_array.data.s_none.elements[i]; @@ -24866,7 +25872,7 @@ static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *s uint32_t len_min = min(len_a, len_b); uint32_t len_max = max(len_a, len_b); - IrInstruction *expand_mask = ir_const(ira, mask, + IrInstGen *expand_mask = ir_const(ira, &mask->base, get_vector_type(ira->codegen, len_max, ira->codegen->builtin_types.entry_i32)); expand_mask->value->data.x_array.data.s_none.elements = create_const_vals(len_max); uint32_t i = 0; @@ -24875,7 +25881,7 @@ static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *s for (; i < len_max; i += 1) bigint_init_signed(&expand_mask->value->data.x_array.data.s_none.elements[i].data.x_bigint, -1); - IrInstruction *undef = ir_const_undef(ira, source_instr, + IrInstGen *undef = ir_const_undef(ira, source_instr, get_vector_type(ira->codegen, len_min, scalar_type)); if (len_b < len_a) { @@ -24885,62 +25891,59 @@ static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *s } } - IrInstruction *result = ir_build_shuffle_vector(&ira->new_irb, - source_instr->scope, source_instr->source_node, - nullptr, a, b, mask); - result->value->type = result_type; - return result; + return ir_build_shuffle_vector_gen(ira, source_instr->scope, source_instr->source_node, + result_type, a, b, mask); } -static IrInstruction *ir_analyze_instruction_shuffle_vector(IrAnalyze *ira, IrInstructionShuffleVector *instruction) { - ZigType *scalar_type = ir_resolve_vector_elem_type(ira, instruction->scalar_type); +static IrInstGen *ir_analyze_instruction_shuffle_vector(IrAnalyze *ira, IrInstSrcShuffleVector *instruction) { + ZigType *scalar_type = ir_resolve_vector_elem_type(ira, instruction->scalar_type->child); if (type_is_invalid(scalar_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *a = instruction->a->child; + IrInstGen *a = instruction->a->child; if (type_is_invalid(a->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *b = instruction->b->child; + IrInstGen *b = instruction->b->child; if (type_is_invalid(b->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *mask = instruction->mask->child; + IrInstGen *mask = instruction->mask->child; if (type_is_invalid(mask->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_shuffle_vector(ira, &instruction->base, scalar_type, a, b, mask); + return ir_analyze_shuffle_vector(ira, &instruction->base.base, scalar_type, a, b, mask); } -static IrInstruction *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstructionSplatSrc *instruction) { +static IrInstGen *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstSrcSplat *instruction) { Error err; - IrInstruction *len = instruction->len->child; + IrInstGen *len = instruction->len->child; if (type_is_invalid(len->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *scalar = instruction->scalar->child; + IrInstGen *scalar = instruction->scalar->child; if (type_is_invalid(scalar->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint64_t len_u64; if (!ir_resolve_unsigned(ira, len, ira->codegen->builtin_types.entry_u32, &len_u64)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint32_t len_int = len_u64; - if ((err = ir_validate_vector_elem_type(ira, scalar, scalar->value->type))) - return ira->codegen->invalid_instruction; + if ((err = ir_validate_vector_elem_type(ira, scalar->base.source_node, scalar->value->type))) + return ira->codegen->invalid_inst_gen; ZigType *return_type = get_vector_type(ira->codegen, len_int, scalar->value->type); if (instr_is_comptime(scalar)) { ZigValue *scalar_val = ir_resolve_const(ira, scalar, UndefOk); if (scalar_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (scalar_val->special == ConstValSpecialUndef) - return ir_const_undef(ira, &instruction->base, return_type); + return ir_const_undef(ira, &instruction->base.base, return_type); - IrInstruction *result = ir_const(ira, &instruction->base, return_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, return_type); result->value->data.x_array.data.s_none.elements = create_const_vals(len_int); for (uint32_t i = 0; i < len_int; i += 1) { copy_const_val(&result->value->data.x_array.data.s_none.elements[i], scalar_val); @@ -24948,48 +25951,45 @@ static IrInstruction *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstruction return result; } - return ir_build_splat_gen(ira, &instruction->base, return_type, scalar); + return ir_build_splat_gen(ira, &instruction->base.base, return_type, scalar); } -static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) { - IrInstruction *value = instruction->value->child; +static IrInstGen *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstSrcBoolNot *instruction) { + IrInstGen *value = instruction->value->child; if (type_is_invalid(value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *bool_type = ira->codegen->builtin_types.entry_bool; - IrInstruction *casted_value = ir_implicit_cast(ira, value, bool_type); + IrInstGen *casted_value = ir_implicit_cast(ira, value, bool_type); if (type_is_invalid(casted_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (instr_is_comptime(casted_value)) { ZigValue *value = ir_resolve_const(ira, casted_value, UndefBad); if (value == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_const_bool(ira, &instruction->base, !value->data.x_bool); + return ir_const_bool(ira, &instruction->base.base, !value->data.x_bool); } - IrInstruction *result = ir_build_bool_not(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, casted_value); - result->value->type = bool_type; - return result; + return ir_build_bool_not_gen(ira, &instruction->base.base, casted_value); } -static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemset *instruction) { +static IrInstGen *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstSrcMemset *instruction) { Error err; - IrInstruction *dest_ptr = instruction->dest_ptr->child; + IrInstGen *dest_ptr = instruction->dest_ptr->child; if (type_is_invalid(dest_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *byte_value = instruction->byte->child; + IrInstGen *byte_value = instruction->byte->child; if (type_is_invalid(byte_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *count_value = instruction->count->child; + IrInstGen *count_value = instruction->count->child; if (type_is_invalid(count_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *dest_uncasted_type = dest_ptr->value->type; bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && @@ -25000,24 +26000,24 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio uint32_t dest_align; if (dest_uncasted_type->id == ZigTypeIdPointer) { if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { dest_align = get_abi_alignment(ira->codegen, u8); } ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, PtrLenUnknown, dest_align, 0, 0, false); - IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr); + IrInstGen *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr); if (type_is_invalid(casted_dest_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_byte = ir_implicit_cast(ira, byte_value, u8); + IrInstGen *casted_byte = ir_implicit_cast(ira, byte_value, u8); if (type_is_invalid(casted_byte->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_count = ir_implicit_cast(ira, count_value, usize); + IrInstGen *casted_count = ir_implicit_cast(ira, count_value, usize); if (type_is_invalid(casted_count->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // TODO test this at comptime with u8 and non-u8 types if (instr_is_comptime(casted_dest_ptr) && @@ -25026,15 +26026,15 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio { ZigValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); if (dest_ptr_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *byte_val = ir_resolve_const(ira, casted_byte, UndefOk); if (byte_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); if (count_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (casted_dest_ptr->value->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && casted_dest_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) @@ -25079,38 +26079,35 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio size_t count = bigint_as_usize(&count_val->data.x_bigint); size_t end = start + count; if (end > bound_end) { - ir_add_error(ira, count_value, buf_sprintf("out of bounds pointer access")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &count_value->base, buf_sprintf("out of bounds pointer access")); + return ira->codegen->invalid_inst_gen; } for (size_t i = start; i < end; i += 1) { copy_const_val(&dest_elements[i], byte_val); } - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } } - IrInstruction *result = ir_build_memset(&ira->new_irb, instruction->base.scope, instruction->base.source_node, - casted_dest_ptr, casted_byte, casted_count); - result->value->type = ira->codegen->builtin_types.entry_void; - return result; + return ir_build_memset_gen(ira, &instruction->base.base, casted_dest_ptr, casted_byte, casted_count); } -static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcpy *instruction) { +static IrInstGen *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstSrcMemcpy *instruction) { Error err; - IrInstruction *dest_ptr = instruction->dest_ptr->child; + IrInstGen *dest_ptr = instruction->dest_ptr->child; if (type_is_invalid(dest_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *src_ptr = instruction->src_ptr->child; + IrInstGen *src_ptr = instruction->src_ptr->child; if (type_is_invalid(src_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *count_value = instruction->count->child; + IrInstGen *count_value = instruction->count->child; if (type_is_invalid(count_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *u8 = ira->codegen->builtin_types.entry_u8; ZigType *dest_uncasted_type = dest_ptr->value->type; @@ -25123,7 +26120,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio uint32_t dest_align; if (dest_uncasted_type->id == ZigTypeIdPointer) { if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { dest_align = get_abi_alignment(ira->codegen, u8); } @@ -25131,7 +26128,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio uint32_t src_align; if (src_uncasted_type->id == ZigTypeIdPointer) { if ((err = resolve_ptr_align(ira, src_uncasted_type, &src_align))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { src_align = get_abi_alignment(ira->codegen, u8); } @@ -25142,17 +26139,17 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio ZigType *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, src_is_volatile, PtrLenUnknown, src_align, 0, 0, false); - IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut); + IrInstGen *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut); if (type_is_invalid(casted_dest_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_src_ptr = ir_implicit_cast(ira, src_ptr, u8_ptr_const); + IrInstGen *casted_src_ptr = ir_implicit_cast(ira, src_ptr, u8_ptr_const); if (type_is_invalid(casted_src_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_count = ir_implicit_cast(ira, count_value, usize); + IrInstGen *casted_count = ir_implicit_cast(ira, count_value, usize); if (type_is_invalid(casted_count->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // TODO test this at comptime with u8 and non-u8 types // TODO test with dest ptr being a global runtime variable @@ -25162,15 +26159,15 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio { ZigValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); if (dest_ptr_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *src_ptr_val = ir_resolve_const(ira, casted_src_ptr, UndefBad); if (src_ptr_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); if (count_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (dest_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { size_t count = bigint_as_usize(&count_val->data.x_bigint); @@ -25213,8 +26210,8 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio } if (dest_start + count > dest_end) { - ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds pointer access")); + return ira->codegen->invalid_inst_gen; } ZigValue *src_elements; @@ -25256,8 +26253,8 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio } if (src_start + count > src_end) { - ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds pointer access")); + return ira->codegen->invalid_inst_gen; } // TODO check for noalias violations - this should be generalized to work for any function @@ -25266,42 +26263,39 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i]); } - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } } - IrInstruction *result = ir_build_memcpy(&ira->new_irb, instruction->base.scope, instruction->base.source_node, - casted_dest_ptr, casted_src_ptr, casted_count); - result->value->type = ira->codegen->builtin_types.entry_void; - return result; + return ir_build_memcpy_gen(ira, &instruction->base.base, casted_dest_ptr, casted_src_ptr, casted_count); } -static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSliceSrc *instruction) { - IrInstruction *ptr_ptr = instruction->ptr->child; +static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *instruction) { + IrInstGen *ptr_ptr = instruction->ptr->child; if (type_is_invalid(ptr_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *ptr_ptr_type = ptr_ptr->value->type; assert(ptr_ptr_type->id == ZigTypeIdPointer); ZigType *array_type = ptr_ptr_type->data.pointer.child_type; - IrInstruction *start = instruction->start->child; + IrInstGen *start = instruction->start->child; if (type_is_invalid(start->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *usize = ira->codegen->builtin_types.entry_usize; - IrInstruction *casted_start = ir_implicit_cast(ira, start, usize); + IrInstGen *casted_start = ir_implicit_cast(ira, start, usize); if (type_is_invalid(casted_start->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *end; + IrInstGen *end; if (instruction->end) { end = instruction->end->child; if (type_is_invalid(end->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; end = ir_implicit_cast(ira, end, usize); if (type_is_invalid(end->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { end = nullptr; } @@ -25329,8 +26323,8 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction PtrLenUnknown, array_type->data.pointer.explicit_alignment, 0, 0, false); } else { - ir_add_error(ira, &instruction->base, buf_sprintf("slice of single-item pointer")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of single-item pointer")); + return ira->codegen->invalid_inst_gen; } } else { elem_type = array_type->data.pointer.child_type; @@ -25340,8 +26334,8 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction ZigType *maybe_sentineled_slice_ptr_type = array_type; non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr); if (!end) { - ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of pointer must include end value")); + return ira->codegen->invalid_inst_gen; } } } else if (is_slice(array_type)) { @@ -25349,23 +26343,23 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr); elem_type = non_sentinel_slice_ptr_type->data.pointer.child_type; } else { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of non-array type '%s'", buf_ptr(&array_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *return_type; ZigValue *sentinel_val = nullptr; if (instruction->sentinel) { - IrInstruction *uncasted_sentinel = instruction->sentinel->child; + IrInstGen *uncasted_sentinel = instruction->sentinel->child; if (type_is_invalid(uncasted_sentinel->value->type)) - return ira->codegen->invalid_instruction; - IrInstruction *sentinel = ir_implicit_cast(ira, uncasted_sentinel, elem_type); + return ira->codegen->invalid_inst_gen; + IrInstGen *sentinel = ir_implicit_cast(ira, uncasted_sentinel, elem_type); if (type_is_invalid(sentinel->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); if (sentinel_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *slice_ptr_type = adjust_ptr_sentinel(ira->codegen, non_sentinel_slice_ptr_type, sentinel_val); return_type = get_slice_type(ira->codegen, slice_ptr_type); } else { @@ -25387,9 +26381,9 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction if (array_type->id == ZigTypeIdPointer) { ZigType *child_array_type = array_type->data.pointer.child_type; assert(child_array_type->id == ZigTypeIdArray); - parent_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.source_node); + parent_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); if (parent_ptr == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (parent_ptr->special == ConstValSpecialUndef) { @@ -25398,26 +26392,26 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction rel_end = SIZE_MAX; ptr_is_undef = true; } else { - array_val = const_ptr_pointee(ira, ira->codegen, parent_ptr, instruction->base.source_node); + array_val = const_ptr_pointee(ira, ira->codegen, parent_ptr, instruction->base.base.source_node); if (array_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; rel_end = child_array_type->data.array.len; abs_offset = 0; } } else { - array_val = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.source_node); + array_val = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); if (array_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; rel_end = array_type->data.array.len; parent_ptr = nullptr; abs_offset = 0; } } else if (array_type->id == ZigTypeIdPointer) { assert(array_type->data.pointer.ptr_len == PtrLenUnknown); - parent_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.source_node); + parent_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); if (parent_ptr == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (parent_ptr->special == ConstValSpecialUndef) { array_val = nullptr; @@ -25463,19 +26457,19 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction zig_panic("TODO slice of null ptr"); } } else if (is_slice(array_type)) { - ZigValue *slice_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.source_node); + ZigValue *slice_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); if (slice_ptr == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (slice_ptr->special == ConstValSpecialUndef) { - ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of undefined")); + return ira->codegen->invalid_inst_gen; } parent_ptr = slice_ptr->data.x_struct.fields[slice_ptr_index]; if (parent_ptr->special == ConstValSpecialUndef) { - ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of undefined")); + return ira->codegen->invalid_inst_gen; } ZigValue *len_val = slice_ptr->data.x_struct.fields[slice_len_index]; @@ -25518,37 +26512,37 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction ZigValue *start_val = ir_resolve_const(ira, casted_start, UndefBad); if (!start_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint64_t start_scalar = bigint_as_u64(&start_val->data.x_bigint); if (!ptr_is_undef && start_scalar > rel_end) { - ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds slice")); + return ira->codegen->invalid_inst_gen; } uint64_t end_scalar = rel_end; if (end) { ZigValue *end_val = ir_resolve_const(ira, end, UndefBad); if (!end_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; end_scalar = bigint_as_u64(&end_val->data.x_bigint); } if (!ptr_is_undef) { if (end_scalar > rel_end) { - ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds slice")); + return ira->codegen->invalid_inst_gen; } if (start_scalar > end_scalar) { - ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("slice start is greater than end")); + return ira->codegen->invalid_inst_gen; } } if (ptr_is_undef && start_scalar != end_scalar) { - ir_add_error(ira, &instruction->base, buf_sprintf("non-zero length slice of undefined pointer")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("non-zero length slice of undefined pointer")); + return ira->codegen->invalid_inst_gen; } - IrInstruction *result = ir_const(ira, &instruction->base, return_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, return_type); ZigValue *out_val = result->value; out_val->data.x_struct.fields = alloc_const_vals_ptrs(2); @@ -25605,28 +26599,28 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction return result; } - IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, - return_type, nullptr, true, false, true); - if (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc)) { + IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, + return_type, nullptr, true, true); + if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { return result_loc; } - return ir_build_slice_gen(ira, &instruction->base, return_type, + return ir_build_slice_gen(ira, &instruction->base.base, return_type, ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc); } -static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) { +static IrInstGen *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstSrcMemberCount *instruction) { Error err; - IrInstruction *container = instruction->container->child; + IrInstGen *container = instruction->container->child; if (type_is_invalid(container->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *container_type = ir_resolve_type(ira, container); if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint64_t result; if (type_is_invalid(container_type)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (container_type->id == ZigTypeIdEnum) { result = container_type->data.enumeration.src_field_count; } else if (container_type->id == ZigTypeIdStruct) { @@ -25634,135 +26628,135 @@ static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInst } else if (container_type->id == ZigTypeIdUnion) { result = container_type->data.unionation.src_field_count; } else if (container_type->id == ZigTypeIdErrorSet) { - if (!resolve_inferred_error_set(ira->codegen, container_type, instruction->base.source_node)) { - return ira->codegen->invalid_instruction; + if (!resolve_inferred_error_set(ira->codegen, container_type, instruction->base.base.source_node)) { + return ira->codegen->invalid_inst_gen; } if (type_is_global_error_set(container_type)) { - ir_add_error(ira, &instruction->base, buf_sprintf("global error set member count not available at comptime")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("global error set member count not available at comptime")); + return ira->codegen->invalid_inst_gen; } result = container_type->data.error_set.err_count; } else { - ir_add_error(ira, &instruction->base, buf_sprintf("no value count available for type '%s'", buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("no value count available for type '%s'", buf_ptr(&container_type->name))); + return ira->codegen->invalid_inst_gen; } - return ir_const_unsigned(ira, &instruction->base, result); + return ir_const_unsigned(ira, &instruction->base.base, result); } -static IrInstruction *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstructionMemberType *instruction) { +static IrInstGen *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstSrcMemberType *instruction) { Error err; - IrInstruction *container_type_value = instruction->container_type->child; + IrInstGen *container_type_value = instruction->container_type->child; ZigType *container_type = ir_resolve_type(ira, container_type_value); if (type_is_invalid(container_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint64_t member_index; - IrInstruction *index_value = instruction->member_index->child; + IrInstGen *index_value = instruction->member_index->child; if (!ir_resolve_usize(ira, index_value, &member_index)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (container_type->id == ZigTypeIdStruct) { if (member_index >= container_type->data.structure.src_field_count) { - ir_add_error(ira, index_value, + ir_add_error(ira, &index_value->base, buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } TypeStructField *field = container_type->data.structure.fields[member_index]; - return ir_const_type(ira, &instruction->base, field->type_entry); + return ir_const_type(ira, &instruction->base.base, field->type_entry); } else if (container_type->id == ZigTypeIdUnion) { if (member_index >= container_type->data.unionation.src_field_count) { - ir_add_error(ira, index_value, + ir_add_error(ira, &index_value->base, buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } TypeUnionField *field = &container_type->data.unionation.fields[member_index]; - return ir_const_type(ira, &instruction->base, field->type_entry); + return ir_const_type(ira, &instruction->base.base, field->type_entry); } else { - ir_add_error(ira, container_type_value, + ir_add_error(ira, &container_type_value->base, buf_sprintf("type '%s' does not support @memberType", buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } -static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstructionMemberName *instruction) { +static IrInstGen *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstSrcMemberName *instruction) { Error err; - IrInstruction *container_type_value = instruction->container_type->child; + IrInstGen *container_type_value = instruction->container_type->child; ZigType *container_type = ir_resolve_type(ira, container_type_value); if (type_is_invalid(container_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint64_t member_index; - IrInstruction *index_value = instruction->member_index->child; + IrInstGen *index_value = instruction->member_index->child; if (!ir_resolve_usize(ira, index_value, &member_index)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (container_type->id == ZigTypeIdStruct) { if (member_index >= container_type->data.structure.src_field_count) { - ir_add_error(ira, index_value, + ir_add_error(ira, &index_value->base, buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } TypeStructField *field = container_type->data.structure.fields[member_index]; - IrInstruction *result = ir_const(ira, &instruction->base, nullptr); + IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); init_const_str_lit(ira->codegen, result->value, field->name); return result; } else if (container_type->id == ZigTypeIdEnum) { if (member_index >= container_type->data.enumeration.src_field_count) { - ir_add_error(ira, index_value, + ir_add_error(ira, &index_value->base, buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", member_index, buf_ptr(&container_type->name), container_type->data.enumeration.src_field_count)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } TypeEnumField *field = &container_type->data.enumeration.fields[member_index]; - IrInstruction *result = ir_const(ira, &instruction->base, nullptr); + IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); init_const_str_lit(ira->codegen, result->value, field->name); return result; } else if (container_type->id == ZigTypeIdUnion) { if (member_index >= container_type->data.unionation.src_field_count) { - ir_add_error(ira, index_value, + ir_add_error(ira, &index_value->base, buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } TypeUnionField *field = &container_type->data.unionation.fields[member_index]; - IrInstruction *result = ir_const(ira, &instruction->base, nullptr); + IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); init_const_str_lit(ira->codegen, result->value, field->name); return result; } else { - ir_add_error(ira, container_type_value, + ir_add_error(ira, &container_type_value->base, buf_sprintf("type '%s' does not support @memberName", buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } -static IrInstruction *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstructionHasField *instruction) { +static IrInstGen *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstSrcHasField *instruction) { Error err; ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); if (type_is_invalid(container_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if ((err = type_resolve(ira->codegen, container_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); if (field_name == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; bool result; if (container_type->id == ZigTypeIdStruct) { @@ -25772,91 +26766,77 @@ static IrInstruction *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstruc } else if (container_type->id == ZigTypeIdUnion) { result = find_union_type_field(container_type, field_name) != nullptr; } else { - ir_add_error(ira, instruction->container_type, + ir_add_error(ira, &instruction->container_type->base, buf_sprintf("type '%s' does not support @hasField", buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - return ir_const_bool(ira, &instruction->base, result); + return ir_const_bool(ira, &instruction->base.base, result); } -static IrInstruction *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstructionBreakpoint *instruction) { - IrInstruction *result = ir_build_breakpoint(&ira->new_irb, - instruction->base.scope, instruction->base.source_node); - result->value->type = ira->codegen->builtin_types.entry_void; - return result; +static IrInstGen *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstSrcBreakpoint *instruction) { + return ir_build_breakpoint_gen(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_return_address(IrAnalyze *ira, IrInstructionReturnAddress *instruction) { - IrInstruction *result = ir_build_return_address(&ira->new_irb, - instruction->base.scope, instruction->base.source_node); - result->value->type = ira->codegen->builtin_types.entry_usize; - return result; +static IrInstGen *ir_analyze_instruction_return_address(IrAnalyze *ira, IrInstSrcReturnAddress *instruction) { + return ir_build_return_address_gen(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstructionFrameAddress *instruction) { - IrInstruction *result = ir_build_frame_address(&ira->new_irb, - instruction->base.scope, instruction->base.source_node); - result->value->type = ira->codegen->builtin_types.entry_usize; - return result; +static IrInstGen *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstSrcFrameAddress *instruction) { + return ir_build_frame_address_gen(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_frame_handle(IrAnalyze *ira, IrInstructionFrameHandle *instruction) { - ZigFn *fn = exec_fn_entry(ira->new_irb.exec); - ir_assert(fn != nullptr, &instruction->base); +static IrInstGen *ir_analyze_instruction_frame_handle(IrAnalyze *ira, IrInstSrcFrameHandle *instruction) { + ZigFn *fn = ira->new_irb.exec->fn_entry; + ir_assert(fn != nullptr, &instruction->base.base); if (fn->inferred_async_node == nullptr) { - fn->inferred_async_node = instruction->base.source_node; + fn->inferred_async_node = instruction->base.base.source_node; } ZigType *frame_type = get_fn_frame_type(ira->codegen, fn); ZigType *ptr_frame_type = get_pointer_to_type(ira->codegen, frame_type, false); - IrInstruction *result = ir_build_handle(&ira->new_irb, instruction->base.scope, instruction->base.source_node); - result->value->type = ptr_frame_type; - return result; + return ir_build_handle_gen(ira, &instruction->base.base, ptr_frame_type); } -static IrInstruction *ir_analyze_instruction_frame_type(IrAnalyze *ira, IrInstructionFrameType *instruction) { +static IrInstGen *ir_analyze_instruction_frame_type(IrAnalyze *ira, IrInstSrcFrameType *instruction) { ZigFn *fn = ir_resolve_fn(ira, instruction->fn->child); if (fn == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (fn->type_entry->data.fn.is_generic) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("@Frame() of generic function")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *ty = get_fn_frame_type(ira->codegen, fn); - return ir_const_type(ira, &instruction->base, ty); + return ir_const_type(ira, &instruction->base.base, ty); } -static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstructionFrameSizeSrc *instruction) { - IrInstruction *fn = instruction->fn->child; +static IrInstGen *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstSrcFrameSize *instruction) { + IrInstGen *fn = instruction->fn->child; if (type_is_invalid(fn->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (fn->value->type->id != ZigTypeIdFn) { - ir_add_error(ira, fn, + ir_add_error(ira, &fn->base, buf_sprintf("expected function, found '%s'", buf_ptr(&fn->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ira->codegen->need_frame_size_prefix_data = true; - IrInstruction *result = ir_build_frame_size_gen(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, fn); - result->value->type = ira->codegen->builtin_types.entry_usize; - return result; + return ir_build_frame_size_gen(ira, &instruction->base.base, fn); } -static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { +static IrInstGen *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstSrcAlignOf *instruction) { // Here we create a lazy value in order to avoid resolving the alignment of the type // immediately. This avoids false positive dependency loops such as: // const Node = struct { // field: []align(@alignOf(Node)) Node, // }; - IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); + IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); result->value->special = ConstValSpecialLazy; LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1, "LazyValueAlignOf"); @@ -25866,41 +26846,41 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct lazy_align_of->target_type = instruction->type_value->child; if (ir_resolve_type_lazy(ira, lazy_align_of->target_type) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return result; } -static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { +static IrInstGen *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstSrcOverflowOp *instruction) { Error err; - IrInstruction *type_value = instruction->type_value->child; + IrInstGen *type_value = instruction->type_value->child; if (type_is_invalid(type_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *dest_type = ir_resolve_type(ira, type_value); if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (dest_type->id != ZigTypeIdInt) { - ir_add_error(ira, type_value, + ir_add_error(ira, &type_value->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *op1 = instruction->op1->child; + IrInstGen *op1 = instruction->op1->child; if (type_is_invalid(op1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, dest_type); + IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, dest_type); if (type_is_invalid(casted_op1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *op2 = instruction->op2->child; + IrInstGen *op2 = instruction->op2->child; if (type_is_invalid(op2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_op2; + IrInstGen *casted_op2; if (instruction->op == IrOverflowOpShl) { ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, dest_type->data.integral.bit_count - 1); @@ -25909,17 +26889,17 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr casted_op2 = ir_implicit_cast(ira, op2, dest_type); } if (type_is_invalid(casted_op2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result_ptr = instruction->result_ptr->child; + IrInstGen *result_ptr = instruction->result_ptr->child; if (type_is_invalid(result_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *expected_ptr_type; if (result_ptr->value->type->id == ZigTypeIdPointer) { uint32_t alignment; if ((err = resolve_ptr_align(ira, result_ptr->value->type, &alignment))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; expected_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_type, false, result_ptr->value->type->data.pointer.is_volatile, PtrLenSingle, @@ -25928,9 +26908,9 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false); } - IrInstruction *casted_result_ptr = ir_implicit_cast(ira, result_ptr, expected_ptr_type); + IrInstGen *casted_result_ptr = ir_implicit_cast(ira, result_ptr, expected_ptr_type); if (type_is_invalid(casted_result_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2) && @@ -25938,22 +26918,22 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr { ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); if (op1_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); if (op2_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *result_val = ir_resolve_const(ira, casted_result_ptr, UndefBad); if (result_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; BigInt *op1_bigint = &op1_val->data.x_bigint; BigInt *op2_bigint = &op2_val->data.x_bigint; ZigValue *pointee_val = const_ptr_pointee(ira, ira->codegen, result_val, - casted_result_ptr->source_node); + casted_result_ptr->base.source_node); if (pointee_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; BigInt *dest_bigint = &pointee_val->data.x_bigint; switch (instruction->op) { case IrOverflowOpAdd: @@ -25980,17 +26960,14 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr dest_type->data.integral.is_signed); } pointee_val->special = ConstValSpecialStatic; - return ir_const_bool(ira, &instruction->base, result_bool); + return ir_const_bool(ira, &instruction->base.base, result_bool); } - IrInstruction *result = ir_build_overflow_op(&ira->new_irb, - instruction->base.scope, instruction->base.source_node, - instruction->op, type_value, casted_op1, casted_op2, casted_result_ptr, dest_type); - result->value->type = ira->codegen->builtin_types.entry_bool; - return result; + return ir_build_overflow_op_gen(ira, &instruction->base.base, instruction->op, + casted_op1, casted_op2, casted_result_ptr, dest_type); } -static void ir_eval_mul_add(IrAnalyze *ira, IrInstructionMulAdd *source_instr, ZigType *float_type, +static void ir_eval_mul_add(IrAnalyze *ira, IrInstSrcMulAdd *source_instr, ZigType *float_type, ZigValue *op1, ZigValue *op2, ZigValue *op3, ZigValue *out_val) { if (float_type->id == ZigTypeIdComptimeFloat) { f128M_mulAdd(&out_val->data.x_bigfloat.value, &op1->data.x_bigfloat.value, &op2->data.x_bigfloat.value, @@ -26017,61 +26994,61 @@ static void ir_eval_mul_add(IrAnalyze *ira, IrInstructionMulAdd *source_instr, Z } } -static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructionMulAdd *instruction) { - IrInstruction *type_value = instruction->type_value->child; +static IrInstGen *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstSrcMulAdd *instruction) { + IrInstGen *type_value = instruction->type_value->child; if (type_is_invalid(type_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *expr_type = ir_resolve_type(ira, type_value); if (type_is_invalid(expr_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // Only allow float types, and vectors of floats. ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; if (float_type->id != ZigTypeIdFloat) { - ir_add_error(ira, type_value, + ir_add_error(ira, &type_value->base, buf_sprintf("expected float or vector of float type, found '%s'", buf_ptr(&float_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *op1 = instruction->op1->child; + IrInstGen *op1 = instruction->op1->child; if (type_is_invalid(op1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, expr_type); + IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, expr_type); if (type_is_invalid(casted_op1->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *op2 = instruction->op2->child; + IrInstGen *op2 = instruction->op2->child; if (type_is_invalid(op2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, expr_type); + IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, expr_type); if (type_is_invalid(casted_op2->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *op3 = instruction->op3->child; + IrInstGen *op3 = instruction->op3->child; if (type_is_invalid(op3->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_op3 = ir_implicit_cast(ira, op3, expr_type); + IrInstGen *casted_op3 = ir_implicit_cast(ira, op3, expr_type); if (type_is_invalid(casted_op3->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2) && instr_is_comptime(casted_op3)) { ZigValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad); if (!op1_const) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *op2_const = ir_resolve_const(ira, casted_op2, UndefBad); if (!op2_const) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *op3_const = ir_resolve_const(ira, casted_op3, UndefBad); if (!op3_const) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result = ir_const(ira, &instruction->base, expr_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, expr_type); ZigValue *out_val = result->value; if (expr_type->id == ZigTypeIdVector) { @@ -26102,63 +27079,59 @@ static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructi return result; } - IrInstruction *result = ir_build_mul_add(&ira->new_irb, - instruction->base.scope, instruction->base.source_node, - type_value, casted_op1, casted_op2, casted_op3); - result->value->type = expr_type; - return result; + return ir_build_mul_add_gen(ira, &instruction->base.base, casted_op1, casted_op2, casted_op3, expr_type); } -static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErrSrc *instruction) { - IrInstruction *base_ptr = instruction->base_ptr->child; +static IrInstGen *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstSrcTestErr *instruction) { + IrInstGen *base_ptr = instruction->base_ptr->child; if (type_is_invalid(base_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *value; + IrInstGen *value; if (instruction->base_ptr_is_payload) { value = base_ptr; } else { - value = ir_get_deref(ira, &instruction->base, base_ptr, nullptr); + value = ir_get_deref(ira, &instruction->base.base, base_ptr, nullptr); } ZigType *type_entry = value->value->type; if (type_is_invalid(type_entry)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (type_entry->id == ZigTypeIdErrorUnion) { if (instr_is_comptime(value)) { ZigValue *err_union_val = ir_resolve_const(ira, value, UndefBad); if (!err_union_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (err_union_val->special != ConstValSpecialRuntime) { ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; - return ir_const_bool(ira, &instruction->base, (err != nullptr)); + return ir_const_bool(ira, &instruction->base.base, (err != nullptr)); } } if (instruction->resolve_err_set) { ZigType *err_set_type = type_entry->data.error_union.err_set_type; - if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { - return ira->codegen->invalid_instruction; + if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.base.source_node)) { + return ira->codegen->invalid_inst_gen; } if (!type_is_global_error_set(err_set_type) && err_set_type->data.error_set.err_count == 0) { assert(!err_set_type->data.error_set.incomplete); - return ir_const_bool(ira, &instruction->base, false); + return ir_const_bool(ira, &instruction->base.base, false); } } - return ir_build_test_err_gen(ira, &instruction->base, value); + return ir_build_test_err_gen(ira, &instruction->base.base, value); } else if (type_entry->id == ZigTypeIdErrorSet) { - return ir_const_bool(ira, &instruction->base, true); + return ir_const_bool(ira, &instruction->base.base, true); } else { - return ir_const_bool(ira, &instruction->base, false); + return ir_const_bool(ira, &instruction->base.base, false); } } -static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *base_ptr, bool initializing) +static IrInstGen *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *base_ptr, bool initializing) { ZigType *ptr_type = base_ptr->value->type; @@ -26167,12 +27140,12 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction * ZigType *type_entry = ptr_type->data.pointer.child_type; if (type_is_invalid(type_entry)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (type_entry->id != ZigTypeIdErrorUnion) { - ir_add_error(ira, base_ptr, + ir_add_error(ira, &base_ptr->base, buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *err_set_type = type_entry->data.error_union.err_set_type; @@ -26183,13 +27156,13 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction * if (instr_is_comptime(base_ptr)) { ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); if (!ptr_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { ZigValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); if (err_union_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (initializing && err_union_val->special == ConstValSpecialUndef) { ZigValue *vals = create_const_vals(2); @@ -26212,11 +27185,10 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction * } ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr); - IrInstruction *result; + IrInstGen *result; if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { - result = ir_build_unwrap_err_code(&ira->new_irb, source_instr->scope, - source_instr->source_node, base_ptr); - result->value->type = result_type; + result = ir_build_unwrap_err_code_gen(ira, source_instr->scope, + source_instr->source_node, base_ptr, result_type); result->value->special = ConstValSpecialStatic; } else { result = ir_const(ira, source_instr, result_type); @@ -26229,23 +27201,18 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction * } } - IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, - source_instr->scope, source_instr->source_node, base_ptr); - result->value->type = result_type; - return result; + return ir_build_unwrap_err_code_gen(ira, source_instr->scope, source_instr->source_node, base_ptr, result_type); } -static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, - IrInstructionUnwrapErrCode *instruction) -{ - IrInstruction *base_ptr = instruction->err_union_ptr->child; +static IrInstGen *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrInstSrcUnwrapErrCode *instruction) { + IrInstGen *base_ptr = instruction->err_union_ptr->child; if (type_is_invalid(base_ptr->value->type)) - return ira->codegen->invalid_instruction; - return ir_analyze_unwrap_err_code(ira, &instruction->base, base_ptr, false); + return ira->codegen->invalid_inst_gen; + return ir_analyze_unwrap_err_code(ira, &instruction->base.base, base_ptr, false); } -static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *base_ptr, bool safety_check_on, bool initializing) +static IrInstGen *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *base_ptr, bool safety_check_on, bool initializing) { ZigType *ptr_type = base_ptr->value->type; @@ -26254,17 +27221,17 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct ZigType *type_entry = ptr_type->data.pointer.child_type; if (type_is_invalid(type_entry)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (type_entry->id != ZigTypeIdErrorUnion) { - ir_add_error(ira, base_ptr, + ir_add_error(ira, &base_ptr->base, buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *payload_type = type_entry->data.error_union.payload_type; if (type_is_invalid(payload_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, @@ -26273,11 +27240,11 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct if (instr_is_comptime(base_ptr)) { ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); if (!ptr_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { ZigValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); if (err_union_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (initializing && err_union_val->special == ConstValSpecialUndef) { ZigValue *vals = create_const_vals(2); ZigValue *err_set_val = &vals[0]; @@ -26300,14 +27267,13 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct if (err != nullptr) { ir_add_error(ira, source_instr, buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *result; + IrInstGen *result; if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { - result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, - source_instr->source_node, base_ptr, safety_check_on, initializing); - result->value->type = result_type; + result = ir_build_unwrap_err_payload_gen(ira, source_instr->scope, + source_instr->source_node, base_ptr, safety_check_on, initializing, result_type); result->value->special = ConstValSpecialStatic; } else { result = ir_const(ira, source_instr, result_type); @@ -26320,28 +27286,26 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct } } - IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, - source_instr->source_node, base_ptr, safety_check_on, initializing); - result->value->type = result_type; - return result; + return ir_build_unwrap_err_payload_gen(ira, source_instr->scope, source_instr->source_node, + base_ptr, safety_check_on, initializing, result_type); } -static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, - IrInstructionUnwrapErrPayload *instruction) +static IrInstGen *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, + IrInstSrcUnwrapErrPayload *instruction) { assert(instruction->value->child); - IrInstruction *value = instruction->value->child; + IrInstGen *value = instruction->value->child; if (type_is_invalid(value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_unwrap_error_payload(ira, &instruction->base, value, instruction->safety_check_on, false); + return ir_analyze_unwrap_error_payload(ira, &instruction->base.base, value, instruction->safety_check_on, false); } -static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { - AstNode *proto_node = instruction->base.source_node; +static IrInstGen *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstSrcFnProto *instruction) { + AstNode *proto_node = instruction->base.base.source_node; assert(proto_node->type == NodeTypeFnProto); - IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); result->value->special = ConstValSpecialLazy; LazyValueFnType *lazy_fn_type = allocate<LazyValueFnType>(1, "LazyValueFnType"); @@ -26350,29 +27314,29 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct lazy_fn_type->base.id = LazyValueIdFnType; if (proto_node->data.fn_proto.auto_err_set) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("inferring error set of return type valid only for function definitions")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } lazy_fn_type->cc = cc_from_fn_proto(&proto_node->data.fn_proto); if (instruction->callconv_value != nullptr) { ZigType *cc_enum_type = get_builtin_type(ira->codegen, "CallingConvention"); - IrInstruction *casted_value = ir_implicit_cast(ira, instruction->callconv_value, cc_enum_type); + IrInstGen *casted_value = ir_implicit_cast(ira, instruction->callconv_value->child, cc_enum_type); if (type_is_invalid(casted_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *const_value = ir_resolve_const(ira, casted_value, UndefBad); if (const_value == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; lazy_fn_type->cc = (CallingConvention)bigint_as_u32(&const_value->data.x_enum_tag); } size_t param_count = proto_node->data.fn_proto.params.length; lazy_fn_type->proto_node = proto_node; - lazy_fn_type->param_types = allocate<IrInstruction *>(param_count); + lazy_fn_type->param_types = allocate<IrInstGen *>(param_count); for (size_t param_index = 0; param_index < param_count; param_index += 1) { AstNode *param_node = proto_node->data.fn_proto.params.at(param_index); @@ -26397,63 +27361,63 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct return result; } - IrInstruction *param_type_value = instruction->param_types[param_index]->child; + IrInstGen *param_type_value = instruction->param_types[param_index]->child; if (type_is_invalid(param_type_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (ir_resolve_const(ira, param_type_value, LazyOk) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; lazy_fn_type->param_types[param_index] = param_type_value; } if (instruction->align_value != nullptr) { lazy_fn_type->align_inst = instruction->align_value->child; if (ir_resolve_const(ira, lazy_fn_type->align_inst, LazyOk) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } lazy_fn_type->return_type = instruction->return_type->child; if (ir_resolve_const(ira, lazy_fn_type->return_type, LazyOk) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return result; } -static IrInstruction *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { - IrInstruction *value = instruction->value->child; +static IrInstGen *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstSrcTestComptime *instruction) { + IrInstGen *value = instruction->value->child; if (type_is_invalid(value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_const_bool(ira, &instruction->base, instr_is_comptime(value)); + return ir_const_bool(ira, &instruction->base.base, instr_is_comptime(value)); } -static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, - IrInstructionCheckSwitchProngs *instruction) +static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, + IrInstSrcCheckSwitchProngs *instruction) { - IrInstruction *target_value = instruction->target_value->child; + IrInstGen *target_value = instruction->target_value->child; ZigType *switch_type = target_value->value->type; if (type_is_invalid(switch_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (switch_type->id == ZigTypeIdEnum) { HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> field_prev_uses = {}; field_prev_uses.init(switch_type->data.enumeration.src_field_count); for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { - IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; + IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; - IrInstruction *start_value_uncasted = range->start->child; + IrInstGen *start_value_uncasted = range->start->child; if (type_is_invalid(start_value_uncasted->value->type)) - return ira->codegen->invalid_instruction; - IrInstruction *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); + return ira->codegen->invalid_inst_gen; + IrInstGen *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); if (type_is_invalid(start_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *end_value_uncasted = range->end->child; + IrInstGen *end_value_uncasted = range->end->child; if (type_is_invalid(end_value_uncasted->value->type)) - return ira->codegen->invalid_instruction; - IrInstruction *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); + return ira->codegen->invalid_inst_gen; + IrInstGen *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); if (type_is_invalid(end_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; assert(start_value->value->type->id == ZigTypeIdEnum); BigInt start_index; @@ -26464,7 +27428,7 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, bigint_init_bigint(&end_index, &end_value->value->data.x_enum_tag); if (bigint_cmp(&start_index, &end_index) == CmpGT) { - ir_add_error(ira, start_value, + ir_add_error(ira, &start_value->base, buf_sprintf("range start value is greater than the end value")); } @@ -26475,12 +27439,12 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, if (cmp == CmpGT) { break; } - auto entry = field_prev_uses.put_unique(field_index, start_value->source_node); + auto entry = field_prev_uses.put_unique(field_index, start_value->base.source_node); if (entry) { AstNode *prev_node = entry->value; TypeEnumField *enum_field = find_enum_field_by_tag(switch_type, &field_index); assert(enum_field != nullptr); - ErrorMsg *msg = ir_add_error(ira, start_value, + ErrorMsg *msg = ir_add_error(ira, &start_value->base, buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), buf_ptr(enum_field->name))); add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); @@ -26490,7 +27454,7 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, } if (instruction->have_underscore_prong) { if (!switch_type->data.enumeration.non_exhaustive){ - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("switch on non-exhaustive enum has `_` prong")); } for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { @@ -26500,14 +27464,14 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, auto entry = field_prev_uses.maybe_get(enum_field->value); if (!entry) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name), buf_ptr(enum_field->name))); } } } else if (!instruction->have_else_prong) { if (switch_type->data.enumeration.non_exhaustive) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("switch on non-exhaustive enum must include `else` or `_` prong")); } for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { @@ -26515,69 +27479,69 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, auto entry = field_prev_uses.maybe_get(enum_field->value); if (!entry) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name), buf_ptr(enum_field->name))); } } } } else if (switch_type->id == ZigTypeIdErrorSet) { - if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->source_node)) { - return ira->codegen->invalid_instruction; + if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->base.source_node)) { + return ira->codegen->invalid_inst_gen; } size_t field_prev_uses_count = ira->codegen->errors_by_index.length; AstNode **field_prev_uses = allocate<AstNode *>(field_prev_uses_count, "AstNode *"); for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { - IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; + IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; - IrInstruction *start_value_uncasted = range->start->child; + IrInstGen *start_value_uncasted = range->start->child; if (type_is_invalid(start_value_uncasted->value->type)) - return ira->codegen->invalid_instruction; - IrInstruction *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); + return ira->codegen->invalid_inst_gen; + IrInstGen *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); if (type_is_invalid(start_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *end_value_uncasted = range->end->child; + IrInstGen *end_value_uncasted = range->end->child; if (type_is_invalid(end_value_uncasted->value->type)) - return ira->codegen->invalid_instruction; - IrInstruction *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); + return ira->codegen->invalid_inst_gen; + IrInstGen *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); if (type_is_invalid(end_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - ir_assert(start_value->value->type->id == ZigTypeIdErrorSet, &instruction->base); + ir_assert(start_value->value->type->id == ZigTypeIdErrorSet, &instruction->base.base); uint32_t start_index = start_value->value->data.x_err_set->value; - ir_assert(end_value->value->type->id == ZigTypeIdErrorSet, &instruction->base); + ir_assert(end_value->value->type->id == ZigTypeIdErrorSet, &instruction->base.base); uint32_t end_index = end_value->value->data.x_err_set->value; if (start_index != end_index) { - ir_add_error(ira, end_value, buf_sprintf("ranges not allowed when switching on errors")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &end_value->base, buf_sprintf("ranges not allowed when switching on errors")); + return ira->codegen->invalid_inst_gen; } AstNode *prev_node = field_prev_uses[start_index]; if (prev_node != nullptr) { Buf *err_name = &ira->codegen->errors_by_index.at(start_index)->name; - ErrorMsg *msg = ir_add_error(ira, start_value, + ErrorMsg *msg = ir_add_error(ira, &start_value->base, buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), buf_ptr(err_name))); add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); } - field_prev_uses[start_index] = start_value->source_node; + field_prev_uses[start_index] = start_value->base.source_node; } if (!instruction->have_else_prong) { if (type_is_global_error_set(switch_type)) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("else prong required when switching on type 'anyerror'")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { for (uint32_t i = 0; i < switch_type->data.error_set.err_count; i += 1) { ErrorTableEntry *err_entry = switch_type->data.error_set.errors[i]; AstNode *prev_node = field_prev_uses[err_entry->value]; if (prev_node == nullptr) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("error.%s not handled in switch", buf_ptr(&err_entry->name))); } } @@ -26588,44 +27552,44 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, } else if (switch_type->id == ZigTypeIdInt) { RangeSet rs = {0}; for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { - IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; + IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; - IrInstruction *start_value = range->start->child; + IrInstGen *start_value = range->start->child; if (type_is_invalid(start_value->value->type)) - return ira->codegen->invalid_instruction; - IrInstruction *casted_start_value = ir_implicit_cast(ira, start_value, switch_type); + return ira->codegen->invalid_inst_gen; + IrInstGen *casted_start_value = ir_implicit_cast(ira, start_value, switch_type); if (type_is_invalid(casted_start_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *end_value = range->end->child; + IrInstGen *end_value = range->end->child; if (type_is_invalid(end_value->value->type)) - return ira->codegen->invalid_instruction; - IrInstruction *casted_end_value = ir_implicit_cast(ira, end_value, switch_type); + return ira->codegen->invalid_inst_gen; + IrInstGen *casted_end_value = ir_implicit_cast(ira, end_value, switch_type); if (type_is_invalid(casted_end_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *start_val = ir_resolve_const(ira, casted_start_value, UndefBad); if (!start_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *end_val = ir_resolve_const(ira, casted_end_value, UndefBad); if (!end_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; assert(start_val->type->id == ZigTypeIdInt || start_val->type->id == ZigTypeIdComptimeInt); assert(end_val->type->id == ZigTypeIdInt || end_val->type->id == ZigTypeIdComptimeInt); if (bigint_cmp(&start_val->data.x_bigint, &end_val->data.x_bigint) == CmpGT) { - ir_add_error(ira, start_value, + ir_add_error(ira, &start_value->base, buf_sprintf("range start value is greater than the end value")); } AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint, - start_value->source_node); + start_value->base.source_node); if (prev_node != nullptr) { - ErrorMsg *msg = ir_add_error(ira, start_value, buf_sprintf("duplicate switch value")); + ErrorMsg *msg = ir_add_error(ira, &start_value->base, buf_sprintf("duplicate switch value")); add_error_note(ira->codegen, msg, prev_node, buf_sprintf("previous value is here")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } if (!instruction->have_else_prong) { @@ -26634,25 +27598,25 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, BigInt max_val; eval_min_max_value_int(ira->codegen, switch_type, &max_val, true); if (!rangeset_spans(&rs, &min_val, &max_val)) { - ir_add_error(ira, &instruction->base, buf_sprintf("switch must handle all possibilities")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities")); + return ira->codegen->invalid_inst_gen; } } } else if (switch_type->id == ZigTypeIdBool) { int seenTrue = 0; int seenFalse = 0; for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { - IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; + IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; - IrInstruction *value = range->start->child; + IrInstGen *value = range->start->child; - IrInstruction *casted_value = ir_implicit_cast(ira, value, switch_type); + IrInstGen *casted_value = ir_implicit_cast(ira, value, switch_type); if (type_is_invalid(casted_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigValue *const_expr_val = ir_resolve_const(ira, casted_value, UndefBad); if (!const_expr_val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; assert(const_expr_val->type->id == ZigTypeIdBool); @@ -26663,60 +27627,59 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, } if ((seenTrue > 1) || (seenFalse > 1)) { - ir_add_error(ira, value, buf_sprintf("duplicate switch value")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &value->base, buf_sprintf("duplicate switch value")); + return ira->codegen->invalid_inst_gen; } } if (((seenTrue < 1) || (seenFalse < 1)) && !instruction->have_else_prong) { - ir_add_error(ira, &instruction->base, buf_sprintf("switch must handle all possibilities")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities")); + return ira->codegen->invalid_inst_gen; } } else if (!instruction->have_else_prong) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base.base, buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_check_statement_is_void(IrAnalyze *ira, - IrInstructionCheckStatementIsVoid *instruction) +static IrInstGen *ir_analyze_instruction_check_statement_is_void(IrAnalyze *ira, + IrInstSrcCheckStatementIsVoid *instruction) { - IrInstruction *statement_value = instruction->statement_value->child; + IrInstGen *statement_value = instruction->statement_value->child; ZigType *statement_type = statement_value->value->type; if (type_is_invalid(statement_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (statement_type->id != ZigTypeIdVoid && statement_type->id != ZigTypeIdUnreachable) { - ir_add_error(ira, &instruction->base, buf_sprintf("expression value is ignored")); + ir_add_error(ira, &instruction->base.base, buf_sprintf("expression value is ignored")); } - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructionPanic *instruction) { - IrInstruction *msg = instruction->msg->child; +static IrInstGen *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstSrcPanic *instruction) { + IrInstGen *msg = instruction->msg->child; if (type_is_invalid(msg->value->type)) return ir_unreach_error(ira); - if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) { - ir_add_error(ira, &instruction->base, buf_sprintf("encountered @panic at compile-time")); + if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope)) { + ir_add_error(ira, &instruction->base.base, buf_sprintf("encountered @panic at compile-time")); return ir_unreach_error(ira); } ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, true, false, PtrLenUnknown, 0, 0, 0, false); ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); - IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type); + IrInstGen *casted_msg = ir_implicit_cast(ira, msg, str_type); if (type_is_invalid(casted_msg->value->type)) return ir_unreach_error(ira); - IrInstruction *new_instruction = ir_build_panic(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, casted_msg); + IrInstGen *new_instruction = ir_build_panic_gen(ira, &instruction->base.base, casted_msg); return ir_finish_anal(ira, new_instruction); } -static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint32_t align_bytes, bool safety_check_on) { +static IrInstGen *ir_align_cast(IrAnalyze *ira, IrInstGen *target, uint32_t align_bytes, bool safety_check_on) { Error err; ZigType *target_type = target->value->type; @@ -26728,7 +27691,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 if (target_type->id == ZigTypeIdPointer) { result_type = adjust_ptr_align(ira->codegen, target_type, align_bytes); if ((err = resolve_ptr_align(ira, target_type, &old_align_bytes))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (target_type->id == ZigTypeIdFn) { FnTypeId fn_type_id = target_type->data.fn.fn_type_id; old_align_bytes = fn_type_id.alignment; @@ -26739,7 +27702,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 { ZigType *ptr_type = target_type->data.maybe.child_type; if ((err = resolve_ptr_align(ira, ptr_type, &old_align_bytes))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *better_ptr_type = adjust_ptr_align(ira->codegen, ptr_type, align_bytes); result_type = get_optional_type(ira->codegen, better_ptr_type); @@ -26754,47 +27717,44 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 } else if (is_slice(target_type)) { ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry; if ((err = resolve_ptr_align(ira, slice_ptr_type, &old_align_bytes))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes); result_type = get_slice_type(ira->codegen, result_ptr_type); } else { - ir_add_error(ira, target, + ir_add_error(ira, &target->base, buf_sprintf("expected pointer or slice, found '%s'", buf_ptr(&target_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(target)) { ZigValue *val = ir_resolve_const(ira, target, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && val->data.x_ptr.data.hard_coded_addr.addr % align_bytes != 0) { - ir_add_error(ira, target, + ir_add_error(ira, &target->base, buf_sprintf("pointer address 0x%" ZIG_PRI_x64 " is not aligned to %" PRIu32 " bytes", val->data.x_ptr.data.hard_coded_addr.addr, align_bytes)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *result = ir_const(ira, target, result_type); + IrInstGen *result = ir_const(ira, &target->base, result_type); copy_const_val(result->value, val); result->value->type = result_type; return result; } - IrInstruction *result; if (safety_check_on && align_bytes > old_align_bytes && align_bytes != 1) { - result = ir_build_align_cast(&ira->new_irb, target->scope, target->source_node, nullptr, target); + return ir_build_align_cast_gen(ira, target->base.scope, target->base.source_node, target, result_type); } else { - result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, result_type, target, CastOpNoop); + return ir_build_cast(ira, &target->base, result_type, target, CastOpNoop); } - result->value->type = result_type; - return result; } -static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, - ZigType *dest_type, IrInstruction *dest_type_src, bool safety_check_on) +static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr, + IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on) { Error err; @@ -26810,52 +27770,52 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ ZigType *src_ptr_type = get_src_ptr_type(src_type); if (src_ptr_type == nullptr) { - ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name))); - return ira->codegen->invalid_instruction; + ir_add_error(ira, ptr_src, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name))); + return ira->codegen->invalid_inst_gen; } ZigType *dest_ptr_type = get_src_ptr_type(dest_type); if (dest_ptr_type == nullptr) { ir_add_error(ira, dest_type_src, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (get_ptr_const(src_type) && !get_ptr_const(dest_type)) { ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } uint32_t src_align_bytes; if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint32_t dest_align_bytes; if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - if (type_has_bits(dest_type) && !type_has_bits(src_type)) { + if (type_has_bits(dest_type) && !type_has_bits(src_type) && safety_check_on) { ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("'%s' and '%s' do not have the same in-memory representation", buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); - add_error_note(ira->codegen, msg, ptr->source_node, + add_error_note(ira->codegen, msg, ptr_src->source_node, buf_sprintf("'%s' has no in-memory bits", buf_ptr(&src_type->name))); add_error_note(ira->codegen, msg, dest_type_src->source_node, buf_sprintf("'%s' has in-memory bits", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(ptr)) { bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad; ZigValue *val = ir_resolve_const(ira, ptr, is_undef_allowed); - if (!val) - return ira->codegen->invalid_instruction; + if (val == nullptr) + return ira->codegen->invalid_inst_gen; if (value_is_comptime(val) && val->special != ConstValSpecialUndef) { bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull || @@ -26864,20 +27824,36 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ if (is_addr_zero && !dest_allows_addr_zero) { ir_add_error(ira, source_instr, buf_sprintf("null pointer casted to type '%s'", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } - IrInstruction *result; - if (ptr->value->data.x_ptr.mut == ConstPtrMutInfer) { + IrInstGen *result; + if (val->data.x_ptr.mut == ConstPtrMutInfer) { result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); - - if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; } else { result = ir_const(ira, source_instr, dest_type); } - copy_const_val(result->value, val); + InferredStructField *isf = (val->type->id == ZigTypeIdPointer) ? + val->type->data.pointer.inferred_struct_field : nullptr; + if (isf == nullptr) { + copy_const_val(result->value, val); + } else { + // The destination value should have x_ptr struct pointing to underlying struct value + result->value->data.x_ptr.mut = val->data.x_ptr.mut; + TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); + assert(field != nullptr); + if (field->is_comptime) { + result->value->data.x_ptr.special = ConstPtrSpecialRef; + result->value->data.x_ptr.data.ref.pointee = field->init_val; + } else { + assert(val->data.x_ptr.special == ConstPtrSpecialRef); + result->value->data.x_ptr.special = ConstPtrSpecialBaseStruct; + result->value->data.x_ptr.data.base_struct.struct_val = val->data.x_ptr.data.ref.pointee; + result->value->data.x_ptr.data.base_struct.field_index = field->src_index; + } + result->value->special = ConstValSpecialStatic; + } result->value->type = dest_type; // Keep the bigger alignment, it can only help- @@ -26891,41 +27867,41 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ if (dest_align_bytes > src_align_bytes) { ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); - add_error_note(ira->codegen, msg, ptr->source_node, + add_error_note(ira->codegen, msg, ptr_src->source_node, buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_type->name), src_align_bytes)); add_error_note(ira->codegen, msg, dest_type_src->source_node, buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&dest_type->name), dest_align_bytes)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); + IrInstGen *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); // Keep the bigger alignment, it can only help- // unless the target is zero bits. - IrInstruction *result; + IrInstGen *result; if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); if (type_is_invalid(result->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { result = casted_ptr; } return result; } -static IrInstruction *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtrCastSrc *instruction) { - IrInstruction *dest_type_value = instruction->dest_type->child; +static IrInstGen *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstSrcPtrCast *instruction) { + IrInstGen *dest_type_value = instruction->dest_type->child; ZigType *dest_type = ir_resolve_type(ira, dest_type_value); if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *ptr = instruction->ptr->child; + IrInstGen *ptr = instruction->ptr->child; ZigType *src_type = ptr->value->type; if (type_is_invalid(src_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_ptr_cast(ira, &instruction->base, ptr, dest_type, dest_type_value, - instruction->safety_check_on); + return ir_analyze_ptr_cast(ira, &instruction->base.base, ptr, &instruction->ptr->base, + dest_type, &dest_type_value->base, instruction->safety_check_on); } static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ZigValue *val, size_t len) { @@ -27255,7 +28231,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou zig_unreachable(); } -static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, +static IrInstGen *ir_analyze_bit_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, ZigType *dest_type) { Error err; @@ -27271,14 +28247,14 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_ buf_sprintf("cannot cast a value of type '%s'", buf_ptr(&dest_type->name))); add_error_note(ira->codegen, msg, source_instr->source_node, buf_sprintf("use @intToEnum for type coercion")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if ((err = type_resolve(ira->codegen, src_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint64_t dest_size_bytes = type_size(ira->codegen, dest_type); uint64_t src_size_bytes = type_size(ira->codegen, src_type); @@ -27287,7 +28263,7 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_ buf_sprintf("destination type '%s' has size %" ZIG_PRI_u64 " but source type '%s' has size %" ZIG_PRI_u64, buf_ptr(&dest_type->name), dest_size_bytes, buf_ptr(&src_type->name), src_size_bytes)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } uint64_t dest_size_bits = type_size_bits(ira->codegen, dest_type); @@ -27297,26 +28273,26 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_ buf_sprintf("destination type '%s' has %" ZIG_PRI_u64 " bits but source type '%s' has %" ZIG_PRI_u64 " bits", buf_ptr(&dest_type->name), dest_size_bits, buf_ptr(&src_type->name), src_size_bits)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(value)) { ZigValue *val = ir_resolve_const(ira, value, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result = ir_const(ira, source_instr, dest_type); + IrInstGen *result = ir_const(ira, source_instr, dest_type); uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes); buf_write_value_bytes(ira->codegen, buf, val); if ((err = buf_read_value_bytes(ira, ira->codegen, source_instr->source_node, buf, result->value))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return result; } return ir_build_bit_cast_gen(ira, source_instr, value, dest_type); } -static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, +static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, ZigType *ptr_type) { Error err; @@ -27324,136 +28300,128 @@ static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *sourc ir_assert(get_src_ptr_type(ptr_type) != nullptr, source_instr); ir_assert(type_has_bits(ptr_type), source_instr); - IrInstruction *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize); + IrInstGen *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize); if (type_is_invalid(casted_int->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (instr_is_comptime(casted_int)) { ZigValue *val = ir_resolve_const(ira, casted_int, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint64_t addr = bigint_as_u64(&val->data.x_bigint); if (!ptr_allows_addr_zero(ptr_type) && addr == 0) { ir_add_error(ira, source_instr, buf_sprintf("pointer type '%s' does not allow address zero", buf_ptr(&ptr_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } uint32_t align_bytes; if ((err = resolve_ptr_align(ira, ptr_type, &align_bytes))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (addr != 0 && addr % align_bytes != 0) { ir_add_error(ira, source_instr, buf_sprintf("pointer type '%s' requires aligned address", buf_ptr(&ptr_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *result = ir_const(ira, source_instr, ptr_type); + IrInstGen *result = ir_const(ira, source_instr, ptr_type); result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; result->value->data.x_ptr.data.hard_coded_addr.addr = addr; return result; } - IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, source_instr->scope, - source_instr->source_node, nullptr, casted_int); - result->value->type = ptr_type; - return result; + return ir_build_int_to_ptr_gen(ira, source_instr->scope, source_instr->source_node, casted_int, ptr_type); } -static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionIntToPtr *instruction) { +static IrInstGen *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstSrcIntToPtr *instruction) { Error err; - IrInstruction *dest_type_value = instruction->dest_type->child; + IrInstGen *dest_type_value = instruction->dest_type->child; ZigType *dest_type = ir_resolve_type(ira, dest_type_value); if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // We explicitly check for the size, so we can use get_src_ptr_type if (get_src_ptr_type(dest_type) == nullptr) { - ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &dest_type_value->base, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); + return ira->codegen->invalid_inst_gen; } bool has_bits; if ((err = type_has_bits2(ira->codegen, dest_type, &has_bits))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!has_bits) { - ir_add_error(ira, dest_type_value, + ir_add_error(ira, &dest_type_value->base, buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *target = instruction->target->child; + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_int_to_ptr(ira, &instruction->base, target, dest_type); + return ir_analyze_int_to_ptr(ira, &instruction->base.base, target, dest_type); } -static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, - IrInstructionDeclRef *instruction) -{ - IrInstruction *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base, instruction->tld); +static IrInstGen *ir_analyze_instruction_decl_ref(IrAnalyze *ira, IrInstSrcDeclRef *instruction) { + IrInstGen *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base.base, instruction->tld); if (type_is_invalid(ref_instruction->value->type)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (instruction->lval == LValPtr) { return ref_instruction; } else { - return ir_get_deref(ira, &instruction->base, ref_instruction, nullptr); + return ir_get_deref(ira, &instruction->base.base, ref_instruction, nullptr); } } -static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) { +static IrInstGen *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstSrcPtrToInt *instruction) { Error err; - IrInstruction *target = instruction->target->child; + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *usize = ira->codegen->builtin_types.entry_usize; // We check size explicitly so we can use get_src_ptr_type here. if (get_src_ptr_type(target->value->type) == nullptr) { - ir_add_error(ira, target, + ir_add_error(ira, &target->base, buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } bool has_bits; if ((err = type_has_bits2(ira->codegen, target->value->type, &has_bits))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!has_bits) { - ir_add_error(ira, target, + ir_add_error(ira, &target->base, buf_sprintf("pointer to size 0 type has no address")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(target)) { ZigValue *val = ir_resolve_const(ira, target, UndefBad); if (!val) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (val->type->id == ZigTypeIdPointer && val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { - IrInstruction *result = ir_const(ira, &instruction->base, usize); + IrInstGen *result = ir_const(ira, &instruction->base.base, usize); bigint_init_unsigned(&result->value->data.x_bigint, val->data.x_ptr.data.hard_coded_addr.addr); result->value->type = usize; return result; } } - IrInstruction *result = ir_build_ptr_to_int(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, target); - result->value->type = usize; - return result; + return ir_build_ptr_to_int_gen(ira, &instruction->base.base, target); } -static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtrType *instruction) { - IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); +static IrInstGen *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstSrcPtrType *instruction) { + IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); result->value->special = ConstValSpecialLazy; LazyValuePtrType *lazy_ptr_type = allocate<LazyValuePtrType>(1, "LazyValuePtrType"); @@ -27464,17 +28432,17 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct if (instruction->sentinel != nullptr) { lazy_ptr_type->sentinel = instruction->sentinel->child; if (ir_resolve_const(ira, lazy_ptr_type->sentinel, LazyOk) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } lazy_ptr_type->elem_type = instruction->child_type->child; if (ir_resolve_type_lazy(ira, lazy_ptr_type->elem_type) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (instruction->align_value != nullptr) { lazy_ptr_type->align_inst = instruction->align_value->child; if (ir_resolve_const(ira, lazy_ptr_type->align_inst, LazyOk) == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } lazy_ptr_type->ptr_len = instruction->ptr_len; @@ -27487,10 +28455,10 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct return result; } -static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstructionAlignCast *instruction) { - IrInstruction *target = instruction->target->child; +static IrInstGen *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstSrcAlignCast *instruction) { + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *elem_type = nullptr; if (is_slice(target->value->type)) { @@ -27501,192 +28469,192 @@ static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstru } uint32_t align_bytes; - IrInstruction *align_bytes_inst = instruction->align_bytes->child; + IrInstGen *align_bytes_inst = instruction->align_bytes->child; if (!ir_resolve_align(ira, align_bytes_inst, elem_type, &align_bytes)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result = ir_align_cast(ira, target, align_bytes, true); + IrInstGen *result = ir_align_cast(ira, target, align_bytes, true); if (type_is_invalid(result->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return result; } -static IrInstruction *ir_analyze_instruction_opaque_type(IrAnalyze *ira, IrInstructionOpaqueType *instruction) { +static IrInstGen *ir_analyze_instruction_opaque_type(IrAnalyze *ira, IrInstSrcOpaqueType *instruction) { Buf *bare_name = buf_alloc(); - Buf *full_name = get_anon_type_name(ira->codegen, ira->new_irb.exec, "opaque", - instruction->base.scope, instruction->base.source_node, bare_name); - ZigType *result_type = get_opaque_type(ira->codegen, instruction->base.scope, instruction->base.source_node, - buf_ptr(full_name), bare_name); - return ir_const_type(ira, &instruction->base, result_type); + Buf *full_name = get_anon_type_name(ira->codegen, ira->old_irb.exec, "opaque", + instruction->base.base.scope, instruction->base.base.source_node, bare_name); + ZigType *result_type = get_opaque_type(ira->codegen, instruction->base.base.scope, + instruction->base.base.source_node, buf_ptr(full_name), bare_name); + return ir_const_type(ira, &instruction->base.base, result_type); } -static IrInstruction *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstructionSetAlignStack *instruction) { +static IrInstGen *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstSrcSetAlignStack *instruction) { uint32_t align_bytes; - IrInstruction *align_bytes_inst = instruction->align_bytes->child; + IrInstGen *align_bytes_inst = instruction->align_bytes->child; if (!ir_resolve_align(ira, align_bytes_inst, nullptr, &align_bytes)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (align_bytes > 256) { - ir_add_error(ira, &instruction->base, buf_sprintf("attempt to @setAlignStack(%" PRIu32 "); maximum is 256", align_bytes)); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("attempt to @setAlignStack(%" PRIu32 "); maximum is 256", align_bytes)); + return ira->codegen->invalid_inst_gen; } - ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); + ZigFn *fn_entry = ira->new_irb.exec->fn_entry; if (fn_entry == nullptr) { - ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack outside function")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack outside function")); + return ira->codegen->invalid_inst_gen; } if (fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionNaked) { - ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack in naked function")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack in naked function")); + return ira->codegen->invalid_inst_gen; } if (fn_entry->fn_inline == FnInlineAlways) { - ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack in inline function")); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack in inline function")); + return ira->codegen->invalid_inst_gen; } if (fn_entry->set_alignstack_node != nullptr) { - ErrorMsg *msg = ir_add_error_node(ira, instruction->base.source_node, + ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, buf_sprintf("alignstack set twice")); add_error_note(ira->codegen, msg, fn_entry->set_alignstack_node, buf_sprintf("first set here")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - fn_entry->set_alignstack_node = instruction->base.source_node; + fn_entry->set_alignstack_node = instruction->base.base.source_node; fn_entry->alignstack_value = align_bytes; - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstructionArgType *instruction) { - IrInstruction *fn_type_inst = instruction->fn_type->child; +static IrInstGen *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstSrcArgType *instruction) { + IrInstGen *fn_type_inst = instruction->fn_type->child; ZigType *fn_type = ir_resolve_type(ira, fn_type_inst); if (type_is_invalid(fn_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *arg_index_inst = instruction->arg_index->child; + IrInstGen *arg_index_inst = instruction->arg_index->child; uint64_t arg_index; if (!ir_resolve_usize(ira, arg_index_inst, &arg_index)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (fn_type->id == ZigTypeIdBoundFn) { fn_type = fn_type->data.bound_fn.fn_type; arg_index += 1; } if (fn_type->id != ZigTypeIdFn) { - ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); - return ira->codegen->invalid_instruction; + ir_add_error(ira, &fn_type_inst->base, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); + return ira->codegen->invalid_inst_gen; } FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; if (arg_index >= fn_type_id->param_count) { if (instruction->allow_var) { // TODO remove this with var args - return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var); + return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_var); } - ir_add_error(ira, arg_index_inst, + ir_add_error(ira, &arg_index_inst->base, buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments", arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigType *result_type = fn_type_id->param_info[arg_index].type; if (result_type == nullptr) { // Args are only unresolved if our function is generic. - ir_assert(fn_type->data.fn.is_generic, &instruction->base); + ir_assert(fn_type->data.fn.is_generic, &instruction->base.base); if (instruction->allow_var) { - return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var); + return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_var); } else { - ir_add_error(ira, arg_index_inst, + ir_add_error(ira, &arg_index_inst->base, buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", arg_index, buf_ptr(&fn_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } - return ir_const_type(ira, &instruction->base, result_type); + return ir_const_type(ira, &instruction->base.base, result_type); } -static IrInstruction *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstructionTagType *instruction) { +static IrInstGen *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstSrcTagType *instruction) { Error err; - IrInstruction *target_inst = instruction->target->child; + IrInstGen *target_inst = instruction->target->child; ZigType *enum_type = ir_resolve_type(ira, target_inst); if (type_is_invalid(enum_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (enum_type->id == ZigTypeIdEnum) { if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_const_type(ira, &instruction->base, enum_type->data.enumeration.tag_int_type); + return ir_const_type(ira, &instruction->base.base, enum_type->data.enumeration.tag_int_type); } else if (enum_type->id == ZigTypeIdUnion) { - ZigType *tag_type = ir_resolve_union_tag_type(ira, instruction->target, enum_type); + ZigType *tag_type = ir_resolve_union_tag_type(ira, instruction->target->base.source_node, enum_type); if (type_is_invalid(tag_type)) - return ira->codegen->invalid_instruction; - return ir_const_type(ira, &instruction->base, tag_type); + return ira->codegen->invalid_inst_gen; + return ir_const_type(ira, &instruction->base.base, tag_type); } else { - ir_add_error(ira, target_inst, buf_sprintf("expected enum or union, found '%s'", + ir_add_error(ira, &target_inst->base, buf_sprintf("expected enum or union, found '%s'", buf_ptr(&enum_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } -static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op) { +static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) { ZigType *operand_type = ir_resolve_type(ira, op); if (type_is_invalid(operand_type)) return ira->codegen->builtin_types.entry_invalid; if (operand_type->id == ZigTypeIdInt) { if (operand_type->data.integral.bit_count < 8) { - ir_add_error(ira, op, + ir_add_error(ira, &op->base, buf_sprintf("expected integer type 8 bits or larger, found %" PRIu32 "-bit integer type", operand_type->data.integral.bit_count)); return ira->codegen->builtin_types.entry_invalid; } uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); if (operand_type->data.integral.bit_count > max_atomic_bits) { - ir_add_error(ira, op, + ir_add_error(ira, &op->base, buf_sprintf("expected %" PRIu32 "-bit integer type or smaller, found %" PRIu32 "-bit integer type", max_atomic_bits, operand_type->data.integral.bit_count)); return ira->codegen->builtin_types.entry_invalid; } if (!is_power_of_2(operand_type->data.integral.bit_count)) { - ir_add_error(ira, op, + ir_add_error(ira, &op->base, buf_sprintf("%" PRIu32 "-bit integer type is not a power of 2", operand_type->data.integral.bit_count)); return ira->codegen->builtin_types.entry_invalid; } } else if (operand_type->id == ZigTypeIdEnum) { ZigType *int_type = operand_type->data.enumeration.tag_int_type; if (int_type->data.integral.bit_count < 8) { - ir_add_error(ira, op, + ir_add_error(ira, &op->base, buf_sprintf("expected enum tag type 8 bits or larger, found %" PRIu32 "-bit tag type", int_type->data.integral.bit_count)); return ira->codegen->builtin_types.entry_invalid; } uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); if (int_type->data.integral.bit_count > max_atomic_bits) { - ir_add_error(ira, op, + ir_add_error(ira, &op->base, buf_sprintf("expected %" PRIu32 "-bit enum tag type or smaller, found %" PRIu32 "-bit tag type", max_atomic_bits, int_type->data.integral.bit_count)); return ira->codegen->builtin_types.entry_invalid; } if (!is_power_of_2(int_type->data.integral.bit_count)) { - ir_add_error(ira, op, + ir_add_error(ira, &op->base, buf_sprintf("%" PRIu32 "-bit enum tag type is not a power of 2", int_type->data.integral.bit_count)); return ira->codegen->builtin_types.entry_invalid; } } else if (operand_type->id == ZigTypeIdFloat) { uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); if (operand_type->data.floating.bit_count > max_atomic_bits) { - ir_add_error(ira, op, + ir_add_error(ira, &op->base, buf_sprintf("expected %" PRIu32 "-bit float or smaller, found %" PRIu32 "-bit float", max_atomic_bits, (uint32_t) operand_type->data.floating.bit_count)); return ira->codegen->builtin_types.entry_invalid; } } else if (get_codegen_ptr_type(operand_type) == nullptr) { - ir_add_error(ira, op, + ir_add_error(ira, &op->base, buf_sprintf("expected integer, float, enum or pointer type, found '%s'", buf_ptr(&operand_type->name))); return ira->codegen->builtin_types.entry_invalid; } @@ -27694,172 +28662,146 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op return operand_type; } -static IrInstruction *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstructionAtomicRmw *instruction) { +static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAtomicRmw *instruction) { ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); if (type_is_invalid(operand_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *ptr_inst = instruction->ptr->child; + IrInstGen *ptr_inst = instruction->ptr->child; if (type_is_invalid(ptr_inst->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // TODO let this be volatile ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); - IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); + IrInstGen *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); if (type_is_invalid(casted_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; AtomicRmwOp op; - if (instruction->op == nullptr) { - op = instruction->resolved_op; - } else { - if (!ir_resolve_atomic_rmw_op(ira, instruction->op->child, &op)) { - return ira->codegen->invalid_instruction; - } + if (!ir_resolve_atomic_rmw_op(ira, instruction->op->child, &op)) { + return ira->codegen->invalid_inst_gen; } if (operand_type->id == ZigTypeIdEnum && op != AtomicRmwOp_xchg) { - ir_add_error(ira, instruction->op, + ir_add_error(ira, &instruction->op->base, buf_sprintf("@atomicRmw on enum only works with .Xchg")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else if (operand_type->id == ZigTypeIdFloat && op > AtomicRmwOp_sub) { - ir_add_error(ira, instruction->op, + ir_add_error(ira, &instruction->op->base, buf_sprintf("@atomicRmw with float only works with .Xchg, .Add and .Sub")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - IrInstruction *operand = instruction->operand->child; + IrInstGen *operand = instruction->operand->child; if (type_is_invalid(operand->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_operand = ir_implicit_cast(ira, operand, operand_type); + IrInstGen *casted_operand = ir_implicit_cast(ira, operand, operand_type); if (type_is_invalid(casted_operand->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; AtomicOrder ordering; - if (instruction->ordering == nullptr) { - ordering = instruction->resolved_ordering; - } else { - if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) - return ira->codegen->invalid_instruction; - if (ordering == AtomicOrderUnordered) { - ir_add_error(ira, instruction->ordering, - buf_sprintf("@atomicRmw atomic ordering must not be Unordered")); - return ira->codegen->invalid_instruction; - } + if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) + return ira->codegen->invalid_inst_gen; + if (ordering == AtomicOrderUnordered) { + ir_add_error(ira, &instruction->ordering->base, + buf_sprintf("@atomicRmw atomic ordering must not be Unordered")); + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(casted_operand) && instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar) { - zig_panic("TODO compile-time execution of atomicRmw"); + ir_add_error(ira, &instruction->base.base, + buf_sprintf("compiler bug: TODO compile-time execution of @atomicRmw")); + return ira->codegen->invalid_inst_gen; } - IrInstruction *result = ir_build_atomic_rmw(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, nullptr, casted_ptr, nullptr, casted_operand, nullptr, - op, ordering); - result->value->type = operand_type; - return result; + return ir_build_atomic_rmw_gen(ira, &instruction->base.base, casted_ptr, casted_operand, op, + ordering, operand_type); } -static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstructionAtomicLoad *instruction) { +static IrInstGen *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstSrcAtomicLoad *instruction) { ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); if (type_is_invalid(operand_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *ptr_inst = instruction->ptr->child; + IrInstGen *ptr_inst = instruction->ptr->child; if (type_is_invalid(ptr_inst->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, true); - IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); + IrInstGen *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); if (type_is_invalid(casted_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; AtomicOrder ordering; - if (instruction->ordering == nullptr) { - ordering = instruction->resolved_ordering; - } else { - if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) - return ira->codegen->invalid_instruction; - } + if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) + return ira->codegen->invalid_inst_gen; if (ordering == AtomicOrderRelease || ordering == AtomicOrderAcqRel) { - ir_assert(instruction->ordering != nullptr, &instruction->base); - ir_add_error(ira, instruction->ordering, + ir_assert(instruction->ordering != nullptr, &instruction->base.base); + ir_add_error(ira, &instruction->ordering->base, buf_sprintf("@atomicLoad atomic ordering must not be Release or AcqRel")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(casted_ptr)) { - IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr, nullptr); - ir_assert(result->value->type != nullptr, &instruction->base); + IrInstGen *result = ir_get_deref(ira, &instruction->base.base, casted_ptr, nullptr); + ir_assert(result->value->type != nullptr, &instruction->base.base); return result; } - IrInstruction *result = ir_build_atomic_load(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, nullptr, casted_ptr, nullptr, ordering); - result->value->type = operand_type; - return result; + return ir_build_atomic_load_gen(ira, &instruction->base.base, casted_ptr, ordering, operand_type); } -static IrInstruction *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstructionAtomicStore *instruction) { +static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcAtomicStore *instruction) { ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); if (type_is_invalid(operand_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *ptr_inst = instruction->ptr->child; + IrInstGen *ptr_inst = instruction->ptr->child; if (type_is_invalid(ptr_inst->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); - IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); + IrInstGen *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); if (type_is_invalid(casted_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *value = instruction->value->child; + IrInstGen *value = instruction->value->child; if (type_is_invalid(value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_value = ir_implicit_cast(ira, value, operand_type); + IrInstGen *casted_value = ir_implicit_cast(ira, value, operand_type); if (type_is_invalid(casted_value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; AtomicOrder ordering; - if (instruction->ordering == nullptr) { - ordering = instruction->resolved_ordering; - } else { - if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) - return ira->codegen->invalid_instruction; - } + if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) + return ira->codegen->invalid_inst_gen; if (ordering == AtomicOrderAcquire || ordering == AtomicOrderAcqRel) { - ir_assert(instruction->ordering != nullptr, &instruction->base); - ir_add_error(ira, instruction->ordering, + ir_assert(instruction->ordering != nullptr, &instruction->base.base); + ir_add_error(ira, &instruction->ordering->base, buf_sprintf("@atomicStore atomic ordering must not be Acquire or AcqRel")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(casted_value) && instr_is_comptime(casted_ptr)) { - IrInstruction *result = ir_analyze_store_ptr(ira, &instruction->base, casted_ptr, value, false); + IrInstGen *result = ir_analyze_store_ptr(ira, &instruction->base.base, casted_ptr, value, false); result->value->type = ira->codegen->builtin_types.entry_void; return result; } - IrInstruction *result = ir_build_atomic_store(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, nullptr, casted_ptr, casted_value, nullptr, ordering); - result->value->type = ira->codegen->builtin_types.entry_void; - return result; + return ir_build_atomic_store_gen(ira, &instruction->base.base, casted_ptr, casted_value, ordering); } -static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstructionSaveErrRetAddr *instruction) { - IrInstruction *result = ir_build_save_err_ret_addr(&ira->new_irb, instruction->base.scope, - instruction->base.source_node); - result->value->type = ira->codegen->builtin_types.entry_void; - return result; +static IrInstGen *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstSrcSaveErrRetAddr *instruction) { + return ir_build_save_err_ret_addr_gen(ira, &instruction->base.base); } -static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, BuiltinFnId fop, ZigType *float_type, +static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinFnId fop, ZigType *float_type, ZigValue *op, ZigValue *out_val) { assert(ira && source_instr && float_type && out_val && op); @@ -28072,30 +29014,30 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInstruction *source_instr, B return nullptr; } -static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstructionFloatOp *instruction) { - IrInstruction *operand = instruction->operand->child; +static IrInstGen *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstSrcFloatOp *instruction) { + IrInstGen *operand = instruction->operand->child; ZigType *operand_type = operand->value->type; if (type_is_invalid(operand_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; // This instruction accepts floats and vectors of floats. ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type; if (scalar_type->id != ZigTypeIdFloat && scalar_type->id != ZigTypeIdComptimeFloat) { - ir_add_error(ira, operand, + ir_add_error(ira, &operand->base, buf_sprintf("expected float type, found '%s'", buf_ptr(&scalar_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(operand)) { ZigValue *operand_val = ir_resolve_const(ira, operand, UndefOk); if (operand_val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (operand_val->special == ConstValSpecialUndef) - return ir_const_undef(ira, &instruction->base, operand_type); + return ir_const_undef(ira, &instruction->base.base, operand_type); - IrInstruction *result = ir_const(ira, &instruction->base, operand_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, operand_type); ZigValue *out_val = result->value; if (operand_type->id == ZigTypeIdVector) { @@ -28106,47 +29048,44 @@ static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstruct for (size_t i = 0; i < len; i += 1) { ZigValue *elem_operand = &operand_val->data.x_array.data.s_none.elements[i]; ZigValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; - ir_assert(elem_operand->type == scalar_type, &instruction->base); - ir_assert(float_out_val->type == scalar_type, &instruction->base); - ErrorMsg *msg = ir_eval_float_op(ira, &instruction->base, instruction->fn_id, scalar_type, + ir_assert(elem_operand->type == scalar_type, &instruction->base.base); + ir_assert(float_out_val->type == scalar_type, &instruction->base.base); + ErrorMsg *msg = ir_eval_float_op(ira, &instruction->base.base, instruction->fn_id, scalar_type, elem_operand, float_out_val); if (msg != nullptr) { - add_error_note(ira->codegen, msg, instruction->base.source_node, + add_error_note(ira->codegen, msg, instruction->base.base.source_node, buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } float_out_val->type = scalar_type; } out_val->type = operand_type; out_val->special = ConstValSpecialStatic; } else { - if (ir_eval_float_op(ira, &instruction->base, instruction->fn_id, scalar_type, + if (ir_eval_float_op(ira, &instruction->base.base, instruction->fn_id, scalar_type, operand_val, out_val) != nullptr) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } return result; } - ir_assert(scalar_type->id == ZigTypeIdFloat, &instruction->base); + ir_assert(scalar_type->id == ZigTypeIdFloat, &instruction->base.base); - IrInstruction *result = ir_build_float_op(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, operand, instruction->fn_id); - result->value->type = operand_type; - return result; + return ir_build_float_op_gen(ira, &instruction->base.base, operand, instruction->fn_id, operand_type); } -static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstructionBswap *instruction) { +static IrInstGen *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstSrcBswap *instruction) { Error err; ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); if (type_is_invalid(int_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *uncasted_op = instruction->op->child; + IrInstGen *uncasted_op = instruction->op->child; if (type_is_invalid(uncasted_op->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; uint32_t vector_len; // UINT32_MAX means not a vector if (uncasted_op->value->type->id == ZigTypeIdArray && @@ -28162,28 +29101,28 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction bool is_vector = (vector_len != UINT32_MAX); ZigType *op_type = is_vector ? get_vector_type(ira->codegen, vector_len, int_type) : int_type; - IrInstruction *op = ir_implicit_cast(ira, uncasted_op, op_type); + IrInstGen *op = ir_implicit_cast(ira, uncasted_op, op_type); if (type_is_invalid(op->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (int_type->data.integral.bit_count == 8 || int_type->data.integral.bit_count == 0) return op; if (int_type->data.integral.bit_count % 8 != 0) { - ir_add_error(ira, instruction->op, + ir_add_error(ira, &instruction->op->base, buf_sprintf("@byteSwap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8", buf_ptr(&int_type->name), int_type->data.integral.bit_count)); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if (instr_is_comptime(op)) { ZigValue *val = ir_resolve_const(ira, op, UndefOk); if (val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (val->special == ConstValSpecialUndef) - return ir_const_undef(ira, &instruction->base, op_type); + return ir_const_undef(ira, &instruction->base.base, op_type); - IrInstruction *result = ir_const(ira, &instruction->base, op_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, op_type); size_t buf_size = int_type->data.integral.bit_count / 8; uint8_t *buf = allocate_nonzero<uint8_t>(buf_size); if (is_vector) { @@ -28191,10 +29130,10 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction result->value->data.x_array.data.s_none.elements = create_const_vals(op_type->data.vector.len); for (unsigned i = 0; i < op_type->data.vector.len; i += 1) { ZigValue *op_elem_val = &val->data.x_array.data.s_none.elements[i]; - if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, instruction->base.source_node, + if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, instruction->base.base.source_node, op_elem_val, UndefOk))) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ZigValue *result_elem_val = &result->value->data.x_array.data.s_none.elements[i]; result_elem_val->type = int_type; @@ -28216,23 +29155,20 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction return result; } - IrInstruction *result = ir_build_bswap(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, nullptr, op); - result->value->type = op_type; - return result; + return ir_build_bswap_gen(ira, &instruction->base.base, op_type, op); } -static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstructionBitReverse *instruction) { +static IrInstGen *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstSrcBitReverse *instruction) { ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); if (type_is_invalid(int_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type); + IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); if (type_is_invalid(op->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (int_type->data.integral.bit_count == 0) { - IrInstruction *result = ir_const(ira, &instruction->base, int_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, int_type); bigint_init_unsigned(&result->value->data.x_bigint, 0); return result; } @@ -28240,11 +29176,11 @@ static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstr if (instr_is_comptime(op)) { ZigValue *val = ir_resolve_const(ira, op, UndefOk); if (val == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (val->special == ConstValSpecialUndef) - return ir_const_undef(ira, &instruction->base, int_type); + return ir_const_undef(ira, &instruction->base.base, int_type); - IrInstruction *result = ir_const(ira, &instruction->base, int_type); + IrInstGen *result = ir_const(ira, &instruction->base.base, int_type); size_t num_bits = int_type->data.integral.bit_count; size_t buf_size = (num_bits + 7) / 8; uint8_t *comptime_buf = allocate_nonzero<uint8_t>(buf_size); @@ -28271,128 +29207,125 @@ static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstr return result; } - IrInstruction *result = ir_build_bit_reverse(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, nullptr, op); - result->value->type = int_type; - return result; + return ir_build_bit_reverse_gen(ira, &instruction->base.base, int_type, op); } -static IrInstruction *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstructionEnumToInt *instruction) { - IrInstruction *target = instruction->target->child; +static IrInstGen *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstSrcEnumToInt *instruction) { + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_enum_to_int(ira, &instruction->base, target); + return ir_analyze_enum_to_int(ira, &instruction->base.base, target); } -static IrInstruction *ir_analyze_instruction_int_to_enum(IrAnalyze *ira, IrInstructionIntToEnum *instruction) { +static IrInstGen *ir_analyze_instruction_int_to_enum(IrAnalyze *ira, IrInstSrcIntToEnum *instruction) { Error err; - IrInstruction *dest_type_value = instruction->dest_type->child; + IrInstGen *dest_type_value = instruction->dest_type->child; ZigType *dest_type = ir_resolve_type(ira, dest_type_value); if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (dest_type->id != ZigTypeIdEnum) { - ir_add_error(ira, instruction->dest_type, + ir_add_error(ira, &instruction->dest_type->base, buf_sprintf("expected enum, found type '%s'", buf_ptr(&dest_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *tag_type = dest_type->data.enumeration.tag_int_type; - IrInstruction *target = instruction->target->child; + IrInstGen *target = instruction->target->child; if (type_is_invalid(target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *casted_target = ir_implicit_cast(ira, target, tag_type); + IrInstGen *casted_target = ir_implicit_cast(ira, target, tag_type); if (type_is_invalid(casted_target->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_int_to_enum(ira, &instruction->base, casted_target, dest_type); + return ir_analyze_int_to_enum(ira, &instruction->base.base, casted_target, dest_type); } -static IrInstruction *ir_analyze_instruction_check_runtime_scope(IrAnalyze *ira, IrInstructionCheckRuntimeScope *instruction) { - IrInstruction *block_comptime_inst = instruction->scope_is_comptime->child; +static IrInstGen *ir_analyze_instruction_check_runtime_scope(IrAnalyze *ira, IrInstSrcCheckRuntimeScope *instruction) { + IrInstGen *block_comptime_inst = instruction->scope_is_comptime->child; bool scope_is_comptime; if (!ir_resolve_bool(ira, block_comptime_inst, &scope_is_comptime)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *is_comptime_inst = instruction->is_comptime->child; + IrInstGen *is_comptime_inst = instruction->is_comptime->child; bool is_comptime; if (!ir_resolve_bool(ira, is_comptime_inst, &is_comptime)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!scope_is_comptime && is_comptime) { - ErrorMsg *msg = ir_add_error(ira, &instruction->base, + ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, buf_sprintf("comptime control flow inside runtime block")); - add_error_note(ira->codegen, msg, block_comptime_inst->source_node, + add_error_note(ira->codegen, msg, block_comptime_inst->base.source_node, buf_sprintf("runtime block created here")); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstructionHasDecl *instruction) { +static IrInstGen *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstSrcHasDecl *instruction) { ZigType *container_type = ir_resolve_type(ira, instruction->container->child); if (type_is_invalid(container_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; Buf *name = ir_resolve_str(ira, instruction->name->child); if (name == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!is_container(container_type)) { - ir_add_error(ira, instruction->container, + ir_add_error(ira, &instruction->container->base, buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&container_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } ScopeDecls *container_scope = get_container_scope(container_type); Tld *tld = find_container_decl(ira->codegen, container_scope, name); if (tld == nullptr) - return ir_const_bool(ira, &instruction->base, false); + return ir_const_bool(ira, &instruction->base.base, false); - if (tld->visib_mod == VisibModPrivate && tld->import != get_scope_import(instruction->base.scope)) { - return ir_const_bool(ira, &instruction->base, false); + if (tld->visib_mod == VisibModPrivate && tld->import != get_scope_import(instruction->base.base.scope)) { + return ir_const_bool(ira, &instruction->base.base, false); } - return ir_const_bool(ira, &instruction->base, true); + return ir_const_bool(ira, &instruction->base.base, true); } -static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, IrInstructionUndeclaredIdent *instruction) { +static IrInstGen *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, IrInstSrcUndeclaredIdent *instruction) { // put a variable of same name with invalid type in global scope // so that future references to this same name will find a variable with an invalid type - populate_invalid_variable_in_scope(ira->codegen, instruction->base.scope, instruction->base.source_node, - instruction->name); - ir_add_error(ira, &instruction->base, + populate_invalid_variable_in_scope(ira->codegen, instruction->base.base.scope, + instruction->base.base.source_node, instruction->name); + ir_add_error(ira, &instruction->base.base, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(instruction->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } -static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstructionEndExpr *instruction) { - IrInstruction *value = instruction->value->child; +static IrInstGen *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstSrcEndExpr *instruction) { + IrInstGen *value = instruction->value->child; if (type_is_invalid(value->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; bool was_written = instruction->result_loc->written; - IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, - value->value->type, value, false, false, true); + IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, + value->value->type, value, false, true); if (result_loc != nullptr) { if (type_is_invalid(result_loc->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (result_loc->value->type->id == ZigTypeIdUnreachable) return result_loc; if (!was_written || instruction->result_loc->id == ResultLocIdPeer) { - IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value, + IrInstGen *store_ptr = ir_analyze_store_ptr(ira, &instruction->base.base, result_loc, value, instruction->result_loc->allow_write_through_const); if (type_is_invalid(store_ptr->value->type)) { - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } } @@ -28407,106 +29340,100 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct } } - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) { - IrInstruction *operand = instruction->operand->child; +static IrInstGen *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstSrcImplicitCast *instruction) { + IrInstGen *operand = instruction->operand->child; if (type_is_invalid(operand->value->type)) return operand; - IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, - &instruction->result_loc_cast->base, operand->value->type, operand, false, false, true); - if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc))) - return result_loc; - ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child); if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; - return ir_implicit_cast2(ira, &instruction->base, operand, dest_type); + return ira->codegen->invalid_inst_gen; + return ir_implicit_cast2(ira, &instruction->base.base, operand, dest_type); } -static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) { - IrInstruction *operand = instruction->operand->child; +static IrInstGen *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstSrcBitCast *instruction) { + IrInstGen *operand = instruction->operand->child; if (type_is_invalid(operand->value->type)) return operand; - IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, - &instruction->result_loc_bit_cast->base, operand->value->type, operand, false, false, true); - if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc))) + IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, + &instruction->result_loc_bit_cast->base, operand->value->type, operand, false, true); + if (result_loc != nullptr && + (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) + { return result_loc; - - if (instruction->result_loc_bit_cast->parent->gen_instruction != nullptr) { - return instruction->result_loc_bit_cast->parent->gen_instruction; } - return result_loc; + ZigType *dest_type = ir_resolve_type(ira, + instruction->result_loc_bit_cast->base.source_instruction->child); + if (type_is_invalid(dest_type)) + return ira->codegen->invalid_inst_gen; + return ir_analyze_bit_cast(ira, &instruction->base.base, operand, dest_type); } -static IrInstruction *ir_analyze_instruction_union_init_named_field(IrAnalyze *ira, - IrInstructionUnionInitNamedField *instruction) +static IrInstGen *ir_analyze_instruction_union_init_named_field(IrAnalyze *ira, + IrInstSrcUnionInitNamedField *instruction) { ZigType *union_type = ir_resolve_type(ira, instruction->union_type->child); if (type_is_invalid(union_type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (union_type->id != ZigTypeIdUnion) { - ir_add_error(ira, instruction->union_type, + ir_add_error(ira, &instruction->union_type->base, buf_sprintf("non-union type '%s' passed to @unionInit", buf_ptr(&union_type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); if (field_name == nullptr) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *field_result_loc = instruction->field_result_loc->child; + IrInstGen *field_result_loc = instruction->field_result_loc->child; if (type_is_invalid(field_result_loc->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *result_loc = instruction->result_loc->child; + IrInstGen *result_loc = instruction->result_loc->child; if (type_is_invalid(result_loc->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_analyze_union_init(ira, &instruction->base, instruction->base.source_node, + return ir_analyze_union_init(ira, &instruction->base.base, instruction->base.base.source_node, union_type, field_name, field_result_loc, result_loc); } -static IrInstruction *ir_analyze_instruction_suspend_begin(IrAnalyze *ira, IrInstructionSuspendBegin *instruction) { - IrInstructionSuspendBegin *result = ir_build_suspend_begin(&ira->new_irb, instruction->base.scope, - instruction->base.source_node); - return &result->base; +static IrInstGen *ir_analyze_instruction_suspend_begin(IrAnalyze *ira, IrInstSrcSuspendBegin *instruction) { + return ir_build_suspend_begin_gen(ira, &instruction->base.base); } -static IrInstruction *ir_analyze_instruction_suspend_finish(IrAnalyze *ira, - IrInstructionSuspendFinish *instruction) -{ - IrInstruction *begin_base = instruction->begin->base.child; +static IrInstGen *ir_analyze_instruction_suspend_finish(IrAnalyze *ira, IrInstSrcSuspendFinish *instruction) { + IrInstGen *begin_base = instruction->begin->base.child; if (type_is_invalid(begin_base->value->type)) - return ira->codegen->invalid_instruction; - ir_assert(begin_base->id == IrInstructionIdSuspendBegin, &instruction->base); - IrInstructionSuspendBegin *begin = reinterpret_cast<IrInstructionSuspendBegin *>(begin_base); + return ira->codegen->invalid_inst_gen; + ir_assert(begin_base->id == IrInstGenIdSuspendBegin, &instruction->base.base); + IrInstGenSuspendBegin *begin = reinterpret_cast<IrInstGenSuspendBegin *>(begin_base); - ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); - ir_assert(fn_entry != nullptr, &instruction->base); + ZigFn *fn_entry = ira->new_irb.exec->fn_entry; + ir_assert(fn_entry != nullptr, &instruction->base.base); if (fn_entry->inferred_async_node == nullptr) { - fn_entry->inferred_async_node = instruction->base.source_node; + fn_entry->inferred_async_node = instruction->base.base.source_node; } - return ir_build_suspend_finish(&ira->new_irb, instruction->base.scope, instruction->base.source_node, begin); + return ir_build_suspend_finish_gen(ira, &instruction->base.base, begin); } -static IrInstruction *analyze_frame_ptr_to_anyframe_T(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *frame_ptr, ZigFn **target_fn) +static IrInstGen *analyze_frame_ptr_to_anyframe_T(IrAnalyze *ira, IrInst* source_instr, + IrInstGen *frame_ptr, ZigFn **target_fn) { if (type_is_invalid(frame_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; *target_fn = nullptr; ZigType *result_type; - IrInstruction *frame; + IrInstGen *frame; if (frame_ptr->value->type->id == ZigTypeIdPointer && frame_ptr->value->type->data.pointer.ptr_len == PtrLenSingle && frame_ptr->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) @@ -28529,38 +29456,38 @@ static IrInstruction *analyze_frame_ptr_to_anyframe_T(IrAnalyze *ira, IrInstruct { ir_add_error(ira, source_instr, buf_sprintf("expected anyframe->T, found '%s'", buf_ptr(&frame->value->type->name))); - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; } else { result_type = frame->value->type->data.any_frame.result_type; } } ZigType *any_frame_type = get_any_frame_type(ira->codegen, result_type); - IrInstruction *casted_frame = ir_implicit_cast(ira, frame, any_frame_type); + IrInstGen *casted_frame = ir_implicit_cast(ira, frame, any_frame_type); if (type_is_invalid(casted_frame->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; return casted_frame; } -static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstructionAwaitSrc *instruction) { - IrInstruction *operand = instruction->frame->child; +static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *instruction) { + IrInstGen *operand = instruction->frame->child; if (type_is_invalid(operand->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigFn *target_fn; - IrInstruction *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base, operand, &target_fn); + IrInstGen *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base.base, operand, &target_fn); if (type_is_invalid(frame->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; ZigType *result_type = frame->value->type->data.any_frame.result_type; - ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); - ir_assert(fn_entry != nullptr, &instruction->base); + ZigFn *fn_entry = ira->new_irb.exec->fn_entry; + ir_assert(fn_entry != nullptr, &instruction->base.base); // If it's not @Frame(func) then it's definitely a suspend point if (target_fn == nullptr) { if (fn_entry->inferred_async_node == nullptr) { - fn_entry->inferred_async_node = instruction->base.source_node; + fn_entry->inferred_async_node = instruction->base.base.source_node; } } @@ -28568,402 +29495,368 @@ static IrInstruction *ir_analyze_instruction_await(IrAnalyze *ira, IrInstruction fn_entry->calls_or_awaits_errorable_fn = true; } - IrInstruction *result_loc; + IrInstGen *result_loc; if (type_has_bits(result_type)) { - result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, - result_type, nullptr, true, true, true); - if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc))) + result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, + result_type, nullptr, true, true); + if (result_loc != nullptr && + (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) + { return result_loc; + } } else { result_loc = nullptr; } - IrInstructionAwaitGen *result = ir_build_await_gen(ira, &instruction->base, frame, result_type, result_loc); + IrInstGenAwait *result = ir_build_await_gen(ira, &instruction->base.base, frame, result_type, result_loc); result->target_fn = target_fn; fn_entry->await_list.append(result); return ir_finish_anal(ira, &result->base); } -static IrInstruction *ir_analyze_instruction_resume(IrAnalyze *ira, IrInstructionResume *instruction) { - IrInstruction *frame_ptr = instruction->frame->child; +static IrInstGen *ir_analyze_instruction_resume(IrAnalyze *ira, IrInstSrcResume *instruction) { + IrInstGen *frame_ptr = instruction->frame->child; if (type_is_invalid(frame_ptr->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - IrInstruction *frame; + IrInstGen *frame; if (frame_ptr->value->type->id == ZigTypeIdPointer && frame_ptr->value->type->data.pointer.ptr_len == PtrLenSingle && frame_ptr->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) { frame = frame_ptr; } else { - frame = ir_get_deref(ira, &instruction->base, frame_ptr, nullptr); + frame = ir_get_deref(ira, &instruction->base.base, frame_ptr, nullptr); } ZigType *any_frame_type = get_any_frame_type(ira->codegen, nullptr); - IrInstruction *casted_frame = ir_implicit_cast(ira, frame, any_frame_type); + IrInstGen *casted_frame = ir_implicit_cast2(ira, &instruction->frame->base, frame, any_frame_type); if (type_is_invalid(casted_frame->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - return ir_build_resume(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_frame); + return ir_build_resume_gen(ira, &instruction->base.base, casted_frame); } -static IrInstruction *ir_analyze_instruction_spill_begin(IrAnalyze *ira, IrInstructionSpillBegin *instruction) { - if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) - return ir_const_void(ira, &instruction->base); +static IrInstGen *ir_analyze_instruction_spill_begin(IrAnalyze *ira, IrInstSrcSpillBegin *instruction) { + if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope)) + return ir_const_void(ira, &instruction->base.base); - IrInstruction *operand = instruction->operand->child; + IrInstGen *operand = instruction->operand->child; if (type_is_invalid(operand->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; if (!type_has_bits(operand->value->type)) - return ir_const_void(ira, &instruction->base); + return ir_const_void(ira, &instruction->base.base); - ir_assert(instruction->spill_id == SpillIdRetErrCode, &instruction->base); + ir_assert(instruction->spill_id == SpillIdRetErrCode, &instruction->base.base); ira->new_irb.exec->need_err_code_spill = true; - IrInstructionSpillBegin *result = ir_build_spill_begin(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, operand, instruction->spill_id); - return &result->base; + return ir_build_spill_begin_gen(ira, &instruction->base.base, operand, instruction->spill_id); } -static IrInstruction *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstructionSpillEnd *instruction) { - IrInstruction *operand = instruction->begin->operand->child; +static IrInstGen *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstSrcSpillEnd *instruction) { + IrInstGen *operand = instruction->begin->operand->child; if (type_is_invalid(operand->value->type)) - return ira->codegen->invalid_instruction; + return ira->codegen->invalid_inst_gen; - if (ir_should_inline(ira->new_irb.exec, instruction->base.scope) || !type_has_bits(operand->value->type)) + if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope) || !type_has_bits(operand->value->type)) return operand; - ir_assert(instruction->begin->base.child->id == IrInstructionIdSpillBegin, &instruction->base); - IrInstructionSpillBegin *begin = reinterpret_cast<IrInstructionSpillBegin *>(instruction->begin->base.child); + ir_assert(instruction->begin->base.child->id == IrInstGenIdSpillBegin, &instruction->base.base); + IrInstGenSpillBegin *begin = reinterpret_cast<IrInstGenSpillBegin *>(instruction->begin->base.child); - IrInstruction *result = ir_build_spill_end(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, begin); - result->value->type = operand->value->type; - return result; + return ir_build_spill_end_gen(ira, &instruction->base.base, begin, operand->value->type); } -static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) { +static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruction) { switch (instruction->id) { - case IrInstructionIdInvalid: - case IrInstructionIdWidenOrShorten: - case IrInstructionIdStructFieldPtr: - case IrInstructionIdUnionFieldPtr: - case IrInstructionIdOptionalWrap: - case IrInstructionIdErrWrapCode: - case IrInstructionIdErrWrapPayload: - case IrInstructionIdCast: - case IrInstructionIdDeclVarGen: - case IrInstructionIdPtrCastGen: - case IrInstructionIdCmpxchgGen: - case IrInstructionIdArrayToVector: - case IrInstructionIdVectorToArray: - case IrInstructionIdPtrOfArrayToSlice: - case IrInstructionIdAssertZero: - case IrInstructionIdAssertNonNull: - case IrInstructionIdResizeSlice: - case IrInstructionIdLoadPtrGen: - case IrInstructionIdBitCastGen: - case IrInstructionIdCallGen: - case IrInstructionIdReturnPtr: - case IrInstructionIdAllocaGen: - case IrInstructionIdSliceGen: - case IrInstructionIdRefGen: - case IrInstructionIdTestErrGen: - case IrInstructionIdFrameSizeGen: - case IrInstructionIdAwaitGen: - case IrInstructionIdSplatGen: - case IrInstructionIdVectorExtractElem: - case IrInstructionIdVectorStoreElem: - case IrInstructionIdAsmGen: + case IrInstSrcIdInvalid: zig_unreachable(); - case IrInstructionIdReturn: - return ir_analyze_instruction_return(ira, (IrInstructionReturn *)instruction); - case IrInstructionIdConst: - return ir_analyze_instruction_const(ira, (IrInstructionConst *)instruction); - case IrInstructionIdUnOp: - return ir_analyze_instruction_un_op(ira, (IrInstructionUnOp *)instruction); - case IrInstructionIdBinOp: - return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction); - case IrInstructionIdMergeErrSets: - return ir_analyze_instruction_merge_err_sets(ira, (IrInstructionMergeErrSets *)instruction); - case IrInstructionIdDeclVarSrc: - return ir_analyze_instruction_decl_var(ira, (IrInstructionDeclVarSrc *)instruction); - case IrInstructionIdLoadPtr: - return ir_analyze_instruction_load_ptr(ira, (IrInstructionLoadPtr *)instruction); - case IrInstructionIdStorePtr: - return ir_analyze_instruction_store_ptr(ira, (IrInstructionStorePtr *)instruction); - case IrInstructionIdElemPtr: - return ir_analyze_instruction_elem_ptr(ira, (IrInstructionElemPtr *)instruction); - case IrInstructionIdVarPtr: - return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); - case IrInstructionIdFieldPtr: - return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); - case IrInstructionIdCallSrc: - return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction); - case IrInstructionIdCallSrcArgs: - return ir_analyze_instruction_call_args(ira, (IrInstructionCallSrcArgs *)instruction); - case IrInstructionIdCallExtra: - return ir_analyze_instruction_call_extra(ira, (IrInstructionCallExtra *)instruction); - case IrInstructionIdBr: - return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); - case IrInstructionIdCondBr: - return ir_analyze_instruction_cond_br(ira, (IrInstructionCondBr *)instruction); - case IrInstructionIdUnreachable: - return ir_analyze_instruction_unreachable(ira, (IrInstructionUnreachable *)instruction); - case IrInstructionIdPhi: - return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); - case IrInstructionIdTypeOf: - return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction); - case IrInstructionIdSetCold: - return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction); - case IrInstructionIdSetRuntimeSafety: - return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction); - case IrInstructionIdSetFloatMode: - return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction); - case IrInstructionIdAnyFrameType: - return ir_analyze_instruction_any_frame_type(ira, (IrInstructionAnyFrameType *)instruction); - case IrInstructionIdSliceType: - return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction); - case IrInstructionIdAsmSrc: - return ir_analyze_instruction_asm(ira, (IrInstructionAsmSrc *)instruction); - case IrInstructionIdArrayType: - return ir_analyze_instruction_array_type(ira, (IrInstructionArrayType *)instruction); - case IrInstructionIdSizeOf: - return ir_analyze_instruction_size_of(ira, (IrInstructionSizeOf *)instruction); - case IrInstructionIdTestNonNull: - return ir_analyze_instruction_test_non_null(ira, (IrInstructionTestNonNull *)instruction); - case IrInstructionIdOptionalUnwrapPtr: - return ir_analyze_instruction_optional_unwrap_ptr(ira, (IrInstructionOptionalUnwrapPtr *)instruction); - case IrInstructionIdClz: - return ir_analyze_instruction_clz(ira, (IrInstructionClz *)instruction); - case IrInstructionIdCtz: - return ir_analyze_instruction_ctz(ira, (IrInstructionCtz *)instruction); - case IrInstructionIdPopCount: - return ir_analyze_instruction_pop_count(ira, (IrInstructionPopCount *)instruction); - case IrInstructionIdBswap: - return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction); - case IrInstructionIdBitReverse: - return ir_analyze_instruction_bit_reverse(ira, (IrInstructionBitReverse *)instruction); - case IrInstructionIdSwitchBr: - return ir_analyze_instruction_switch_br(ira, (IrInstructionSwitchBr *)instruction); - case IrInstructionIdSwitchTarget: - return ir_analyze_instruction_switch_target(ira, (IrInstructionSwitchTarget *)instruction); - case IrInstructionIdSwitchVar: - return ir_analyze_instruction_switch_var(ira, (IrInstructionSwitchVar *)instruction); - case IrInstructionIdSwitchElseVar: - return ir_analyze_instruction_switch_else_var(ira, (IrInstructionSwitchElseVar *)instruction); - case IrInstructionIdUnionTag: - return ir_analyze_instruction_union_tag(ira, (IrInstructionUnionTag *)instruction); - case IrInstructionIdImport: - return ir_analyze_instruction_import(ira, (IrInstructionImport *)instruction); - case IrInstructionIdRef: - return ir_analyze_instruction_ref(ira, (IrInstructionRef *)instruction); - case IrInstructionIdContainerInitList: - return ir_analyze_instruction_container_init_list(ira, (IrInstructionContainerInitList *)instruction); - case IrInstructionIdContainerInitFields: - return ir_analyze_instruction_container_init_fields(ira, (IrInstructionContainerInitFields *)instruction); - case IrInstructionIdCompileErr: - return ir_analyze_instruction_compile_err(ira, (IrInstructionCompileErr *)instruction); - case IrInstructionIdCompileLog: - return ir_analyze_instruction_compile_log(ira, (IrInstructionCompileLog *)instruction); - case IrInstructionIdErrName: - return ir_analyze_instruction_err_name(ira, (IrInstructionErrName *)instruction); - case IrInstructionIdTypeName: - return ir_analyze_instruction_type_name(ira, (IrInstructionTypeName *)instruction); - case IrInstructionIdCImport: - return ir_analyze_instruction_c_import(ira, (IrInstructionCImport *)instruction); - case IrInstructionIdCInclude: - return ir_analyze_instruction_c_include(ira, (IrInstructionCInclude *)instruction); - case IrInstructionIdCDefine: - return ir_analyze_instruction_c_define(ira, (IrInstructionCDefine *)instruction); - case IrInstructionIdCUndef: - return ir_analyze_instruction_c_undef(ira, (IrInstructionCUndef *)instruction); - case IrInstructionIdEmbedFile: - return ir_analyze_instruction_embed_file(ira, (IrInstructionEmbedFile *)instruction); - case IrInstructionIdCmpxchgSrc: - return ir_analyze_instruction_cmpxchg(ira, (IrInstructionCmpxchgSrc *)instruction); - case IrInstructionIdFence: - return ir_analyze_instruction_fence(ira, (IrInstructionFence *)instruction); - case IrInstructionIdTruncate: - return ir_analyze_instruction_truncate(ira, (IrInstructionTruncate *)instruction); - case IrInstructionIdIntCast: - return ir_analyze_instruction_int_cast(ira, (IrInstructionIntCast *)instruction); - case IrInstructionIdFloatCast: - return ir_analyze_instruction_float_cast(ira, (IrInstructionFloatCast *)instruction); - case IrInstructionIdErrSetCast: - return ir_analyze_instruction_err_set_cast(ira, (IrInstructionErrSetCast *)instruction); - case IrInstructionIdFromBytes: - return ir_analyze_instruction_from_bytes(ira, (IrInstructionFromBytes *)instruction); - case IrInstructionIdToBytes: - return ir_analyze_instruction_to_bytes(ira, (IrInstructionToBytes *)instruction); - case IrInstructionIdIntToFloat: - return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction); - case IrInstructionIdFloatToInt: - return ir_analyze_instruction_float_to_int(ira, (IrInstructionFloatToInt *)instruction); - case IrInstructionIdBoolToInt: - return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction); - case IrInstructionIdIntType: - return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction); - case IrInstructionIdVectorType: - return ir_analyze_instruction_vector_type(ira, (IrInstructionVectorType *)instruction); - case IrInstructionIdShuffleVector: - return ir_analyze_instruction_shuffle_vector(ira, (IrInstructionShuffleVector *)instruction); - case IrInstructionIdSplatSrc: - return ir_analyze_instruction_splat(ira, (IrInstructionSplatSrc *)instruction); - case IrInstructionIdBoolNot: - return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction); - case IrInstructionIdMemset: - return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction); - case IrInstructionIdMemcpy: - return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction); - case IrInstructionIdSliceSrc: - return ir_analyze_instruction_slice(ira, (IrInstructionSliceSrc *)instruction); - case IrInstructionIdMemberCount: - return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction); - case IrInstructionIdMemberType: - return ir_analyze_instruction_member_type(ira, (IrInstructionMemberType *)instruction); - case IrInstructionIdMemberName: - return ir_analyze_instruction_member_name(ira, (IrInstructionMemberName *)instruction); - case IrInstructionIdBreakpoint: - return ir_analyze_instruction_breakpoint(ira, (IrInstructionBreakpoint *)instruction); - case IrInstructionIdReturnAddress: - return ir_analyze_instruction_return_address(ira, (IrInstructionReturnAddress *)instruction); - case IrInstructionIdFrameAddress: - return ir_analyze_instruction_frame_address(ira, (IrInstructionFrameAddress *)instruction); - case IrInstructionIdFrameHandle: - return ir_analyze_instruction_frame_handle(ira, (IrInstructionFrameHandle *)instruction); - case IrInstructionIdFrameType: - return ir_analyze_instruction_frame_type(ira, (IrInstructionFrameType *)instruction); - case IrInstructionIdFrameSizeSrc: - return ir_analyze_instruction_frame_size(ira, (IrInstructionFrameSizeSrc *)instruction); - case IrInstructionIdAlignOf: - return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction); - case IrInstructionIdOverflowOp: - return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); - case IrInstructionIdTestErrSrc: - return ir_analyze_instruction_test_err(ira, (IrInstructionTestErrSrc *)instruction); - case IrInstructionIdUnwrapErrCode: - return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction); - case IrInstructionIdUnwrapErrPayload: - return ir_analyze_instruction_unwrap_err_payload(ira, (IrInstructionUnwrapErrPayload *)instruction); - case IrInstructionIdFnProto: - return ir_analyze_instruction_fn_proto(ira, (IrInstructionFnProto *)instruction); - case IrInstructionIdTestComptime: - return ir_analyze_instruction_test_comptime(ira, (IrInstructionTestComptime *)instruction); - case IrInstructionIdCheckSwitchProngs: - return ir_analyze_instruction_check_switch_prongs(ira, (IrInstructionCheckSwitchProngs *)instruction); - case IrInstructionIdCheckStatementIsVoid: - return ir_analyze_instruction_check_statement_is_void(ira, (IrInstructionCheckStatementIsVoid *)instruction); - case IrInstructionIdDeclRef: - return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction); - case IrInstructionIdPanic: - return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); - case IrInstructionIdPtrCastSrc: - return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction); - case IrInstructionIdIntToPtr: - return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); - case IrInstructionIdPtrToInt: - return ir_analyze_instruction_ptr_to_int(ira, (IrInstructionPtrToInt *)instruction); - case IrInstructionIdTagName: - return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionTagName *)instruction); - case IrInstructionIdFieldParentPtr: - return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction); - case IrInstructionIdByteOffsetOf: - return ir_analyze_instruction_byte_offset_of(ira, (IrInstructionByteOffsetOf *)instruction); - case IrInstructionIdBitOffsetOf: - return ir_analyze_instruction_bit_offset_of(ira, (IrInstructionBitOffsetOf *)instruction); - case IrInstructionIdTypeInfo: - return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction); - case IrInstructionIdType: - return ir_analyze_instruction_type(ira, (IrInstructionType *)instruction); - case IrInstructionIdHasField: - return ir_analyze_instruction_has_field(ira, (IrInstructionHasField *) instruction); - case IrInstructionIdTypeId: - return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); - case IrInstructionIdSetEvalBranchQuota: - return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstructionSetEvalBranchQuota *)instruction); - case IrInstructionIdPtrType: - return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction); - case IrInstructionIdAlignCast: - return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction); - case IrInstructionIdImplicitCast: - return ir_analyze_instruction_implicit_cast(ira, (IrInstructionImplicitCast *)instruction); - case IrInstructionIdResolveResult: - return ir_analyze_instruction_resolve_result(ira, (IrInstructionResolveResult *)instruction); - case IrInstructionIdResetResult: - return ir_analyze_instruction_reset_result(ira, (IrInstructionResetResult *)instruction); - case IrInstructionIdOpaqueType: - return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); - case IrInstructionIdSetAlignStack: - return ir_analyze_instruction_set_align_stack(ira, (IrInstructionSetAlignStack *)instruction); - case IrInstructionIdArgType: - return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction); - case IrInstructionIdTagType: - return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction); - case IrInstructionIdExport: - return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction); - case IrInstructionIdErrorReturnTrace: - return ir_analyze_instruction_error_return_trace(ira, (IrInstructionErrorReturnTrace *)instruction); - case IrInstructionIdErrorUnion: - return ir_analyze_instruction_error_union(ira, (IrInstructionErrorUnion *)instruction); - case IrInstructionIdAtomicRmw: - return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction); - case IrInstructionIdAtomicLoad: - return ir_analyze_instruction_atomic_load(ira, (IrInstructionAtomicLoad *)instruction); - case IrInstructionIdAtomicStore: - return ir_analyze_instruction_atomic_store(ira, (IrInstructionAtomicStore *)instruction); - case IrInstructionIdSaveErrRetAddr: - return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstructionSaveErrRetAddr *)instruction); - case IrInstructionIdAddImplicitReturnType: - return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstructionAddImplicitReturnType *)instruction); - case IrInstructionIdFloatOp: - return ir_analyze_instruction_float_op(ira, (IrInstructionFloatOp *)instruction); - case IrInstructionIdMulAdd: - return ir_analyze_instruction_mul_add(ira, (IrInstructionMulAdd *)instruction); - case IrInstructionIdIntToErr: - return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); - case IrInstructionIdErrToInt: - return ir_analyze_instruction_err_to_int(ira, (IrInstructionErrToInt *)instruction); - case IrInstructionIdIntToEnum: - return ir_analyze_instruction_int_to_enum(ira, (IrInstructionIntToEnum *)instruction); - case IrInstructionIdEnumToInt: - return ir_analyze_instruction_enum_to_int(ira, (IrInstructionEnumToInt *)instruction); - case IrInstructionIdCheckRuntimeScope: - return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction); - case IrInstructionIdHasDecl: - return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction); - case IrInstructionIdUndeclaredIdent: - return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction); - case IrInstructionIdAllocaSrc: + case IrInstSrcIdReturn: + return ir_analyze_instruction_return(ira, (IrInstSrcReturn *)instruction); + case IrInstSrcIdConst: + return ir_analyze_instruction_const(ira, (IrInstSrcConst *)instruction); + case IrInstSrcIdUnOp: + return ir_analyze_instruction_un_op(ira, (IrInstSrcUnOp *)instruction); + case IrInstSrcIdBinOp: + return ir_analyze_instruction_bin_op(ira, (IrInstSrcBinOp *)instruction); + case IrInstSrcIdMergeErrSets: + return ir_analyze_instruction_merge_err_sets(ira, (IrInstSrcMergeErrSets *)instruction); + case IrInstSrcIdDeclVar: + return ir_analyze_instruction_decl_var(ira, (IrInstSrcDeclVar *)instruction); + case IrInstSrcIdLoadPtr: + return ir_analyze_instruction_load_ptr(ira, (IrInstSrcLoadPtr *)instruction); + case IrInstSrcIdStorePtr: + return ir_analyze_instruction_store_ptr(ira, (IrInstSrcStorePtr *)instruction); + case IrInstSrcIdElemPtr: + return ir_analyze_instruction_elem_ptr(ira, (IrInstSrcElemPtr *)instruction); + case IrInstSrcIdVarPtr: + return ir_analyze_instruction_var_ptr(ira, (IrInstSrcVarPtr *)instruction); + case IrInstSrcIdFieldPtr: + return ir_analyze_instruction_field_ptr(ira, (IrInstSrcFieldPtr *)instruction); + case IrInstSrcIdCall: + return ir_analyze_instruction_call(ira, (IrInstSrcCall *)instruction); + case IrInstSrcIdCallArgs: + return ir_analyze_instruction_call_args(ira, (IrInstSrcCallArgs *)instruction); + case IrInstSrcIdCallExtra: + return ir_analyze_instruction_call_extra(ira, (IrInstSrcCallExtra *)instruction); + case IrInstSrcIdBr: + return ir_analyze_instruction_br(ira, (IrInstSrcBr *)instruction); + case IrInstSrcIdCondBr: + return ir_analyze_instruction_cond_br(ira, (IrInstSrcCondBr *)instruction); + case IrInstSrcIdUnreachable: + return ir_analyze_instruction_unreachable(ira, (IrInstSrcUnreachable *)instruction); + case IrInstSrcIdPhi: + return ir_analyze_instruction_phi(ira, (IrInstSrcPhi *)instruction); + case IrInstSrcIdTypeOf: + return ir_analyze_instruction_typeof(ira, (IrInstSrcTypeOf *)instruction); + case IrInstSrcIdSetCold: + return ir_analyze_instruction_set_cold(ira, (IrInstSrcSetCold *)instruction); + case IrInstSrcIdSetRuntimeSafety: + return ir_analyze_instruction_set_runtime_safety(ira, (IrInstSrcSetRuntimeSafety *)instruction); + case IrInstSrcIdSetFloatMode: + return ir_analyze_instruction_set_float_mode(ira, (IrInstSrcSetFloatMode *)instruction); + case IrInstSrcIdAnyFrameType: + return ir_analyze_instruction_any_frame_type(ira, (IrInstSrcAnyFrameType *)instruction); + case IrInstSrcIdSliceType: + return ir_analyze_instruction_slice_type(ira, (IrInstSrcSliceType *)instruction); + case IrInstSrcIdAsm: + return ir_analyze_instruction_asm(ira, (IrInstSrcAsm *)instruction); + case IrInstSrcIdArrayType: + return ir_analyze_instruction_array_type(ira, (IrInstSrcArrayType *)instruction); + case IrInstSrcIdSizeOf: + return ir_analyze_instruction_size_of(ira, (IrInstSrcSizeOf *)instruction); + case IrInstSrcIdTestNonNull: + return ir_analyze_instruction_test_non_null(ira, (IrInstSrcTestNonNull *)instruction); + case IrInstSrcIdOptionalUnwrapPtr: + return ir_analyze_instruction_optional_unwrap_ptr(ira, (IrInstSrcOptionalUnwrapPtr *)instruction); + case IrInstSrcIdClz: + return ir_analyze_instruction_clz(ira, (IrInstSrcClz *)instruction); + case IrInstSrcIdCtz: + return ir_analyze_instruction_ctz(ira, (IrInstSrcCtz *)instruction); + case IrInstSrcIdPopCount: + return ir_analyze_instruction_pop_count(ira, (IrInstSrcPopCount *)instruction); + case IrInstSrcIdBswap: + return ir_analyze_instruction_bswap(ira, (IrInstSrcBswap *)instruction); + case IrInstSrcIdBitReverse: + return ir_analyze_instruction_bit_reverse(ira, (IrInstSrcBitReverse *)instruction); + case IrInstSrcIdSwitchBr: + return ir_analyze_instruction_switch_br(ira, (IrInstSrcSwitchBr *)instruction); + case IrInstSrcIdSwitchTarget: + return ir_analyze_instruction_switch_target(ira, (IrInstSrcSwitchTarget *)instruction); + case IrInstSrcIdSwitchVar: + return ir_analyze_instruction_switch_var(ira, (IrInstSrcSwitchVar *)instruction); + case IrInstSrcIdSwitchElseVar: + return ir_analyze_instruction_switch_else_var(ira, (IrInstSrcSwitchElseVar *)instruction); + case IrInstSrcIdImport: + return ir_analyze_instruction_import(ira, (IrInstSrcImport *)instruction); + case IrInstSrcIdRef: + return ir_analyze_instruction_ref(ira, (IrInstSrcRef *)instruction); + case IrInstSrcIdContainerInitList: + return ir_analyze_instruction_container_init_list(ira, (IrInstSrcContainerInitList *)instruction); + case IrInstSrcIdContainerInitFields: + return ir_analyze_instruction_container_init_fields(ira, (IrInstSrcContainerInitFields *)instruction); + case IrInstSrcIdCompileErr: + return ir_analyze_instruction_compile_err(ira, (IrInstSrcCompileErr *)instruction); + case IrInstSrcIdCompileLog: + return ir_analyze_instruction_compile_log(ira, (IrInstSrcCompileLog *)instruction); + case IrInstSrcIdErrName: + return ir_analyze_instruction_err_name(ira, (IrInstSrcErrName *)instruction); + case IrInstSrcIdTypeName: + return ir_analyze_instruction_type_name(ira, (IrInstSrcTypeName *)instruction); + case IrInstSrcIdCImport: + return ir_analyze_instruction_c_import(ira, (IrInstSrcCImport *)instruction); + case IrInstSrcIdCInclude: + return ir_analyze_instruction_c_include(ira, (IrInstSrcCInclude *)instruction); + case IrInstSrcIdCDefine: + return ir_analyze_instruction_c_define(ira, (IrInstSrcCDefine *)instruction); + case IrInstSrcIdCUndef: + return ir_analyze_instruction_c_undef(ira, (IrInstSrcCUndef *)instruction); + case IrInstSrcIdEmbedFile: + return ir_analyze_instruction_embed_file(ira, (IrInstSrcEmbedFile *)instruction); + case IrInstSrcIdCmpxchg: + return ir_analyze_instruction_cmpxchg(ira, (IrInstSrcCmpxchg *)instruction); + case IrInstSrcIdFence: + return ir_analyze_instruction_fence(ira, (IrInstSrcFence *)instruction); + case IrInstSrcIdTruncate: + return ir_analyze_instruction_truncate(ira, (IrInstSrcTruncate *)instruction); + case IrInstSrcIdIntCast: + return ir_analyze_instruction_int_cast(ira, (IrInstSrcIntCast *)instruction); + case IrInstSrcIdFloatCast: + return ir_analyze_instruction_float_cast(ira, (IrInstSrcFloatCast *)instruction); + case IrInstSrcIdErrSetCast: + return ir_analyze_instruction_err_set_cast(ira, (IrInstSrcErrSetCast *)instruction); + case IrInstSrcIdFromBytes: + return ir_analyze_instruction_from_bytes(ira, (IrInstSrcFromBytes *)instruction); + case IrInstSrcIdToBytes: + return ir_analyze_instruction_to_bytes(ira, (IrInstSrcToBytes *)instruction); + case IrInstSrcIdIntToFloat: + return ir_analyze_instruction_int_to_float(ira, (IrInstSrcIntToFloat *)instruction); + case IrInstSrcIdFloatToInt: + return ir_analyze_instruction_float_to_int(ira, (IrInstSrcFloatToInt *)instruction); + case IrInstSrcIdBoolToInt: + return ir_analyze_instruction_bool_to_int(ira, (IrInstSrcBoolToInt *)instruction); + case IrInstSrcIdIntType: + return ir_analyze_instruction_int_type(ira, (IrInstSrcIntType *)instruction); + case IrInstSrcIdVectorType: + return ir_analyze_instruction_vector_type(ira, (IrInstSrcVectorType *)instruction); + case IrInstSrcIdShuffleVector: + return ir_analyze_instruction_shuffle_vector(ira, (IrInstSrcShuffleVector *)instruction); + case IrInstSrcIdSplat: + return ir_analyze_instruction_splat(ira, (IrInstSrcSplat *)instruction); + case IrInstSrcIdBoolNot: + return ir_analyze_instruction_bool_not(ira, (IrInstSrcBoolNot *)instruction); + case IrInstSrcIdMemset: + return ir_analyze_instruction_memset(ira, (IrInstSrcMemset *)instruction); + case IrInstSrcIdMemcpy: + return ir_analyze_instruction_memcpy(ira, (IrInstSrcMemcpy *)instruction); + case IrInstSrcIdSlice: + return ir_analyze_instruction_slice(ira, (IrInstSrcSlice *)instruction); + case IrInstSrcIdMemberCount: + return ir_analyze_instruction_member_count(ira, (IrInstSrcMemberCount *)instruction); + case IrInstSrcIdMemberType: + return ir_analyze_instruction_member_type(ira, (IrInstSrcMemberType *)instruction); + case IrInstSrcIdMemberName: + return ir_analyze_instruction_member_name(ira, (IrInstSrcMemberName *)instruction); + case IrInstSrcIdBreakpoint: + return ir_analyze_instruction_breakpoint(ira, (IrInstSrcBreakpoint *)instruction); + case IrInstSrcIdReturnAddress: + return ir_analyze_instruction_return_address(ira, (IrInstSrcReturnAddress *)instruction); + case IrInstSrcIdFrameAddress: + return ir_analyze_instruction_frame_address(ira, (IrInstSrcFrameAddress *)instruction); + case IrInstSrcIdFrameHandle: + return ir_analyze_instruction_frame_handle(ira, (IrInstSrcFrameHandle *)instruction); + case IrInstSrcIdFrameType: + return ir_analyze_instruction_frame_type(ira, (IrInstSrcFrameType *)instruction); + case IrInstSrcIdFrameSize: + return ir_analyze_instruction_frame_size(ira, (IrInstSrcFrameSize *)instruction); + case IrInstSrcIdAlignOf: + return ir_analyze_instruction_align_of(ira, (IrInstSrcAlignOf *)instruction); + case IrInstSrcIdOverflowOp: + return ir_analyze_instruction_overflow_op(ira, (IrInstSrcOverflowOp *)instruction); + case IrInstSrcIdTestErr: + return ir_analyze_instruction_test_err(ira, (IrInstSrcTestErr *)instruction); + case IrInstSrcIdUnwrapErrCode: + return ir_analyze_instruction_unwrap_err_code(ira, (IrInstSrcUnwrapErrCode *)instruction); + case IrInstSrcIdUnwrapErrPayload: + return ir_analyze_instruction_unwrap_err_payload(ira, (IrInstSrcUnwrapErrPayload *)instruction); + case IrInstSrcIdFnProto: + return ir_analyze_instruction_fn_proto(ira, (IrInstSrcFnProto *)instruction); + case IrInstSrcIdTestComptime: + return ir_analyze_instruction_test_comptime(ira, (IrInstSrcTestComptime *)instruction); + case IrInstSrcIdCheckSwitchProngs: + return ir_analyze_instruction_check_switch_prongs(ira, (IrInstSrcCheckSwitchProngs *)instruction); + case IrInstSrcIdCheckStatementIsVoid: + return ir_analyze_instruction_check_statement_is_void(ira, (IrInstSrcCheckStatementIsVoid *)instruction); + case IrInstSrcIdDeclRef: + return ir_analyze_instruction_decl_ref(ira, (IrInstSrcDeclRef *)instruction); + case IrInstSrcIdPanic: + return ir_analyze_instruction_panic(ira, (IrInstSrcPanic *)instruction); + case IrInstSrcIdPtrCast: + return ir_analyze_instruction_ptr_cast(ira, (IrInstSrcPtrCast *)instruction); + case IrInstSrcIdIntToPtr: + return ir_analyze_instruction_int_to_ptr(ira, (IrInstSrcIntToPtr *)instruction); + case IrInstSrcIdPtrToInt: + return ir_analyze_instruction_ptr_to_int(ira, (IrInstSrcPtrToInt *)instruction); + case IrInstSrcIdTagName: + return ir_analyze_instruction_enum_tag_name(ira, (IrInstSrcTagName *)instruction); + case IrInstSrcIdFieldParentPtr: + return ir_analyze_instruction_field_parent_ptr(ira, (IrInstSrcFieldParentPtr *)instruction); + case IrInstSrcIdByteOffsetOf: + return ir_analyze_instruction_byte_offset_of(ira, (IrInstSrcByteOffsetOf *)instruction); + case IrInstSrcIdBitOffsetOf: + return ir_analyze_instruction_bit_offset_of(ira, (IrInstSrcBitOffsetOf *)instruction); + case IrInstSrcIdTypeInfo: + return ir_analyze_instruction_type_info(ira, (IrInstSrcTypeInfo *) instruction); + case IrInstSrcIdType: + return ir_analyze_instruction_type(ira, (IrInstSrcType *)instruction); + case IrInstSrcIdHasField: + return ir_analyze_instruction_has_field(ira, (IrInstSrcHasField *) instruction); + case IrInstSrcIdTypeId: + return ir_analyze_instruction_type_id(ira, (IrInstSrcTypeId *)instruction); + case IrInstSrcIdSetEvalBranchQuota: + return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstSrcSetEvalBranchQuota *)instruction); + case IrInstSrcIdPtrType: + return ir_analyze_instruction_ptr_type(ira, (IrInstSrcPtrType *)instruction); + case IrInstSrcIdAlignCast: + return ir_analyze_instruction_align_cast(ira, (IrInstSrcAlignCast *)instruction); + case IrInstSrcIdImplicitCast: + return ir_analyze_instruction_implicit_cast(ira, (IrInstSrcImplicitCast *)instruction); + case IrInstSrcIdResolveResult: + return ir_analyze_instruction_resolve_result(ira, (IrInstSrcResolveResult *)instruction); + case IrInstSrcIdResetResult: + return ir_analyze_instruction_reset_result(ira, (IrInstSrcResetResult *)instruction); + case IrInstSrcIdOpaqueType: + return ir_analyze_instruction_opaque_type(ira, (IrInstSrcOpaqueType *)instruction); + case IrInstSrcIdSetAlignStack: + return ir_analyze_instruction_set_align_stack(ira, (IrInstSrcSetAlignStack *)instruction); + case IrInstSrcIdArgType: + return ir_analyze_instruction_arg_type(ira, (IrInstSrcArgType *)instruction); + case IrInstSrcIdTagType: + return ir_analyze_instruction_tag_type(ira, (IrInstSrcTagType *)instruction); + case IrInstSrcIdExport: + return ir_analyze_instruction_export(ira, (IrInstSrcExport *)instruction); + case IrInstSrcIdErrorReturnTrace: + return ir_analyze_instruction_error_return_trace(ira, (IrInstSrcErrorReturnTrace *)instruction); + case IrInstSrcIdErrorUnion: + return ir_analyze_instruction_error_union(ira, (IrInstSrcErrorUnion *)instruction); + case IrInstSrcIdAtomicRmw: + return ir_analyze_instruction_atomic_rmw(ira, (IrInstSrcAtomicRmw *)instruction); + case IrInstSrcIdAtomicLoad: + return ir_analyze_instruction_atomic_load(ira, (IrInstSrcAtomicLoad *)instruction); + case IrInstSrcIdAtomicStore: + return ir_analyze_instruction_atomic_store(ira, (IrInstSrcAtomicStore *)instruction); + case IrInstSrcIdSaveErrRetAddr: + return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstSrcSaveErrRetAddr *)instruction); + case IrInstSrcIdAddImplicitReturnType: + return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstSrcAddImplicitReturnType *)instruction); + case IrInstSrcIdFloatOp: + return ir_analyze_instruction_float_op(ira, (IrInstSrcFloatOp *)instruction); + case IrInstSrcIdMulAdd: + return ir_analyze_instruction_mul_add(ira, (IrInstSrcMulAdd *)instruction); + case IrInstSrcIdIntToErr: + return ir_analyze_instruction_int_to_err(ira, (IrInstSrcIntToErr *)instruction); + case IrInstSrcIdErrToInt: + return ir_analyze_instruction_err_to_int(ira, (IrInstSrcErrToInt *)instruction); + case IrInstSrcIdIntToEnum: + return ir_analyze_instruction_int_to_enum(ira, (IrInstSrcIntToEnum *)instruction); + case IrInstSrcIdEnumToInt: + return ir_analyze_instruction_enum_to_int(ira, (IrInstSrcEnumToInt *)instruction); + case IrInstSrcIdCheckRuntimeScope: + return ir_analyze_instruction_check_runtime_scope(ira, (IrInstSrcCheckRuntimeScope *)instruction); + case IrInstSrcIdHasDecl: + return ir_analyze_instruction_has_decl(ira, (IrInstSrcHasDecl *)instruction); + case IrInstSrcIdUndeclaredIdent: + return ir_analyze_instruction_undeclared_ident(ira, (IrInstSrcUndeclaredIdent *)instruction); + case IrInstSrcIdAlloca: return nullptr; - case IrInstructionIdEndExpr: - return ir_analyze_instruction_end_expr(ira, (IrInstructionEndExpr *)instruction); - case IrInstructionIdBitCastSrc: - return ir_analyze_instruction_bit_cast_src(ira, (IrInstructionBitCastSrc *)instruction); - case IrInstructionIdUnionInitNamedField: - return ir_analyze_instruction_union_init_named_field(ira, (IrInstructionUnionInitNamedField *)instruction); - case IrInstructionIdSuspendBegin: - return ir_analyze_instruction_suspend_begin(ira, (IrInstructionSuspendBegin *)instruction); - case IrInstructionIdSuspendFinish: - return ir_analyze_instruction_suspend_finish(ira, (IrInstructionSuspendFinish *)instruction); - case IrInstructionIdResume: - return ir_analyze_instruction_resume(ira, (IrInstructionResume *)instruction); - case IrInstructionIdAwaitSrc: - return ir_analyze_instruction_await(ira, (IrInstructionAwaitSrc *)instruction); - case IrInstructionIdSpillBegin: - return ir_analyze_instruction_spill_begin(ira, (IrInstructionSpillBegin *)instruction); - case IrInstructionIdSpillEnd: - return ir_analyze_instruction_spill_end(ira, (IrInstructionSpillEnd *)instruction); + case IrInstSrcIdEndExpr: + return ir_analyze_instruction_end_expr(ira, (IrInstSrcEndExpr *)instruction); + case IrInstSrcIdBitCast: + return ir_analyze_instruction_bit_cast_src(ira, (IrInstSrcBitCast *)instruction); + case IrInstSrcIdUnionInitNamedField: + return ir_analyze_instruction_union_init_named_field(ira, (IrInstSrcUnionInitNamedField *)instruction); + case IrInstSrcIdSuspendBegin: + return ir_analyze_instruction_suspend_begin(ira, (IrInstSrcSuspendBegin *)instruction); + case IrInstSrcIdSuspendFinish: + return ir_analyze_instruction_suspend_finish(ira, (IrInstSrcSuspendFinish *)instruction); + case IrInstSrcIdResume: + return ir_analyze_instruction_resume(ira, (IrInstSrcResume *)instruction); + case IrInstSrcIdAwait: + return ir_analyze_instruction_await(ira, (IrInstSrcAwait *)instruction); + case IrInstSrcIdSpillBegin: + return ir_analyze_instruction_spill_begin(ira, (IrInstSrcSpillBegin *)instruction); + case IrInstSrcIdSpillEnd: + return ir_analyze_instruction_spill_end(ira, (IrInstSrcSpillEnd *)instruction); } zig_unreachable(); } // This function attempts to evaluate IR code while doing type checking and other analysis. -// It emits a new IrExecutable which is partially evaluated IR code. -ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, - ZigType *expected_type, AstNode *expected_type_source_node) +// It emits to a new IrExecutableGen which is partially evaluated IR code. +ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen *new_exec, + ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *result_ptr) { assert(old_exec->first_err_trace_msg == nullptr); assert(expected_type == nullptr || !type_is_invalid(expected_type)); @@ -28982,24 +29875,31 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ ira->new_irb.codegen = codegen; ira->new_irb.exec = new_exec; - ZigValue *vals = create_const_vals(ira->old_irb.exec->mem_slot_count); - ira->exec_context.mem_slot_list.resize(ira->old_irb.exec->mem_slot_count); - for (size_t i = 0; i < ira->exec_context.mem_slot_list.length; i += 1) { - ira->exec_context.mem_slot_list.items[i] = &vals[i]; - } - - IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); - IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); - ir_ref_bb(new_entry_bb); + IrBasicBlockSrc *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); + IrBasicBlockGen *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); + ir_ref_bb_gen(new_entry_bb); ira->new_irb.current_basic_block = new_entry_bb; ira->old_bb_index = 0; ir_start_bb(ira, old_entry_bb, nullptr); + if (result_ptr != nullptr) { + assert(result_ptr->type->id == ZigTypeIdPointer); + IrInstGenConst *const_inst = ir_create_inst_noval<IrInstGenConst>( + &ira->new_irb, new_exec->begin_scope, new_exec->source_node); + const_inst->base.value = result_ptr; + ira->return_ptr = &const_inst->base; + } else { + assert(new_exec->begin_scope != nullptr); + assert(new_exec->source_node != nullptr); + ira->return_ptr = ir_build_return_ptr(ira, new_exec->begin_scope, new_exec->source_node, + get_pointer_to_type(codegen, expected_type, false)); + } + while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { - IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); + IrInstSrc *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); - if (old_instruction->ref_count == 0 && !ir_has_side_effects(old_instruction)) { + if (old_instruction->base.ref_count == 0 && !ir_inst_src_has_side_effects(old_instruction)) { ira->instruction_index += 1; continue; } @@ -29008,14 +29908,14 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ fprintf(stderr, "~ "); old_instruction->src(); fprintf(stderr, "~ "); - ir_print_instruction(codegen, stderr, old_instruction, 0, IrPassSrc); + ir_print_inst_src(codegen, stderr, old_instruction, 0); bool want_break = false; - if (ira->break_debug_id == old_instruction->debug_id) { + if (ira->break_debug_id == old_instruction->base.debug_id) { want_break = true; - } else if (old_instruction->source_node != nullptr) { + } else if (old_instruction->base.source_node != nullptr) { for (size_t i = 0; i < dbg_ir_breakpoints_count; i += 1) { - if (dbg_ir_breakpoints_buf[i].line == old_instruction->source_node->line + 1 && - buf_ends_with_str(old_instruction->source_node->owner->data.structure.root_struct->path, + if (dbg_ir_breakpoints_buf[i].line == old_instruction->base.source_node->line + 1 && + buf_ends_with_str(old_instruction->base.source_node->owner->data.structure.root_struct->path, dbg_ir_breakpoints_buf[i].src_file)) { want_break = true; @@ -29024,9 +29924,9 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ } if (want_break) BREAKPOINT; } - IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); + IrInstGen *new_instruction = ir_analyze_instruction_base(ira, old_instruction); if (new_instruction != nullptr) { - ir_assert(new_instruction->value->type != nullptr || new_instruction->value->type != nullptr, old_instruction); + ir_assert(new_instruction->value->type != nullptr || new_instruction->value->type != nullptr, &old_instruction->base); old_instruction->child = new_instruction; if (type_is_invalid(new_instruction->value->type)) { @@ -29040,19 +29940,19 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ new_exec->first_err_trace_msg = ira->codegen->trace_err; } if (new_exec->first_err_trace_msg != nullptr && - !old_instruction->source_node->already_traced_this_node) + !old_instruction->base.source_node->already_traced_this_node) { - old_instruction->source_node->already_traced_this_node = true; + old_instruction->base.source_node->already_traced_this_node = true; new_exec->first_err_trace_msg = add_error_note(ira->codegen, new_exec->first_err_trace_msg, - old_instruction->source_node, buf_create_from_str("referenced here")); + old_instruction->base.source_node, buf_create_from_str("referenced here")); } return ira->codegen->builtin_types.entry_invalid; } else if (ira->codegen->verbose_ir) { fprintf(stderr, "-> "); - if (instr_is_unreachable(new_instruction)) { + if (new_instruction->value->type->id == ZigTypeIdUnreachable) { fprintf(stderr, "(noreturn)\n"); } else { - ir_print_instruction(codegen, stderr, new_instruction, 0, IrPassGen); + ir_print_inst_gen(codegen, stderr, new_instruction, 0); } } @@ -29092,204 +29992,280 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ return res_type; } -bool ir_has_side_effects(IrInstruction *instruction) { +bool ir_inst_gen_has_side_effects(IrInstGen *instruction) { switch (instruction->id) { - case IrInstructionIdInvalid: + case IrInstGenIdInvalid: zig_unreachable(); - case IrInstructionIdBr: - case IrInstructionIdCondBr: - case IrInstructionIdSwitchBr: - case IrInstructionIdDeclVarSrc: - case IrInstructionIdDeclVarGen: - case IrInstructionIdStorePtr: - case IrInstructionIdVectorStoreElem: - case IrInstructionIdCallExtra: - case IrInstructionIdCallSrc: - case IrInstructionIdCallSrcArgs: - case IrInstructionIdCallGen: - case IrInstructionIdReturn: - case IrInstructionIdUnreachable: - case IrInstructionIdSetCold: - case IrInstructionIdSetRuntimeSafety: - case IrInstructionIdSetFloatMode: - case IrInstructionIdImport: - case IrInstructionIdCompileErr: - case IrInstructionIdCompileLog: - case IrInstructionIdCImport: - case IrInstructionIdCInclude: - case IrInstructionIdCDefine: - case IrInstructionIdCUndef: - case IrInstructionIdFence: - case IrInstructionIdMemset: - case IrInstructionIdMemcpy: - case IrInstructionIdBreakpoint: - case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free - case IrInstructionIdCheckSwitchProngs: - case IrInstructionIdCheckStatementIsVoid: - case IrInstructionIdCheckRuntimeScope: - case IrInstructionIdPanic: - case IrInstructionIdSetEvalBranchQuota: - case IrInstructionIdPtrType: - case IrInstructionIdSetAlignStack: - case IrInstructionIdExport: - case IrInstructionIdSaveErrRetAddr: - case IrInstructionIdAddImplicitReturnType: - case IrInstructionIdAtomicRmw: - case IrInstructionIdAtomicStore: - case IrInstructionIdCmpxchgGen: - case IrInstructionIdCmpxchgSrc: - case IrInstructionIdAssertZero: - case IrInstructionIdAssertNonNull: - case IrInstructionIdResizeSlice: - case IrInstructionIdUndeclaredIdent: - case IrInstructionIdEndExpr: - case IrInstructionIdPtrOfArrayToSlice: - case IrInstructionIdSliceGen: - case IrInstructionIdOptionalWrap: - case IrInstructionIdVectorToArray: - case IrInstructionIdResetResult: - case IrInstructionIdSuspendBegin: - case IrInstructionIdSuspendFinish: - case IrInstructionIdResume: - case IrInstructionIdAwaitSrc: - case IrInstructionIdAwaitGen: - case IrInstructionIdSpillBegin: + case IrInstGenIdBr: + case IrInstGenIdCondBr: + case IrInstGenIdSwitchBr: + case IrInstGenIdDeclVar: + case IrInstGenIdStorePtr: + case IrInstGenIdVectorStoreElem: + case IrInstGenIdCall: + case IrInstGenIdReturn: + case IrInstGenIdUnreachable: + case IrInstGenIdFence: + case IrInstGenIdMemset: + case IrInstGenIdMemcpy: + case IrInstGenIdBreakpoint: + case IrInstGenIdOverflowOp: // TODO when we support multiple returns this can be side effect free + case IrInstGenIdPanic: + case IrInstGenIdSaveErrRetAddr: + case IrInstGenIdAtomicRmw: + case IrInstGenIdAtomicStore: + case IrInstGenIdCmpxchg: + case IrInstGenIdAssertZero: + case IrInstGenIdAssertNonNull: + case IrInstGenIdResizeSlice: + case IrInstGenIdPtrOfArrayToSlice: + case IrInstGenIdSlice: + case IrInstGenIdOptionalWrap: + case IrInstGenIdVectorToArray: + case IrInstGenIdSuspendBegin: + case IrInstGenIdSuspendFinish: + case IrInstGenIdResume: + case IrInstGenIdAwait: + case IrInstGenIdSpillBegin: return true; - case IrInstructionIdPhi: - case IrInstructionIdUnOp: - case IrInstructionIdBinOp: - case IrInstructionIdMergeErrSets: - case IrInstructionIdLoadPtr: - case IrInstructionIdConst: - case IrInstructionIdCast: - case IrInstructionIdContainerInitList: - case IrInstructionIdContainerInitFields: - case IrInstructionIdUnionInitNamedField: - case IrInstructionIdFieldPtr: - case IrInstructionIdElemPtr: - case IrInstructionIdVarPtr: - case IrInstructionIdReturnPtr: - case IrInstructionIdTypeOf: - case IrInstructionIdStructFieldPtr: - case IrInstructionIdArrayType: - case IrInstructionIdSliceType: - case IrInstructionIdAnyFrameType: - case IrInstructionIdSizeOf: - case IrInstructionIdTestNonNull: - case IrInstructionIdOptionalUnwrapPtr: - case IrInstructionIdClz: - case IrInstructionIdCtz: - case IrInstructionIdPopCount: - case IrInstructionIdBswap: - case IrInstructionIdBitReverse: - case IrInstructionIdSwitchVar: - case IrInstructionIdSwitchElseVar: - case IrInstructionIdSwitchTarget: - case IrInstructionIdUnionTag: - case IrInstructionIdRef: - case IrInstructionIdEmbedFile: - case IrInstructionIdTruncate: - case IrInstructionIdIntType: - case IrInstructionIdVectorType: - case IrInstructionIdShuffleVector: - case IrInstructionIdSplatSrc: - case IrInstructionIdSplatGen: - case IrInstructionIdBoolNot: - case IrInstructionIdSliceSrc: - case IrInstructionIdMemberCount: - case IrInstructionIdMemberType: - case IrInstructionIdMemberName: - case IrInstructionIdAlignOf: - case IrInstructionIdReturnAddress: - case IrInstructionIdFrameAddress: - case IrInstructionIdFrameHandle: - case IrInstructionIdFrameType: - case IrInstructionIdFrameSizeSrc: - case IrInstructionIdFrameSizeGen: - case IrInstructionIdTestErrSrc: - case IrInstructionIdTestErrGen: - case IrInstructionIdFnProto: - case IrInstructionIdTestComptime: - case IrInstructionIdPtrCastSrc: - case IrInstructionIdPtrCastGen: - case IrInstructionIdBitCastSrc: - case IrInstructionIdBitCastGen: - case IrInstructionIdWidenOrShorten: - case IrInstructionIdPtrToInt: - case IrInstructionIdIntToPtr: - case IrInstructionIdIntToEnum: - case IrInstructionIdIntToErr: - case IrInstructionIdErrToInt: - case IrInstructionIdDeclRef: - case IrInstructionIdErrName: - case IrInstructionIdTypeName: - case IrInstructionIdTagName: - case IrInstructionIdFieldParentPtr: - case IrInstructionIdByteOffsetOf: - case IrInstructionIdBitOffsetOf: - case IrInstructionIdTypeInfo: - case IrInstructionIdType: - case IrInstructionIdHasField: - case IrInstructionIdTypeId: - case IrInstructionIdAlignCast: - case IrInstructionIdImplicitCast: - case IrInstructionIdResolveResult: - case IrInstructionIdOpaqueType: - case IrInstructionIdArgType: - case IrInstructionIdTagType: - case IrInstructionIdErrorReturnTrace: - case IrInstructionIdErrorUnion: - case IrInstructionIdFloatOp: - case IrInstructionIdMulAdd: - case IrInstructionIdAtomicLoad: - case IrInstructionIdIntCast: - case IrInstructionIdFloatCast: - case IrInstructionIdErrSetCast: - case IrInstructionIdIntToFloat: - case IrInstructionIdFloatToInt: - case IrInstructionIdBoolToInt: - case IrInstructionIdFromBytes: - case IrInstructionIdToBytes: - case IrInstructionIdEnumToInt: - case IrInstructionIdArrayToVector: - case IrInstructionIdHasDecl: - case IrInstructionIdAllocaSrc: - case IrInstructionIdAllocaGen: - case IrInstructionIdSpillEnd: - case IrInstructionIdVectorExtractElem: + case IrInstGenIdPhi: + case IrInstGenIdBinOp: + case IrInstGenIdConst: + case IrInstGenIdCast: + case IrInstGenIdElemPtr: + case IrInstGenIdVarPtr: + case IrInstGenIdReturnPtr: + case IrInstGenIdStructFieldPtr: + case IrInstGenIdTestNonNull: + case IrInstGenIdClz: + case IrInstGenIdCtz: + case IrInstGenIdPopCount: + case IrInstGenIdBswap: + case IrInstGenIdBitReverse: + case IrInstGenIdUnionTag: + case IrInstGenIdTruncate: + case IrInstGenIdShuffleVector: + case IrInstGenIdSplat: + case IrInstGenIdBoolNot: + case IrInstGenIdReturnAddress: + case IrInstGenIdFrameAddress: + case IrInstGenIdFrameHandle: + case IrInstGenIdFrameSize: + case IrInstGenIdTestErr: + case IrInstGenIdPtrCast: + case IrInstGenIdBitCast: + case IrInstGenIdWidenOrShorten: + case IrInstGenIdPtrToInt: + case IrInstGenIdIntToPtr: + case IrInstGenIdIntToEnum: + case IrInstGenIdIntToErr: + case IrInstGenIdErrToInt: + case IrInstGenIdErrName: + case IrInstGenIdTagName: + case IrInstGenIdFieldParentPtr: + case IrInstGenIdAlignCast: + case IrInstGenIdErrorReturnTrace: + case IrInstGenIdFloatOp: + case IrInstGenIdMulAdd: + case IrInstGenIdAtomicLoad: + case IrInstGenIdArrayToVector: + case IrInstGenIdAlloca: + case IrInstGenIdSpillEnd: + case IrInstGenIdVectorExtractElem: + case IrInstGenIdBinaryNot: + case IrInstGenIdNegation: + case IrInstGenIdNegationWrapping: return false; - case IrInstructionIdAsmSrc: + case IrInstGenIdAsm: { - IrInstructionAsmSrc *asm_instruction = (IrInstructionAsmSrc *)instruction; + IrInstGenAsm *asm_instruction = (IrInstGenAsm *)instruction; return asm_instruction->has_side_effects; } + case IrInstGenIdUnwrapErrPayload: + { + IrInstGenUnwrapErrPayload *unwrap_err_payload_instruction = + (IrInstGenUnwrapErrPayload *)instruction; + return unwrap_err_payload_instruction->safety_check_on || + unwrap_err_payload_instruction->initializing; + } + case IrInstGenIdUnwrapErrCode: + return reinterpret_cast<IrInstGenUnwrapErrCode *>(instruction)->initializing; + case IrInstGenIdUnionFieldPtr: + return reinterpret_cast<IrInstGenUnionFieldPtr *>(instruction)->initializing; + case IrInstGenIdOptionalUnwrapPtr: + return reinterpret_cast<IrInstGenOptionalUnwrapPtr *>(instruction)->initializing; + case IrInstGenIdErrWrapPayload: + return reinterpret_cast<IrInstGenErrWrapPayload *>(instruction)->result_loc != nullptr; + case IrInstGenIdErrWrapCode: + return reinterpret_cast<IrInstGenErrWrapCode *>(instruction)->result_loc != nullptr; + case IrInstGenIdLoadPtr: + return reinterpret_cast<IrInstGenLoadPtr *>(instruction)->result_loc != nullptr; + case IrInstGenIdRef: + return reinterpret_cast<IrInstGenRef *>(instruction)->result_loc != nullptr; + } + zig_unreachable(); +} + +bool ir_inst_src_has_side_effects(IrInstSrc *instruction) { + switch (instruction->id) { + case IrInstSrcIdInvalid: + zig_unreachable(); + case IrInstSrcIdBr: + case IrInstSrcIdCondBr: + case IrInstSrcIdSwitchBr: + case IrInstSrcIdDeclVar: + case IrInstSrcIdStorePtr: + case IrInstSrcIdCallExtra: + case IrInstSrcIdCall: + case IrInstSrcIdCallArgs: + case IrInstSrcIdReturn: + case IrInstSrcIdUnreachable: + case IrInstSrcIdSetCold: + case IrInstSrcIdSetRuntimeSafety: + case IrInstSrcIdSetFloatMode: + case IrInstSrcIdImport: + case IrInstSrcIdCompileErr: + case IrInstSrcIdCompileLog: + case IrInstSrcIdCImport: + case IrInstSrcIdCInclude: + case IrInstSrcIdCDefine: + case IrInstSrcIdCUndef: + case IrInstSrcIdFence: + case IrInstSrcIdMemset: + case IrInstSrcIdMemcpy: + case IrInstSrcIdBreakpoint: + case IrInstSrcIdOverflowOp: // TODO when we support multiple returns this can be side effect free + case IrInstSrcIdCheckSwitchProngs: + case IrInstSrcIdCheckStatementIsVoid: + case IrInstSrcIdCheckRuntimeScope: + case IrInstSrcIdPanic: + case IrInstSrcIdSetEvalBranchQuota: + case IrInstSrcIdPtrType: + case IrInstSrcIdSetAlignStack: + case IrInstSrcIdExport: + case IrInstSrcIdSaveErrRetAddr: + case IrInstSrcIdAddImplicitReturnType: + case IrInstSrcIdAtomicRmw: + case IrInstSrcIdAtomicStore: + case IrInstSrcIdCmpxchg: + case IrInstSrcIdUndeclaredIdent: + case IrInstSrcIdEndExpr: + case IrInstSrcIdResetResult: + case IrInstSrcIdSuspendBegin: + case IrInstSrcIdSuspendFinish: + case IrInstSrcIdResume: + case IrInstSrcIdAwait: + case IrInstSrcIdSpillBegin: + return true; + + case IrInstSrcIdPhi: + case IrInstSrcIdUnOp: + case IrInstSrcIdBinOp: + case IrInstSrcIdMergeErrSets: + case IrInstSrcIdLoadPtr: + case IrInstSrcIdConst: + case IrInstSrcIdContainerInitList: + case IrInstSrcIdContainerInitFields: + case IrInstSrcIdUnionInitNamedField: + case IrInstSrcIdFieldPtr: + case IrInstSrcIdElemPtr: + case IrInstSrcIdVarPtr: + case IrInstSrcIdTypeOf: + case IrInstSrcIdArrayType: + case IrInstSrcIdSliceType: + case IrInstSrcIdAnyFrameType: + case IrInstSrcIdSizeOf: + case IrInstSrcIdTestNonNull: + case IrInstSrcIdOptionalUnwrapPtr: + case IrInstSrcIdClz: + case IrInstSrcIdCtz: + case IrInstSrcIdPopCount: + case IrInstSrcIdBswap: + case IrInstSrcIdBitReverse: + case IrInstSrcIdSwitchVar: + case IrInstSrcIdSwitchElseVar: + case IrInstSrcIdSwitchTarget: + case IrInstSrcIdRef: + case IrInstSrcIdEmbedFile: + case IrInstSrcIdTruncate: + case IrInstSrcIdIntType: + case IrInstSrcIdVectorType: + case IrInstSrcIdShuffleVector: + case IrInstSrcIdSplat: + case IrInstSrcIdBoolNot: + case IrInstSrcIdSlice: + case IrInstSrcIdMemberCount: + case IrInstSrcIdMemberType: + case IrInstSrcIdMemberName: + case IrInstSrcIdAlignOf: + case IrInstSrcIdReturnAddress: + case IrInstSrcIdFrameAddress: + case IrInstSrcIdFrameHandle: + case IrInstSrcIdFrameType: + case IrInstSrcIdFrameSize: + case IrInstSrcIdTestErr: + case IrInstSrcIdFnProto: + case IrInstSrcIdTestComptime: + case IrInstSrcIdPtrCast: + case IrInstSrcIdBitCast: + case IrInstSrcIdPtrToInt: + case IrInstSrcIdIntToPtr: + case IrInstSrcIdIntToEnum: + case IrInstSrcIdIntToErr: + case IrInstSrcIdErrToInt: + case IrInstSrcIdDeclRef: + case IrInstSrcIdErrName: + case IrInstSrcIdTypeName: + case IrInstSrcIdTagName: + case IrInstSrcIdFieldParentPtr: + case IrInstSrcIdByteOffsetOf: + case IrInstSrcIdBitOffsetOf: + case IrInstSrcIdTypeInfo: + case IrInstSrcIdType: + case IrInstSrcIdHasField: + case IrInstSrcIdTypeId: + case IrInstSrcIdAlignCast: + case IrInstSrcIdImplicitCast: + case IrInstSrcIdResolveResult: + case IrInstSrcIdOpaqueType: + case IrInstSrcIdArgType: + case IrInstSrcIdTagType: + case IrInstSrcIdErrorReturnTrace: + case IrInstSrcIdErrorUnion: + case IrInstSrcIdFloatOp: + case IrInstSrcIdMulAdd: + case IrInstSrcIdAtomicLoad: + case IrInstSrcIdIntCast: + case IrInstSrcIdFloatCast: + case IrInstSrcIdErrSetCast: + case IrInstSrcIdIntToFloat: + case IrInstSrcIdFloatToInt: + case IrInstSrcIdBoolToInt: + case IrInstSrcIdFromBytes: + case IrInstSrcIdToBytes: + case IrInstSrcIdEnumToInt: + case IrInstSrcIdHasDecl: + case IrInstSrcIdAlloca: + case IrInstSrcIdSpillEnd: + return false; - case IrInstructionIdAsmGen: + case IrInstSrcIdAsm: { - IrInstructionAsmGen *asm_instruction = (IrInstructionAsmGen *)instruction; + IrInstSrcAsm *asm_instruction = (IrInstSrcAsm *)instruction; return asm_instruction->has_side_effects; } - case IrInstructionIdUnwrapErrPayload: + + case IrInstSrcIdUnwrapErrPayload: { - IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = - (IrInstructionUnwrapErrPayload *)instruction; + IrInstSrcUnwrapErrPayload *unwrap_err_payload_instruction = + (IrInstSrcUnwrapErrPayload *)instruction; return unwrap_err_payload_instruction->safety_check_on || unwrap_err_payload_instruction->initializing; } - case IrInstructionIdUnwrapErrCode: - return reinterpret_cast<IrInstructionUnwrapErrCode *>(instruction)->initializing; - case IrInstructionIdUnionFieldPtr: - return reinterpret_cast<IrInstructionUnionFieldPtr *>(instruction)->initializing; - case IrInstructionIdErrWrapPayload: - return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr; - case IrInstructionIdErrWrapCode: - return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr; - case IrInstructionIdLoadPtrGen: - return reinterpret_cast<IrInstructionLoadPtrGen *>(instruction)->result_loc != nullptr; - case IrInstructionIdRefGen: - return reinterpret_cast<IrInstructionRefGen *>(instruction)->result_loc != nullptr; + case IrInstSrcIdUnwrapErrCode: + return reinterpret_cast<IrInstSrcUnwrapErrCode *>(instruction)->initializing; } zig_unreachable(); } @@ -29323,14 +30299,14 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La param_info->type = nullptr; return get_generic_fn_type(ira->codegen, &fn_type_id); } else { - IrInstruction *param_type_inst = lazy_fn_type->param_types[fn_type_id.next_param_index]; + IrInstGen *param_type_inst = lazy_fn_type->param_types[fn_type_id.next_param_index]; ZigType *param_type = ir_resolve_type(ira, param_type_inst); if (type_is_invalid(param_type)) return nullptr; switch (type_requires_comptime(ira->codegen, param_type)) { case ReqCompTimeYes: if (!calling_convention_allows_zig_types(fn_type_id.cc)) { - ir_add_error(ira, param_type_inst, + ir_add_error(ira, ¶m_type_inst->base, buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); return nullptr; @@ -29348,7 +30324,7 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La if ((err = type_has_bits2(ira->codegen, param_type, &has_bits))) return nullptr; if (!has_bits) { - ir_add_error(ira, param_type_inst, + ir_add_error(ira, ¶m_type_inst->base, buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); return nullptr; @@ -29367,7 +30343,7 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La if (type_is_invalid(fn_type_id.return_type)) return nullptr; if (fn_type_id.return_type->id == ZigTypeIdOpaque) { - ir_add_error(ira, lazy_fn_type->return_type, buf_create_from_str("return type cannot be opaque")); + ir_add_error(ira, &lazy_fn_type->return_type->base, buf_create_from_str("return type cannot be opaque")); return nullptr; } @@ -29399,7 +30375,7 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { case ZigTypeIdBoundFn: case ZigTypeIdVoid: case ZigTypeIdOpaque: - ir_add_error(ira, lazy_align_of->target_type, + ir_add_error(ira, &lazy_align_of->target_type->base, buf_sprintf("no align available for type '%s'", buf_ptr(&lazy_align_of->target_type->value->data.x_type->name))); return ErrorSemanticAnalyzeFail; @@ -29449,7 +30425,7 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { case ZigTypeIdNull: case ZigTypeIdBoundFn: case ZigTypeIdOpaque: - ir_add_error(ira, lazy_size_of->target_type, + ir_add_error(ira, &lazy_size_of->target_type->base, buf_sprintf("no size available for type '%s'", buf_ptr(&lazy_size_of->target_type->value->data.x_type->name))); return ErrorSemanticAnalyzeFail; @@ -29507,7 +30483,7 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { if (lazy_slice_type->sentinel != nullptr) { if (type_is_invalid(lazy_slice_type->sentinel->value->type)) return ErrorSemanticAnalyzeFail; - IrInstruction *sentinel = ir_implicit_cast(ira, lazy_slice_type->sentinel, elem_type); + IrInstGen *sentinel = ir_implicit_cast(ira, lazy_slice_type->sentinel, elem_type); if (type_is_invalid(sentinel->value->type)) return ErrorSemanticAnalyzeFail; sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); @@ -29530,7 +30506,7 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { case ZigTypeIdUndefined: case ZigTypeIdNull: case ZigTypeIdOpaque: - ir_add_error(ira, lazy_slice_type->elem_type, + ir_add_error(ira, &lazy_slice_type->elem_type->base, buf_sprintf("slice of type '%s' not allowed", buf_ptr(&elem_type->name))); return ErrorSemanticAnalyzeFail; case ZigTypeIdMetaType: @@ -29586,7 +30562,7 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { if (lazy_ptr_type->sentinel != nullptr) { if (type_is_invalid(lazy_ptr_type->sentinel->value->type)) return ErrorSemanticAnalyzeFail; - IrInstruction *sentinel = ir_implicit_cast(ira, lazy_ptr_type->sentinel, elem_type); + IrInstGen *sentinel = ir_implicit_cast(ira, lazy_ptr_type->sentinel, elem_type); if (type_is_invalid(sentinel->value->type)) return ErrorSemanticAnalyzeFail; sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); @@ -29603,11 +30579,11 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { } if (elem_type->id == ZigTypeIdUnreachable) { - ir_add_error(ira, lazy_ptr_type->elem_type, + ir_add_error(ira, &lazy_ptr_type->elem_type->base, buf_create_from_str("pointer to noreturn not allowed")); return ErrorSemanticAnalyzeFail; } else if (elem_type->id == ZigTypeIdOpaque && lazy_ptr_type->ptr_len == PtrLenUnknown) { - ir_add_error(ira, lazy_ptr_type->elem_type, + ir_add_error(ira, &lazy_ptr_type->elem_type->base, buf_create_from_str("unknown-length pointer to opaque")); return ErrorSemanticAnalyzeFail; } else if (lazy_ptr_type->ptr_len == PtrLenC) { @@ -29615,16 +30591,16 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { if ((err = type_allowed_in_extern(ira->codegen, elem_type, &ok_type))) return err; if (!ok_type) { - ir_add_error(ira, lazy_ptr_type->elem_type, + ir_add_error(ira, &lazy_ptr_type->elem_type->base, buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", buf_ptr(&elem_type->name))); return ErrorSemanticAnalyzeFail; } else if (elem_type->id == ZigTypeIdOpaque) { - ir_add_error(ira, lazy_ptr_type->elem_type, + ir_add_error(ira, &lazy_ptr_type->elem_type->base, buf_sprintf("C pointers cannot point opaque types")); return ErrorSemanticAnalyzeFail; } else if (lazy_ptr_type->is_allowzero) { - ir_add_error(ira, lazy_ptr_type->elem_type, + ir_add_error(ira, &lazy_ptr_type->elem_type->base, buf_sprintf("C pointers always allow address zero")); return ErrorSemanticAnalyzeFail; } @@ -29662,7 +30638,7 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { case ZigTypeIdUndefined: case ZigTypeIdNull: case ZigTypeIdOpaque: - ir_add_error(ira, lazy_array_type->elem_type, + ir_add_error(ira, &lazy_array_type->elem_type->base, buf_sprintf("array of type '%s' not allowed", buf_ptr(&elem_type->name))); return ErrorSemanticAnalyzeFail; @@ -29697,7 +30673,7 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { if (lazy_array_type->sentinel != nullptr) { if (type_is_invalid(lazy_array_type->sentinel->value->type)) return ErrorSemanticAnalyzeFail; - IrInstruction *sentinel = ir_implicit_cast(ira, lazy_array_type->sentinel, elem_type); + IrInstGen *sentinel = ir_implicit_cast(ira, lazy_array_type->sentinel, elem_type); if (type_is_invalid(sentinel->value->type)) return ErrorSemanticAnalyzeFail; sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); @@ -29721,7 +30697,7 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { return ErrorSemanticAnalyzeFail; if (payload_type->id == ZigTypeIdOpaque || payload_type->id == ZigTypeIdUnreachable) { - ir_add_error(ira, lazy_opt_type->payload_type, + ir_add_error(ira, &lazy_opt_type->payload_type->base, buf_sprintf("type '%s' cannot be optional", buf_ptr(&payload_type->name))); return ErrorSemanticAnalyzeFail; } @@ -29763,7 +30739,7 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { return ErrorSemanticAnalyzeFail; if (err_set_type->id != ZigTypeIdErrorSet) { - ir_add_error(ira, lazy_err_union_type->err_set_type, + ir_add_error(ira, &lazy_err_union_type->err_set_type->base, buf_sprintf("expected error set type, found type '%s'", buf_ptr(&err_set_type->name))); return ErrorSemanticAnalyzeFail; @@ -29799,8 +30775,8 @@ Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val) { return ErrorNone; } -void IrInstruction::src() { - IrInstruction *inst = this; +void IrInst::src() { + IrInst *inst = this; if (inst->source_node != nullptr) { inst->source_node->src(); } else { @@ -29808,26 +30784,45 @@ void IrInstruction::src() { } } -void IrInstruction::dump() { - IrInstruction *inst = this; +void IrInst::dump() { + this->src(); + fprintf(stderr, "IrInst(#%" PRIu32 ")\n", this->debug_id); +} + +void IrInstSrc::src() { + this->base.src(); +} + +void IrInstGen::src() { + this->base.src(); +} + +void IrInstSrc::dump() { + IrInstSrc *inst = this; inst->src(); - IrPass pass = (inst->child == nullptr) ? IrPassGen : IrPassSrc; - if (inst->scope == nullptr) { + if (inst->base.scope == nullptr) { fprintf(stderr, "(null scope)\n"); } else { - ir_print_instruction(inst->scope->codegen, stderr, inst, 0, pass); - if (pass == IrPassSrc) { - fprintf(stderr, "-> "); - ir_print_instruction(inst->scope->codegen, stderr, inst->child, 0, IrPassGen); - } + ir_print_inst_src(inst->base.scope->codegen, stderr, inst, 0); + fprintf(stderr, "-> "); + ir_print_inst_gen(inst->base.scope->codegen, stderr, inst->child, 0); + } +} +void IrInstGen::dump() { + IrInstGen *inst = this; + inst->src(); + if (inst->base.scope == nullptr) { + fprintf(stderr, "(null scope)\n"); + } else { + ir_print_inst_gen(inst->base.scope->codegen, stderr, inst, 0); } } void IrAnalyze::dump() { - ir_print(this->codegen, stderr, this->new_irb.exec, 0, IrPassGen); + ir_print_gen(this->codegen, stderr, this->new_irb.exec, 0); if (this->new_irb.current_basic_block != nullptr) { fprintf(stderr, "Current basic block:\n"); - ir_print_basic_block(this->codegen, stderr, this->new_irb.current_basic_block, 1, IrPassGen); + ir_print_basic_block_gen(this->codegen, stderr, this->new_irb.current_basic_block, 1); } } |
