From 1806cb923bb319ebc18559e1bffa87990525d6a4 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 28 Jul 2022 15:25:41 -0400 Subject: [PATCH] Handle invalidated inlining requests, comptime alias rebuilds --- IDEHelper/Compiler/BfContext.cpp | 103 ++++++++++++++------- IDEHelper/Compiler/BfContext.h | 10 +- IDEHelper/Compiler/BfModule.cpp | 6 +- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 4 +- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 11 +++ 5 files changed, 93 insertions(+), 41 deletions(-) diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index e26403c3..85068be0 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -577,7 +577,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) wantProcessMethod = false; else if (workItem->mType->IsDeleting()) wantProcessMethod = false; - if (!IsWorkItemValid(workItem)) + else if (!IsWorkItemValid(workItem)) wantProcessMethod = false; if (methodInstance != NULL) BF_ASSERT(methodInstance->mMethodProcessRequest == workItem); @@ -771,38 +771,41 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods) } auto workItem = *workItemRef; - auto owner = workItem.mMethodInstance->mMethodInstanceGroup->mOwner; auto module = workItem.mFromModule; auto methodInstance = workItem.mMethodInstance; - BF_ASSERT(module->mIsModuleMutable); - module->PrepareForIRWriting(methodInstance->GetOwner()); + bool wantProcessMethod = methodInstance != NULL; + if ((workItem.mFromModuleRebuildIdx != -1) && (workItem.mFromModuleRebuildIdx != module->mRebuildIdx)) + wantProcessMethod = false; + else if (workItem.mType->IsDeleting()) + wantProcessMethod = false; + else if (!IsWorkItemValid(&workItem)) + wantProcessMethod = false; workIdx = mInlineMethodWorkList.RemoveAt(workIdx); - BfLogSysM("Module %p inlining method %p into func:%p\n", module, methodInstance, workItem.mFunc); - - BfMethodInstance dupMethodInstance; - dupMethodInstance.CopyFrom(methodInstance); - dupMethodInstance.mIRFunction = workItem.mFunc; - dupMethodInstance.mIsReified = true; - dupMethodInstance.mInCEMachine = false; // Only have the original one - BF_ASSERT(module->mIsReified); // We should only bother inlining in reified modules - - bool wantProcessMethod = true; - if (owner->IsDeleting()) - wantProcessMethod = false; + BfLogSysM("Module %p inlining method %p into func:%p wantProcessMethod:%d\n", module, methodInstance, workItem.mFunc, wantProcessMethod); if (wantProcessMethod) { + BF_ASSERT(module->mIsModuleMutable); + module->PrepareForIRWriting(methodInstance->GetOwner()); + + BfMethodInstance dupMethodInstance; + dupMethodInstance.CopyFrom(methodInstance); + dupMethodInstance.mIRFunction = workItem.mFunc; + dupMethodInstance.mIsReified = true; + dupMethodInstance.mInCEMachine = false; // Only have the original one + BF_ASSERT(module->mIsReified); // We should only bother inlining in reified modules + // These errors SHOULD be duplicates, but if we have no other errors at all then we don't ignoreErrors, which // may help unveil some kinds of compiler bugs SetAndRestoreValue prevIgnoreErrors(module->mIgnoreErrors, mCompiler->mPassInstance->HasFailed()); module->ProcessMethod(&dupMethodInstance, true); - } - static int sMethodIdx = 0; - module->mBfIRBuilder->Func_SetLinkage(workItem.mFunc, BfIRLinkageType_Internal); + static int sMethodIdx = 0; + module->mBfIRBuilder->Func_SetLinkage(workItem.mFunc, BfIRLinkageType_Internal); + } BF_ASSERT(module->mContext == this); BF_ASSERT(module->mIsModuleMutable); @@ -1949,7 +1952,9 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds) } if ((deferDepRebuilds) && (dependentTypeInst != NULL)) - mFailTypes.Add(dependentTypeInst); + { + mFailTypes.TryAdd(dependentTypeInst, BfFailKind_Normal); + } else { rebuildTypeQueue.Add(dependentType); @@ -2359,14 +2364,18 @@ void BfContext::UpdateRevisedTypes() RebuildType(typeInst); } - for (auto typeInst : failTypes) + for (auto failKV : failTypes) { + auto typeInst = failKV.mKey; if (!typeInst->IsDeleting()) { if (!typeInst->mTypeDef->mProject->mDisabled) { - BfLogSysM("Rebuilding failed type %p\n", typeInst); - RebuildType(typeInst); + BfLogSysM("Rebuilding failed type %p %d\n", typeInst, (int)failKV.mValue); + if (failKV.mValue == BfFailKind_Deep) + TypeDataChanged(typeInst, true); + else + RebuildType(typeInst); } } } @@ -3041,27 +3050,49 @@ bool BfContext::IsWorkItemValid(BfWorkListEntry* item) return true; } +bool BfContext::IsWorkItemValid(BfMethodInstance* methodInstance) +{ + if (methodInstance == NULL) + return false; + + for (auto& param : methodInstance->mParams) + { + if (param.mResolvedType->IsDeleting()) + return false; + } + + if (methodInstance->mMethodInfoEx != NULL) + { + for (auto genericArg : methodInstance->mMethodInfoEx->mMethodGenericArguments) + if (genericArg->IsDeleting()) + return false; + } + + return true; +} + bool BfContext::IsWorkItemValid(BfMethodProcessRequest* item) { // If we had mid-compile rebuilds then we may have deleted types referenced in methods if (mCompiler->mStats.mMidCompileRebuilds == 0) return true; - if (item->mMethodInstance == NULL) + if (!IsWorkItemValid(item->mMethodInstance)) return false; - for (auto& param : item->mMethodInstance->mParams) - { - if (param.mResolvedType->IsDeleting()) - return false; - } + return true; +} - if (item->mMethodInstance->mMethodInfoEx != NULL) - { - for (auto genericArg : item->mMethodInstance->mMethodInfoEx->mMethodGenericArguments) - if (genericArg->IsDeleting()) - return false; - } +bool BfContext::IsWorkItemValid(BfInlineMethodRequest* item) +{ + if (mCompiler->mStats.mMidCompileRebuilds == 0) + return true; + + if (!IsWorkItemValid(item->mMethodInstance)) + return false; + + if (item->mMethodInstance->GetOwner()->IsDeleting()) + return false; return true; } @@ -3130,7 +3161,7 @@ void BfContext::RemoveInvalidFailTypes() { for (auto itr = mFailTypes.begin(); itr != mFailTypes.end(); ) { - auto typeInst = *itr; + auto typeInst = itr->mKey; BfLogSysM("Checking FailType: %p\n", typeInst); if ((typeInst->IsDeleting()) || (typeInst->mRebuildFlags & BfTypeRebuildFlag_Deleted)) { diff --git a/IDEHelper/Compiler/BfContext.h b/IDEHelper/Compiler/BfContext.h index d3c8e42f..44d883ee 100644 --- a/IDEHelper/Compiler/BfContext.h +++ b/IDEHelper/Compiler/BfContext.h @@ -355,6 +355,12 @@ public: } }; +enum BfFailKind +{ + BfFailKind_Normal, + BfFailKind_Deep +}; + class BfContext { public: @@ -379,7 +385,7 @@ public: Dictionary mProjectModule; Array mModules; Array mDeletingModules; - HashSet mFailTypes; // All types handled after a failure need to be rebuild on subsequent compile + Dictionary mFailTypes; // All types handled after a failure need to be rebuild on subsequent compile HashSet mReferencedIFaceSlots; BfMethodInstance* mValueTypeDeinitSentinel; @@ -478,7 +484,9 @@ public: void MarkAsReferenced(BfDependedType* depType); void RemoveInvalidFailTypes(); bool IsWorkItemValid(BfWorkListEntry* item); + bool IsWorkItemValid(BfMethodInstance* methodInstance); bool IsWorkItemValid(BfMethodProcessRequest* item); + bool IsWorkItemValid(BfInlineMethodRequest* item); bool IsWorkItemValid(BfMethodSpecializationRequest* item); void RemoveInvalidWorkItems(); BfType* FindTypeById(int typeId); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index bb3e8519..46cf79c1 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -4007,7 +4007,7 @@ void BfModule::AddFailType(BfTypeInstance* typeInstance) if ((typeInstance->mRebuildFlags & BfTypeRebuildFlag_InFailTypes) != 0) return; typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags | BfTypeRebuildFlag_InFailTypes); - mContext->mFailTypes.Add(typeInstance); + mContext->mFailTypes.TryAdd(typeInstance, BfFailKind_Normal); } void BfModule::DeferRebuildType(BfTypeInstance* typeInstance) @@ -13632,6 +13632,7 @@ BfModuleMethodInstance BfModule::ReferenceExternalMethodInstance(BfMethodInstanc inlineMethodRequest->mFromModule = this; inlineMethodRequest->mFunc = func; inlineMethodRequest->mFromModuleRevision = mRevision; + inlineMethodRequest->mFromModuleRebuildIdx = mRebuildIdx; inlineMethodRequest->mMethodInstance = methodInstance; BF_ASSERT(mIsModuleMutable); @@ -14362,6 +14363,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM inlineMethodRequest->mFromModule = this; inlineMethodRequest->mFunc = methodInstance->mIRFunction; inlineMethodRequest->mFromModuleRevision = mRevision; + inlineMethodRequest->mFromModuleRebuildIdx = mRebuildIdx; inlineMethodRequest->mMethodInstance = methodInstance; BfLogSysM("mInlineMethodWorkList %p for method %p in module %p in GetMethodInstance\n", inlineMethodRequest, methodInstance, this); @@ -23761,7 +23763,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool { auto boxedType = (BfBoxedType*)mCurTypeInstance; // If we failed a lookup here then we better have also failed it in the original type - BF_ASSERT(boxedType->mElementType->ToTypeInstance()->mModule->mHadBuildError || mContext->mFailTypes.Contains(boxedType->mElementType->ToTypeInstance())); + BF_ASSERT(boxedType->mElementType->ToTypeInstance()->mModule->mHadBuildError || mContext->mFailTypes.ContainsKey(boxedType->mElementType->ToTypeInstance())); } } diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 18a09f5b..19222aa2 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -1034,7 +1034,7 @@ void BfModule::TypeFailed(BfTypeInstance* typeInstance) typeInstance->mAlign = 1; if (typeInstance->mSize == -1) typeInstance->mSize = 1; - mContext->mFailTypes.Add(typeInstance); + mContext->mFailTypes.TryAdd(typeInstance, BfFailKind_Normal); mHadBuildError = true; } @@ -3338,7 +3338,7 @@ void BfModule::DoPopulateType_TypeAlias(BfTypeAliasType* typeAlias) AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom); } else - mContext->mFailTypes.Add(typeAlias); + mContext->mFailTypes.TryAdd(typeAlias, BfFailKind_Normal); if (typeAlias->mTypeFailed) aliasToType = NULL; diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 61bbdbf8..2c2b15e3 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -3982,6 +3982,17 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa { ctx->mHadVar = true; cachedResolvedType = ctx->mModule->GetPrimitiveType(BfTypeCode_Var); + + auto typeState = ctx->mModule->mContext->mCurTypeState; + if ((typeState != NULL) && (typeState->mType != NULL) && (typeState->mType->IsTypeInstance())) + { + auto typeInst = typeState->mType->ToTypeInstance(); + if (typeInst->mDefineState == BfTypeDefineState_ResolvingBaseType) + { + // Make sure we regenerate this type + ctx->mModule->mContext->mFailTypes.TryAdd(typeState->mType->ToTypeInstance(), BfFailKind_Deep); + } + } } else if (BfIRConstHolder::IsInt(constant->mTypeCode)) {