diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 1e3a7fe0..e0bb4e90 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -7072,7 +7072,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) { if (!module->mIsSpecialModule) { - if ((module->mIsReified) && (module->mIsModuleMutable)) + if ((module->HasCompiledOutput()) && (module->mIsModuleMutable)) { module->Finish(); } diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index 412c29e1..2e9dfc4b 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -61,12 +61,14 @@ BfContext::BfContext(BfCompiler* compiler) : mScratchModule->mIsSpecialModule = true; mScratchModule->mIsScratchModule = true; mScratchModule->mIsReified = true; + mScratchModule->mGeneratesCode = false; mScratchModule->Init(); mUnreifiedModule = new BfModule(this, ""); mUnreifiedModule->mIsSpecialModule = true; mUnreifiedModule->mIsScratchModule = true; mUnreifiedModule->mIsReified = false; + mUnreifiedModule->mGeneratesCode = false; mUnreifiedModule->Init(); mValueTypeDeinitSentinel = (BfMethodInstance*)1; @@ -158,7 +160,7 @@ void BfContext::AssignModule(BfType* type) // We used to have this "IsReified" check, but we DO want to create modules for unreified types even if they remain unused. // What was that IsReified check catching? // It screwed up the reification of generic types- they just got switched to mScratchModule from mUnreifiedModule, but didn't ever generate code. - if (/*(!type->IsReified()) ||*/ (type->IsUnspecializedType()) || (type->IsInterface()) || (type->IsVar()) || (type->IsTypeAlias()) || (type->IsFunction())) + if (/*(!type->IsReified()) ||*/ (type->IsUnspecializedType()) || (type->IsVar()) || (type->IsTypeAlias()) || (type->IsFunction())) { if (typeInst->mIsReified) module = mScratchModule; @@ -203,7 +205,7 @@ void BfContext::AssignModule(BfType* type) { String moduleName = GenerateModuleName(typeInst); module = new BfModule(this, moduleName); - module->mIsReified = typeInst->mIsReified; + module->mIsReified = typeInst->mIsReified; module->mProject = project; typeInst->mModule = module; BF_ASSERT(!mLockModules); @@ -221,6 +223,8 @@ void BfContext::AssignModule(BfType* type) module->mOwnedTypeInstances.push_back(localTypeInst); } + module->CalcGeneratesCode(); + if (needsModuleInit) module->Init(); } diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 508acdaf..ddba0956 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -829,7 +829,7 @@ BfModule* gLastCreatedModule = NULL; BfModule::BfModule(BfContext* context, const StringImpl& moduleName) { BfLogSys(context->mSystem, "BfModule::BFModule %p %s\n", this, moduleName.c_str()); - + gLastCreatedModule = this; mContext = context; @@ -847,6 +847,7 @@ BfModule::BfModule(BfContext* context, const StringImpl& moduleName) mUsedSlotCount = -1; mIsReified = true; + mGeneratesCode = true; mReifyQueued = false; mIsSpecialModule = false; mIsComptimeModule = false; @@ -1048,6 +1049,20 @@ void BfModule::FinishInit() mAwaitingInitFinish = false; } +void BfModule::CalcGeneratesCode() +{ + if ((!mIsReified) || (mIsScratchModule)) + { + mGeneratesCode = false; + return; + } + + mGeneratesCode = false; + for (auto typeInst : mOwnedTypeInstances) + if (!typeInst->IsInterface()) + mGeneratesCode = true; +} + void BfModule::ReifyModule() { BF_ASSERT((mCompiler->mCompileState != BfCompiler::CompileState_Unreified) && (mCompiler->mCompileState != BfCompiler::CompileState_VData)); @@ -1055,9 +1070,10 @@ void BfModule::ReifyModule() BfLogSysM("ReifyModule %@ %s\n", this, mModuleName.c_str()); BF_ASSERT((this != mContext->mScratchModule) && (this != mContext->mUnreifiedModule)); mIsReified = true; + CalcGeneratesCode(); mReifyQueued = false; StartNewRevision(RebuildKind_SkipOnDemandTypes, true); - mCompiler->mStats.mModulesReified++; + mCompiler->mStats.mModulesReified++; } void BfModule::UnreifyModule() @@ -1065,6 +1081,7 @@ void BfModule::UnreifyModule() BfLogSysM("UnreifyModule %p %s\n", this, mModuleName.c_str()); BF_ASSERT((this != mContext->mScratchModule) && (this != mContext->mUnreifiedModule)); mIsReified = false; + CalcGeneratesCode(); mReifyQueued = false; StartNewRevision(RebuildKind_None, true); mCompiler->mStats.mModulesUnreified++; @@ -1126,8 +1143,8 @@ void BfModule::SetupIRBuilder(bool dbgVerifyCodeGen) // The only purpose of not ignoring writes is so we can verify the codegen one instruction at a time mBfIRBuilder->mDbgVerifyCodeGen = true; } - } - else if (!mIsReified) + } + else if (!mGeneratesCode) { mBfIRBuilder->mIgnoreWrites = true; } @@ -9475,10 +9492,10 @@ bool BfModule::WantsLifetimes() bool BfModule::HasCompiledOutput() { - return (!mSystem->mIsResolveOnly) && (mIsReified) && (!mIsComptimeModule); + return (!mSystem->mIsResolveOnly) && (mGeneratesCode) && (!mIsComptimeModule); } -// We will skip the object access check for any occurances of this value +// We will skip the object access check for any occurrences of this value void BfModule::SkipObjectAccessCheck(BfTypedValue typedVal) { if ((mBfIRBuilder->mIgnoreWrites) || (!typedVal.mType->IsObjectOrInterface()) || (mCurMethodState == NULL) || (mCurMethodState->mIgnoreObjectAccessCheck)) @@ -13107,9 +13124,9 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM { MarkDerivedDirty(typeInst); - if (mIsScratchModule) + if (!HasCompiledOutput()) { - BfLogSysM("Marking scratch module method instance as reified: %p\n", methodInstance); + BfLogSysM("Marking non-compiled-output module method instance as reified: %p\n", methodInstance); _SetReified(); CheckHotMethod(methodInstance, ""); } @@ -23923,14 +23940,16 @@ bool BfModule::Finish() if (mUsedSlotCount != -1) { BF_ASSERT(mCompiler->mMaxInterfaceSlots != -1); - mUsedSlotCount = mCompiler->mMaxInterfaceSlots; + mUsedSlotCount = mCompiler->mMaxInterfaceSlots; } + if ((!mGeneratesCode) && (!mAddedToCount)) + return true; + BF_ASSERT(mAddedToCount); mAddedToCount = false; mAwaitingFinish = false; - mCompiler->mStats.mModulesFinished++; if (HasCompiledOutput()) @@ -24053,13 +24072,13 @@ bool BfModule::Finish() if ((writeModule) && (!mBfIRBuilder->mIgnoreWrites)) mCompiler->mCodeGen.WriteObjectFile(this, outputPath, codeGenOptions); mLastModuleWrittenRevision = mCompiler->mRevision; - } + } else { for (auto type : mOwnedTypeInstances) { BF_ASSERT((!type->IsIncomplete()) || (type->IsSpecializedByAutoCompleteMethod())); - } + } } for (auto& specModulePair : mSpecializedMethodModules) @@ -24129,8 +24148,7 @@ void BfModule::ClearModuleData(bool clearTransientData) mAddedToCount = false; } - mDICompileUnit = BfIRMDNode(); - mIsModuleMutable = false; + mDICompileUnit = BfIRMDNode(); if (clearTransientData) mIncompleteMethodCount = 0; mHasGenericMethods = false; @@ -24165,7 +24183,8 @@ void BfModule::ClearModuleData(bool clearTransientData) if (mNextAltModule != NULL) mNextAltModule->ClearModuleData(); - BfLogSysM("ClearModuleData. Deleting IRBuilder: %p\n", mBfIRBuilder); + BfLogSysM("ClearModuleData. Deleting IRBuilder: %p\n", mBfIRBuilder); + mIsModuleMutable = false; delete mBfIRBuilder; mBfIRBuilder = NULL; mWantsIRIgnoreWrites = false; diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 1728f3ef..d7fda7e1 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1476,6 +1476,7 @@ public: bool mAddedToCount; bool mHasForceLinkMarker; bool mIsReified; + bool mGeneratesCode; bool mReifyQueued; bool mWantsIRIgnoreWrites; bool mHasGenericMethods; @@ -1947,6 +1948,7 @@ public: void Init(bool isFullRebuild = true); bool WantsFinishModule(); void FinishInit(); + void CalcGeneratesCode(); void ReifyModule(); void UnreifyModule(); void Cleanup(); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 38d9c2a6..103e870c 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -1038,6 +1038,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType { BfLogSysM("Setting reified type %p in module %p in PopulateType on module awaiting finish\n", resolvedTypeRef, typeModule); typeModule->mIsReified = true; + typeModule->CalcGeneratesCode(); typeModule->mWantsIRIgnoreWrites = false; for (auto ownedTypes : typeModule->mOwnedTypeInstances) { @@ -6049,7 +6050,15 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance) methodProcessRequest->mFromModule = this; if ((!mCompiler->mIsResolveOnly) && (methodInstance->mIsReified)) + { + if ((!mIsModuleMutable) && (!mIsScratchModule)) + { + BF_ASSERT(!mGeneratesCode); + StartNewRevision(BfModule::RebuildKind_None); + } + BF_ASSERT(mIsModuleMutable || mReifyQueued); + } BF_ASSERT(mBfIRBuilder != NULL);