Bläddra i källkod

Handle invalidated inlining requests, comptime alias rebuilds

Brian Fiete 3 år sedan
förälder
incheckning
1806cb923b

+ 64 - 33
IDEHelper/Compiler/BfContext.cpp

@@ -577,7 +577,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods)
 				wantProcessMethod = false;
 				wantProcessMethod = false;
 			else if (workItem->mType->IsDeleting())
 			else if (workItem->mType->IsDeleting())
 				wantProcessMethod = false;
 				wantProcessMethod = false;
-			if (!IsWorkItemValid(workItem))
+			else if (!IsWorkItemValid(workItem))
 				wantProcessMethod = false;
 				wantProcessMethod = false;
 			if (methodInstance != NULL)
 			if (methodInstance != NULL)
 				BF_ASSERT(methodInstance->mMethodProcessRequest == workItem);
 				BF_ASSERT(methodInstance->mMethodProcessRequest == workItem);
@@ -771,38 +771,41 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods)
 			}
 			}
 
 
 			auto workItem = *workItemRef;
 			auto workItem = *workItemRef;
-			auto owner = workItem.mMethodInstance->mMethodInstanceGroup->mOwner;
 			auto module = workItem.mFromModule;
 			auto module = workItem.mFromModule;
 			auto methodInstance = workItem.mMethodInstance;
 			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);
 			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)
 			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
 				// 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
 				//  may help unveil some kinds of compiler bugs
 				SetAndRestoreValue<bool> prevIgnoreErrors(module->mIgnoreErrors, mCompiler->mPassInstance->HasFailed());
 				SetAndRestoreValue<bool> prevIgnoreErrors(module->mIgnoreErrors, mCompiler->mPassInstance->HasFailed());
 				module->ProcessMethod(&dupMethodInstance, true);
 				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->mContext == this);
 			BF_ASSERT(module->mIsModuleMutable);
 			BF_ASSERT(module->mIsModuleMutable);
@@ -1949,7 +1952,9 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds)
 			}
 			}
 
 
 			if ((deferDepRebuilds) && (dependentTypeInst != NULL))
 			if ((deferDepRebuilds) && (dependentTypeInst != NULL))
-				mFailTypes.Add(dependentTypeInst);
+			{
+				mFailTypes.TryAdd(dependentTypeInst, BfFailKind_Normal);
+			}
 			else
 			else
 			{
 			{
 				rebuildTypeQueue.Add(dependentType);
 				rebuildTypeQueue.Add(dependentType);
@@ -2359,14 +2364,18 @@ void BfContext::UpdateRevisedTypes()
 		RebuildType(typeInst);
 		RebuildType(typeInst);
 	}
 	}
 
 
-	for (auto typeInst : failTypes)
+	for (auto failKV : failTypes)
 	{
 	{
+		auto typeInst = failKV.mKey;
 		if (!typeInst->IsDeleting())
 		if (!typeInst->IsDeleting())
 		{
 		{
 			if (!typeInst->mTypeDef->mProject->mDisabled)
 			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,24 +3050,20 @@ bool BfContext::IsWorkItemValid(BfWorkListEntry* item)
 	return true;
 	return true;
 }
 }
 
 
-bool BfContext::IsWorkItemValid(BfMethodProcessRequest* item)
+bool BfContext::IsWorkItemValid(BfMethodInstance* methodInstance)
 {
 {
-	// 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 (methodInstance == NULL)
 		return false;
 		return false;
 
 
-	for (auto& param : item->mMethodInstance->mParams)
+	for (auto& param : methodInstance->mParams)
 	{
 	{
 		if (param.mResolvedType->IsDeleting())
 		if (param.mResolvedType->IsDeleting())
 			return false;
 			return false;
 	}
 	}
 
 
-	if (item->mMethodInstance->mMethodInfoEx != NULL)
+	if (methodInstance->mMethodInfoEx != NULL)
 	{
 	{
-		for (auto genericArg : item->mMethodInstance->mMethodInfoEx->mMethodGenericArguments)
+		for (auto genericArg : methodInstance->mMethodInfoEx->mMethodGenericArguments)
 			if (genericArg->IsDeleting())
 			if (genericArg->IsDeleting())
 				return false;
 				return false;
 	}
 	}
@@ -3066,6 +3071,32 @@ bool BfContext::IsWorkItemValid(BfMethodProcessRequest* item)
 	return true;
 	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 (!IsWorkItemValid(item->mMethodInstance))
+		return false;
+
+	return true;
+}
+
+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;
+}
+
 bool BfContext::IsWorkItemValid(BfMethodSpecializationRequest* item)
 bool BfContext::IsWorkItemValid(BfMethodSpecializationRequest* item)
 {
 {
 	// If we had mid-compile rebuilds then we may have deleted types referenced in methods
 	// If we had mid-compile rebuilds then we may have deleted types referenced in methods
@@ -3130,7 +3161,7 @@ void BfContext::RemoveInvalidFailTypes()
 {
 {
 	for (auto itr = mFailTypes.begin(); itr != mFailTypes.end(); )
 	for (auto itr = mFailTypes.begin(); itr != mFailTypes.end(); )
 	{
 	{
-		auto typeInst = *itr;
+		auto typeInst = itr->mKey;
 		BfLogSysM("Checking FailType: %p\n", typeInst);
 		BfLogSysM("Checking FailType: %p\n", typeInst);
 		if ((typeInst->IsDeleting()) || (typeInst->mRebuildFlags & BfTypeRebuildFlag_Deleted))
 		if ((typeInst->IsDeleting()) || (typeInst->mRebuildFlags & BfTypeRebuildFlag_Deleted))
 		{
 		{

+ 9 - 1
IDEHelper/Compiler/BfContext.h

@@ -355,6 +355,12 @@ public:
 	}
 	}
 };
 };
 
 
+enum BfFailKind
+{
+	BfFailKind_Normal,
+	BfFailKind_Deep
+};
+
 class BfContext
 class BfContext
 {
 {
 public:
 public:
@@ -379,7 +385,7 @@ public:
 	Dictionary<BfProject*, BfModule*> mProjectModule;
 	Dictionary<BfProject*, BfModule*> mProjectModule;
 	Array<BfModule*> mModules;
 	Array<BfModule*> mModules;
 	Array<BfModule*> mDeletingModules;
 	Array<BfModule*> mDeletingModules;
-	HashSet<BfTypeInstance*> mFailTypes; // All types handled after a failure need to be rebuild on subsequent compile
+	Dictionary<BfTypeInstance*, BfFailKind> mFailTypes; // All types handled after a failure need to be rebuild on subsequent compile
 	HashSet<BfTypeInstance*> mReferencedIFaceSlots;
 	HashSet<BfTypeInstance*> mReferencedIFaceSlots;
 
 
 	BfMethodInstance* mValueTypeDeinitSentinel;
 	BfMethodInstance* mValueTypeDeinitSentinel;
@@ -478,7 +484,9 @@ public:
 	void MarkAsReferenced(BfDependedType* depType);
 	void MarkAsReferenced(BfDependedType* depType);
 	void RemoveInvalidFailTypes();
 	void RemoveInvalidFailTypes();
 	bool IsWorkItemValid(BfWorkListEntry* item);
 	bool IsWorkItemValid(BfWorkListEntry* item);
+	bool IsWorkItemValid(BfMethodInstance* methodInstance);
 	bool IsWorkItemValid(BfMethodProcessRequest* item);
 	bool IsWorkItemValid(BfMethodProcessRequest* item);
+	bool IsWorkItemValid(BfInlineMethodRequest* item);
 	bool IsWorkItemValid(BfMethodSpecializationRequest* item);
 	bool IsWorkItemValid(BfMethodSpecializationRequest* item);
 	void RemoveInvalidWorkItems();
 	void RemoveInvalidWorkItems();
 	BfType* FindTypeById(int typeId);
 	BfType* FindTypeById(int typeId);

+ 4 - 2
IDEHelper/Compiler/BfModule.cpp

@@ -4007,7 +4007,7 @@ void BfModule::AddFailType(BfTypeInstance* typeInstance)
 	if ((typeInstance->mRebuildFlags & BfTypeRebuildFlag_InFailTypes) != 0)
 	if ((typeInstance->mRebuildFlags & BfTypeRebuildFlag_InFailTypes) != 0)
 		return;
 		return;
 	typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags | BfTypeRebuildFlag_InFailTypes);
 	typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags | BfTypeRebuildFlag_InFailTypes);
-	mContext->mFailTypes.Add(typeInstance);
+	mContext->mFailTypes.TryAdd(typeInstance, BfFailKind_Normal);
 }
 }
 
 
 void BfModule::DeferRebuildType(BfTypeInstance* typeInstance)
 void BfModule::DeferRebuildType(BfTypeInstance* typeInstance)
@@ -13632,6 +13632,7 @@ BfModuleMethodInstance BfModule::ReferenceExternalMethodInstance(BfMethodInstanc
 			inlineMethodRequest->mFromModule = this;
 			inlineMethodRequest->mFromModule = this;
 			inlineMethodRequest->mFunc = func;
 			inlineMethodRequest->mFunc = func;
 			inlineMethodRequest->mFromModuleRevision = mRevision;
 			inlineMethodRequest->mFromModuleRevision = mRevision;
+			inlineMethodRequest->mFromModuleRebuildIdx = mRebuildIdx;
 			inlineMethodRequest->mMethodInstance = methodInstance;
 			inlineMethodRequest->mMethodInstance = methodInstance;
 			BF_ASSERT(mIsModuleMutable);
 			BF_ASSERT(mIsModuleMutable);
 
 
@@ -14362,6 +14363,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
 					inlineMethodRequest->mFromModule = this;
 					inlineMethodRequest->mFromModule = this;
 					inlineMethodRequest->mFunc = methodInstance->mIRFunction;
 					inlineMethodRequest->mFunc = methodInstance->mIRFunction;
 					inlineMethodRequest->mFromModuleRevision = mRevision;
 					inlineMethodRequest->mFromModuleRevision = mRevision;
+					inlineMethodRequest->mFromModuleRebuildIdx = mRebuildIdx;
 					inlineMethodRequest->mMethodInstance = methodInstance;
 					inlineMethodRequest->mMethodInstance = methodInstance;
 
 
 					BfLogSysM("mInlineMethodWorkList %p for method %p in module %p in GetMethodInstance\n", inlineMethodRequest, methodInstance, this);
 					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;
 				auto boxedType = (BfBoxedType*)mCurTypeInstance;
 				// If we failed a lookup here then we better have also failed it in the original type
 				// 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()));
 			}
 			}
 		}
 		}
 
 

+ 2 - 2
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -1034,7 +1034,7 @@ void BfModule::TypeFailed(BfTypeInstance* typeInstance)
 		typeInstance->mAlign = 1;
 		typeInstance->mAlign = 1;
 	if (typeInstance->mSize == -1)
 	if (typeInstance->mSize == -1)
 		typeInstance->mSize = 1;
 		typeInstance->mSize = 1;
-	mContext->mFailTypes.Add(typeInstance);
+	mContext->mFailTypes.TryAdd(typeInstance, BfFailKind_Normal);
 	mHadBuildError = true;
 	mHadBuildError = true;
 }
 }
 
 
@@ -3338,7 +3338,7 @@ void BfModule::DoPopulateType_TypeAlias(BfTypeAliasType* typeAlias)
 		AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom);
 		AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom);
 	}
 	}
 	else
 	else
-		mContext->mFailTypes.Add(typeAlias);
+		mContext->mFailTypes.TryAdd(typeAlias, BfFailKind_Normal);
 
 
 	if (typeAlias->mTypeFailed)
 	if (typeAlias->mTypeFailed)
 		aliasToType = NULL;
 		aliasToType = NULL;

+ 11 - 0
IDEHelper/Compiler/BfResolvedTypeUtils.cpp

@@ -3982,6 +3982,17 @@ int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHa
 						{
 						{
 							ctx->mHadVar = true;
 							ctx->mHadVar = true;
 							cachedResolvedType = ctx->mModule->GetPrimitiveType(BfTypeCode_Var);
 							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))
 						else if (BfIRConstHolder::IsInt(constant->mTypeCode))
 						{
 						{