aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp486
1 files changed, 456 insertions, 30 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 8f79841df3..a2c5a4318a 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -41,6 +41,7 @@ struct IrAnalyze {
ZigList<IrInstruction *> src_implicit_return_type_list;
ZigList<IrSuspendPosition> resume_stack;
IrBasicBlock *const_predecessor_bb;
+ size_t ref_count;
// For the purpose of using in a debugger
void dump();
@@ -74,6 +75,7 @@ enum ConstCastResultId {
ConstCastResultIdPtrLens,
ConstCastResultIdCV,
ConstCastResultIdPtrSentinel,
+ ConstCastResultIdIntShorten,
};
struct ConstCastOnly;
@@ -100,6 +102,7 @@ struct ConstCastBadAllowsZero;
struct ConstCastBadNullTermArrays;
struct ConstCastBadCV;
struct ConstCastPtrSentinel;
+struct ConstCastIntShorten;
struct ConstCastOnly {
ConstCastResultId id;
@@ -120,6 +123,7 @@ struct ConstCastOnly {
ConstCastBadNullTermArrays *sentinel_arrays;
ConstCastBadCV *bad_cv;
ConstCastPtrSentinel *bad_ptr_sentinel;
+ ConstCastIntShorten *int_shorten;
} data;
};
@@ -189,6 +193,11 @@ struct ConstCastPtrSentinel {
ZigType *actual_type;
};
+struct ConstCastIntShorten {
+ ZigType *wanted_type;
+ ZigType *actual_type;
+};
+
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,
ResultLoc *result_loc);
@@ -248,6 +257,381 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n
IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type);
static ResultLoc *no_result_loc(void);
+static void destroy_instruction(IrInstruction *inst) {
+#ifdef ZIG_ENABLE_MEM_PROFILE
+ const char *name = ir_instruction_type_str(inst->id);
+#else
+ const char *name = nullptr;
+#endif
+ switch (inst->id) {
+ case IrInstructionIdInvalid:
+ 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 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 IrInstructionIdGlobalAsm:
+ return destroy(reinterpret_cast<IrInstructionGlobalAsm *>(inst), name);
+ case IrInstructionIdAsm:
+ return destroy(reinterpret_cast<IrInstructionAsm *>(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);
+ }
+ zig_unreachable();
+}
+
+static void ira_ref(IrAnalyze *ira) {
+ ira->ref_count += 1;
+}
+static void ira_deref(IrAnalyze *ira) {
+ if (ira->ref_count > 1) {
+ ira->ref_count -= 1;
+ return;
+ }
+ 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];
+ 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);
+ }
+ destroy(pass1_bb, "IrBasicBlock");
+ }
+ 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");
+ ira->src_implicit_return_type_list.deinit();
+ ira->resume_stack.deinit();
+ ira->exec_context.mem_slot_list.deinit();
+ destroy(ira, "IrAnalyze");
+}
+
static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) {
assert(get_src_ptr_type(const_val->type) != nullptr);
assert(const_val->special == ConstValSpecialStatic);
@@ -4186,7 +4570,7 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod
IrInstruction **incoming_values = allocate<IrInstruction *>(2);
incoming_values[0] = val1;
incoming_values[1] = val2;
- IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
+ IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *");
incoming_blocks[0] = post_val1_block;
incoming_blocks[1] = post_val2_block;
@@ -4277,7 +4661,7 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode
IrInstruction **incoming_values = allocate<IrInstruction *>(2);
incoming_values[0] = null_result;
incoming_values[1] = unwrapped_payload;
- IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
+ IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *");
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);
@@ -6044,7 +6428,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
IrInstruction **incoming_values = allocate<IrInstruction *>(2);
incoming_values[0] = then_expr_result;
incoming_values[1] = else_expr_result;
- IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
+ IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *");
incoming_blocks[0] = after_then_block;
incoming_blocks[1] = after_else_block;
@@ -7398,7 +7782,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
IrInstruction **incoming_values = allocate<IrInstruction *>(2);
incoming_values[0] = then_expr_result;
incoming_values[1] = else_expr_result;
- IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
+ IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *");
incoming_blocks[0] = after_then_block;
incoming_blocks[1] = after_else_block;
@@ -7495,7 +7879,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
IrInstruction **incoming_values = allocate<IrInstruction *>(2);
incoming_values[0] = then_expr_result;
incoming_values[1] = else_expr_result;
- IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
+ IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *");
incoming_blocks[0] = after_then_block;
incoming_blocks[1] = after_else_block;
@@ -8092,7 +8476,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
IrInstruction **incoming_values = allocate<IrInstruction *>(2);
incoming_values[0] = err_result;
incoming_values[1] = unwrapped_payload;
- IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
+ IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2, "IrBasicBlock *");
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);
@@ -8680,7 +9064,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;
+ IrExecutable *ir_executable = fn_entry->ir_executable;
AstNode *body_node = fn_entry->body_node;
assert(fn_entry->child_scope);
@@ -10224,6 +10608,14 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
return result;
}
+ if (wanted_type->id == ZigTypeIdInt && actual_type->id == ZigTypeIdInt) {
+ result.id = ConstCastResultIdIntShorten;
+ result.data.int_shorten = allocate_nonzero<ConstCastIntShorten>(1);
+ result.data.int_shorten->wanted_type = wanted_type;
+ result.data.int_shorten->actual_type = actual_type;
+ return result;
+ }
+
result.id = ConstCastResultIdType;
result.data.type_mismatch = allocate_nonzero<ConstCastTypeMismatch>(1);
result.data.type_mismatch->wanted_type = wanted_type;
@@ -11490,7 +11882,7 @@ ZigValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
if (expected_type != nullptr && type_is_invalid(expected_type))
return codegen->invalid_instruction->value;
- IrExecutable *ir_executable = allocate<IrExecutable>(1);
+ IrExecutable *ir_executable = allocate<IrExecutable>(1, "IrExecutablePass1");
ir_executable->source_node = source_node;
ir_executable->parent_exec = parent_exec;
ir_executable->name = exec_name;
@@ -11512,7 +11904,7 @@ ZigValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
ir_print(codegen, stderr, ir_executable, 2, IrPassSrc);
fprintf(stderr, "}\n");
}
- IrExecutable *analyzed_executable = allocate<IrExecutable>(1);
+ IrExecutable *analyzed_executable = allocate<IrExecutable>(1, "IrExecutablePass2");
analyzed_executable->source_node = source_node;
analyzed_executable->parent_exec = parent_exec;
analyzed_executable->source_exec = ir_executable;
@@ -12641,6 +13033,17 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
add_error_note(ira->codegen, parent_msg, source_node,
buf_sprintf("calling convention mismatch"));
break;
+ case ConstCastResultIdIntShorten: {
+ ZigType *wanted_type = cast_result->data.int_shorten->wanted_type;
+ ZigType *actual_type = cast_result->data.int_shorten->actual_type;
+ const char *wanted_signed = wanted_type->data.integral.is_signed ? "signed" : "unsigned";
+ const char *actual_signed = actual_type->data.integral.is_signed ? "signed" : "unsigned";
+ add_error_note(ira->codegen, parent_msg, source_node,
+ buf_sprintf("%s %" PRIu32 "-bit int cannot represent all possible %s %" PRIu32 "-bit values",
+ wanted_signed, wanted_type->data.integral.bit_count,
+ actual_signed, actual_type->data.integral.bit_count));
+ break;
+ }
case ConstCastResultIdFnAlign: // TODO
case ConstCastResultIdFnVarArgs: // TODO
case ConstCastResultIdFnReturnType: // TODO
@@ -15597,6 +16000,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
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, !is_comptime_var || var->gen_is_const);
+ 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);
@@ -15869,8 +16273,8 @@ static IrInstruction *ir_analyze_instruction_error_union(IrAnalyze *ira,
IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type);
result->value->special = ConstValSpecialLazy;
- LazyValueErrUnionType *lazy_err_union_type = allocate<LazyValueErrUnionType>(1);
- lazy_err_union_type->ira = ira;
+ LazyValueErrUnionType *lazy_err_union_type = allocate<LazyValueErrUnionType>(1, "LazyValueErrUnionType");
+ lazy_err_union_type->ira = ira; ira_ref(ira);
result->value->data.x_lazy = &lazy_err_union_type->base;
lazy_err_union_type->base.id = LazyValueIdErrUnionType;
@@ -17368,8 +17772,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
if (type_is_invalid(impl_fn->type_entry))
return ira->codegen->invalid_instruction;
- impl_fn->ir_executable.source_node = call_instruction->base.source_node;
- impl_fn->ir_executable.parent_exec = ira->new_irb.exec;
+ impl_fn->ir_executable->source_node = call_instruction->base.source_node;
+ impl_fn->ir_executable->parent_exec = ira->new_irb.exec;
impl_fn->analyzed_executable.source_node = call_instruction->base.source_node;
impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec;
impl_fn->analyzed_executable.backward_branch_quota = ira->new_irb.exec->backward_branch_quota;
@@ -17722,8 +18126,8 @@ static IrInstruction *ir_analyze_optional_type(IrAnalyze *ira, IrInstructionUnOp
IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type);
result->value->special = ConstValSpecialLazy;
- LazyValueOptType *lazy_opt_type = allocate<LazyValueOptType>(1);
- lazy_opt_type->ira = ira;
+ LazyValueOptType *lazy_opt_type = allocate<LazyValueOptType>(1, "LazyValueOptType");
+ lazy_opt_type->ira = ira; ira_ref(ira);
result->value->data.x_lazy = &lazy_opt_type->base;
lazy_opt_type->base.id = LazyValueIdOptType;
@@ -19668,8 +20072,8 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira,
IrInstruction *result = ir_const(ira, &slice_type_instruction->base, ira->codegen->builtin_types.entry_type);
result->value->special = ConstValSpecialLazy;
- LazyValueSliceType *lazy_slice_type = allocate<LazyValueSliceType>(1);
- lazy_slice_type->ira = ira;
+ LazyValueSliceType *lazy_slice_type = allocate<LazyValueSliceType>(1, "LazyValueSliceType");
+ lazy_slice_type->ira = ira; ira_ref(ira);
result->value->data.x_lazy = &lazy_slice_type->base;
lazy_slice_type->base.id = LazyValueIdSliceType;
@@ -19828,8 +20232,8 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstructi
IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int);
result->value->special = ConstValSpecialLazy;
- LazyValueSizeOf *lazy_size_of = allocate<LazyValueSizeOf>(1);
- lazy_size_of->ira = ira;
+ LazyValueSizeOf *lazy_size_of = allocate<LazyValueSizeOf>(1, "LazyValueSizeOf");
+ lazy_size_of->ira = ira; ira_ref(ira);
result->value->data.x_lazy = &lazy_size_of->base;
lazy_size_of->base.id = LazyValueIdSizeOf;
@@ -24556,8 +24960,8 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct
IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int);
result->value->special = ConstValSpecialLazy;
- LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1);
- lazy_align_of->ira = ira;
+ LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1, "LazyValueAlignOf");
+ lazy_align_of->ira = ira; ira_ref(ira);
result->value->data.x_lazy = &lazy_align_of->base;
lazy_align_of->base.id = LazyValueIdAlignOf;
@@ -25040,8 +25444,8 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct
IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type);
result->value->special = ConstValSpecialLazy;
- LazyValueFnType *lazy_fn_type = allocate<LazyValueFnType>(1);
- lazy_fn_type->ira = ira;
+ LazyValueFnType *lazy_fn_type = allocate<LazyValueFnType>(1, "LazyValueFnType");
+ lazy_fn_type->ira = ira; ira_ref(ira);
result->value->data.x_lazy = &lazy_fn_type->base;
lazy_fn_type->base.id = LazyValueIdFnType;
@@ -26081,8 +26485,8 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct
IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type);
result->value->special = ConstValSpecialLazy;
- LazyValuePtrType *lazy_ptr_type = allocate<LazyValuePtrType>(1);
- lazy_ptr_type->ira = ira;
+ LazyValuePtrType *lazy_ptr_type = allocate<LazyValuePtrType>(1, "LazyValuePtrType");
+ lazy_ptr_type->ira = ira; ira_ref(ira);
result->value->data.x_lazy = &lazy_ptr_type->base;
lazy_ptr_type->base.id = LazyValueIdPtrType;
@@ -27551,7 +27955,8 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
assert(old_exec->first_err_trace_msg == nullptr);
assert(expected_type == nullptr || !type_is_invalid(expected_type));
- IrAnalyze *ira = allocate<IrAnalyze>(1);
+ IrAnalyze *ira = allocate<IrAnalyze>(1, "IrAnalyze");
+ ira->ref_count = 1;
old_exec->analysis = ira;
ira->codegen = codegen;
@@ -27618,6 +28023,7 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
ira->instruction_index += 1;
}
+ ZigType *res_type;
if (new_exec->first_err_trace_msg != nullptr) {
codegen->trace_err = new_exec->first_err_trace_msg;
if (codegen->trace_err != nullptr && new_exec->source_node != nullptr &&
@@ -27627,13 +28033,18 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
codegen->trace_err = add_error_note(codegen, codegen->trace_err,
new_exec->source_node, buf_create_from_str("referenced here"));
}
- return ira->codegen->builtin_types.entry_invalid;
+ res_type = ira->codegen->builtin_types.entry_invalid;
} else if (ira->src_implicit_return_type_list.length == 0) {
- return codegen->builtin_types.entry_unreachable;
+ res_type = codegen->builtin_types.entry_unreachable;
} else {
- return ir_resolve_peer_types(ira, expected_type_source_node, expected_type, ira->src_implicit_return_type_list.items,
+ res_type = ir_resolve_peer_types(ira, expected_type_source_node, expected_type, ira->src_implicit_return_type_list.items,
ira->src_implicit_return_type_list.length);
}
+
+ // It is now safe to free Pass 1 IR instructions.
+ ira_deref(ira);
+
+ return res_type;
}
bool ir_has_side_effects(IrInstruction *instruction) {
@@ -27969,6 +28380,8 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
val->special = ConstValSpecialStatic;
assert(val->type->id == ZigTypeIdComptimeInt || val->type->id == ZigTypeIdInt);
bigint_init_unsigned(&val->data.x_bigint, align_in_bytes);
+
+ // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
return ErrorNone;
}
case LazyValueIdSizeOf: {
@@ -28024,6 +28437,8 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
val->special = ConstValSpecialStatic;
assert(val->type->id == ZigTypeIdComptimeInt || val->type->id == ZigTypeIdInt);
bigint_init_unsigned(&val->data.x_bigint, abi_size);
+
+ // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
return ErrorNone;
}
case LazyValueIdSliceType: {
@@ -28102,6 +28517,8 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
val->special = ConstValSpecialStatic;
assert(val->type->id == ZigTypeIdMetaType);
val->data.x_type = get_slice_type(ira->codegen, slice_ptr_type);
+
+ // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
return ErrorNone;
}
case LazyValueIdPtrType: {
@@ -28173,6 +28590,8 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
lazy_ptr_type->bit_offset_in_host, lazy_ptr_type->host_int_bytes,
allow_zero, VECTOR_INDEX_NONE, nullptr, sentinel_val);
val->special = ConstValSpecialStatic;
+
+ // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
return ErrorNone;
}
case LazyValueIdOptType: {
@@ -28195,16 +28614,21 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
assert(val->type->id == ZigTypeIdMetaType);
val->data.x_type = get_optional_type(ira->codegen, payload_type);
val->special = ConstValSpecialStatic;
+
+ // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
return ErrorNone;
}
case LazyValueIdFnType: {
LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(val->data.x_lazy);
- ZigType *fn_type = ir_resolve_lazy_fn_type(lazy_fn_type->ira, source_node, lazy_fn_type);
+ IrAnalyze *ira = lazy_fn_type->ira;
+ ZigType *fn_type = ir_resolve_lazy_fn_type(ira, source_node, lazy_fn_type);
if (fn_type == nullptr)
return ErrorSemanticAnalyzeFail;
val->special = ConstValSpecialStatic;
assert(val->type->id == ZigTypeIdMetaType);
val->data.x_type = fn_type;
+
+ // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
return ErrorNone;
}
case LazyValueIdErrUnionType: {
@@ -28233,6 +28657,8 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
assert(val->type->id == ZigTypeIdMetaType);
val->data.x_type = get_error_union_type(ira->codegen, err_set_type, payload_type);
val->special = ConstValSpecialStatic;
+
+ // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
return ErrorNone;
}
}