From fb0bace727199795b937f4d8d250fdfbc78fca6f Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 11 Feb 2021 06:48:51 -0800 Subject: [PATCH] Fixed duplicate global variables when used as default args --- IDEHelper/Compiler/BfIRBuilder.cpp | 77 ++++++++++++++++-------------- IDEHelper/Compiler/BfIRBuilder.h | 5 +- IDEHelper/Compiler/BfIRCodeGen.cpp | 36 ++++++++------ IDEHelper/Compiler/BfModule.cpp | 15 +++--- 4 files changed, 73 insertions(+), 60 deletions(-) diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 9469c721..09d6927c 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -615,17 +615,7 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f else if (fromConst->mConstType == BfConstType_GlobalVar) { auto fromGlobalVar = (BfGlobalVar*)fromConst; - auto constGV = mTempAlloc.Alloc(); - chunkId = mTempAlloc.GetChunkedId(constGV); - constGV->mStreamId = -1; - constGV->mConstType = BfConstType_GlobalVar; - constGV->mType = fromGlobalVar->mType; - constGV->mIsConst = fromGlobalVar->mIsConst; - constGV->mLinkageType = fromGlobalVar->mLinkageType; - constGV->mInitializer = fromGlobalVar->mInitializer; - constGV->mName = AllocStr(fromGlobalVar->mName); - constGV->mIsTLS = fromGlobalVar->mIsTLS; - copiedConst = (BfConstant*)constGV; + return CreateGlobalVariableConstant(fromGlobalVar->mType, fromGlobalVar->mIsConst, fromGlobalVar->mLinkageType, fromGlobalVar->mInitializer, fromGlobalVar->mName, fromGlobalVar->mIsTLS); } else if (fromConst->mConstType == BfConstType_GEP32_2) { @@ -1875,6 +1865,7 @@ void BfIRBuilder::ClearConstData() mTempAlloc.Clear(); mConstMemMap.Clear(); mFunctionMap.Clear(); + mGlobalVarMap.Clear(); BF_ASSERT(mMethodTypeMap.GetCount() == 0); BF_ASSERT(mTypeMap.GetCount() == 0); BF_ASSERT(mDITemporaryTypes.size() == 0); @@ -1889,6 +1880,7 @@ void BfIRBuilder::ClearNonConstData() { mMethodTypeMap.Clear(); mFunctionMap.Clear(); + mGlobalVarMap.Clear(); mTypeMap.Clear(); mConstMemMap.Clear(); mDITemporaryTypes.Clear(); @@ -2996,11 +2988,6 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type) if (fieldInstance->mConstIdx != -1) { - if (fieldInstance->GetFieldDef()->mName == "mMembers") - { - NOP; - } - constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx); staticValue = mModule->ConstantToCurrent(constant, typeInstance->mConstHolder, resolvedFieldType); } @@ -4743,39 +4730,55 @@ BfIRValue BfIRBuilder::CreateStackRestore(BfIRValue stackVal) return retVal; } -BfIRValue BfIRBuilder::CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS) +void BfIRBuilder::CreateGlobalVariable(BfIRValue irValue) { + auto globalVar = (BfGlobalVar*)GetConstant(irValue); + + if (!mIgnoreWrites) + { + BF_ASSERT(globalVar->mStreamId == -1); + + if (globalVar->mInitializer) + mHasGlobalDefs = true; + + BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVariable, globalVar->mType, globalVar->mIsConst, (uint8)globalVar->mLinkageType, String(globalVar->mName), globalVar->mIsTLS, globalVar->mInitializer); + globalVar->mStreamId = retVal.mId; + + NEW_CMD_INSERTED_IRVALUE; + } +} + +BfIRValue BfIRConstHolder::CreateGlobalVariableConstant(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS) +{ + BfIRValue* valuePtr = NULL; + if ((!mGlobalVarMap.TryAdd(name, NULL, &valuePtr)) && (!initializer)) + { + return *valuePtr; + } + BF_ASSERT(varType); auto constGV = mTempAlloc.Alloc(); int chunkId = mTempAlloc.GetChunkedId(constGV); constGV->mStreamId = -1; - constGV->mConstType = BfConstType_GlobalVar; - constGV->mType = varType; + constGV->mConstType = BfConstType_GlobalVar; + constGV->mType = varType; constGV->mIsConst = isConstant; constGV->mLinkageType = linkageType; constGV->mInitializer = initializer; constGV->mName = AllocStr(name); - constGV->mIsTLS = isTLS; + constGV->mIsTLS = isTLS; - if (!mIgnoreWrites) - { - if (initializer) - mHasGlobalDefs = true; + auto irValue = BfIRValue(BfIRValueFlags_Const, chunkId);; + *valuePtr = irValue; + return irValue; +} - BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVariable, varType, isConstant, (uint8)linkageType, name, isTLS, initializer); - constGV->mStreamId = retVal.mId; - retVal.mFlags = BfIRValueFlags_Const; -#ifdef CHECK_CONSTHOLDER - retVal.mHolder = this; -#endif - retVal.mId = chunkId; - NEW_CMD_INSERTED_IRVALUE; - return retVal; - } - - auto irValue = BfIRValue(BfIRValueFlags_Const, chunkId); - return irValue; +BfIRValue BfIRBuilder::CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS) +{ + auto irValue = CreateGlobalVariableConstant(varType, isConstant, linkageType, initializer, name); + CreateGlobalVariable(irValue); + return irValue; } void BfIRBuilder::GlobalVar_SetUnnamedAddr(BfIRValue val, bool unnamedAddr) diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index ff098a6c..3d045deb 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -901,6 +901,7 @@ class BfIRConstHolder public: BumpAllocatorT<256> mTempAlloc; BfModule* mModule; + Dictionary mGlobalVarMap; public: void FixTypeCode(BfTypeCode& typeCode); @@ -936,6 +937,7 @@ public: BfIRValue CreateTypeOf(BfType* type); BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData); BfIRValue GetUndefConstValue(BfIRType type); + BfIRValue CreateGlobalVariableConstant(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS = false); bool WriteConstant(BfIRValue val, void* ptr, BfType* type); BfIRValue ReadConstant(void* ptr, BfType* type); @@ -979,7 +981,7 @@ public: bool mHasDebugInfo; bool mHasDebugLineInfo; Dictionary mMethodTypeMap; - Dictionary mFunctionMap; + Dictionary mFunctionMap; Dictionary mTypeMap; Dictionary mConstMemMap; Array mDITemporaryTypes; @@ -1227,6 +1229,7 @@ public: BfIRValue CreateStackRestore(BfIRValue stackVal); BfIRValue CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS = false); + void CreateGlobalVariable(BfIRValue irValue); void GlobalVar_SetUnnamedAddr(BfIRValue val, bool unnamedAddr); void GlobalVar_SetInitializer(BfIRValue globalVar, BfIRValue initVal); void GlobalVar_SetAlignment(BfIRValue globalVar, int alignment); diff --git a/IDEHelper/Compiler/BfIRCodeGen.cpp b/IDEHelper/Compiler/BfIRCodeGen.cpp index 79ea9430..25dcc194 100644 --- a/IDEHelper/Compiler/BfIRCodeGen.cpp +++ b/IDEHelper/Compiler/BfIRCodeGen.cpp @@ -810,13 +810,17 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, llvm::GlobalVariable* globalVariable = mLLVMModule->getGlobalVariable(name.c_str(), true); if (globalVariable == NULL) { - globalVariable = new llvm::GlobalVariable( - *mLLVMModule, - varType, - isConstant, - LLVMMapLinkageType(linkageType), - initializer, - name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal); + globalVariable = mLLVMModule->getGlobalVariable(name.c_str()); + if (globalVariable == NULL) + { + globalVariable = new llvm::GlobalVariable( + *mLLVMModule, + varType, + isConstant, + LLVMMapLinkageType(linkageType), + initializer, + name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal); + } } llvmValue = globalVariable; @@ -2390,13 +2394,17 @@ void BfIRCodeGen::HandleNextCmd() CMD_PARAM(bool, isTLS); CMD_PARAM(llvm::Constant*, initializer); - auto globalVariable = new llvm::GlobalVariable( - *mLLVMModule, - varType, - isConstant, - LLVMMapLinkageType(linkageType), - initializer, - name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal); + auto globalVariable = mLLVMModule->getGlobalVariable(name.c_str()); + if (globalVariable == NULL) + { + globalVariable = new llvm::GlobalVariable( + *mLLVMModule, + varType, + isConstant, + LLVMMapLinkageType(linkageType), + initializer, + name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal); + } SetResult(curId, globalVariable); } break; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 7d1c7329..7b6c32ab 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -13722,6 +13722,10 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance) { globalValue = *globalValuePtr; BF_ASSERT(globalValue); + + auto globalVar = (BfGlobalVar*)mBfIRBuilder->GetConstant(globalValue); + if ((globalVar->mStreamId == -1) && (!mBfIRBuilder->mIgnoreWrites)) + mBfIRBuilder->CreateGlobalVariable(globalValue); } else { @@ -13753,16 +13757,11 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance) BfIRValue(), staticVarName, IsThreadLocal(fieldInstance)); - - if (!mBfIRBuilder->mIgnoreWrites) - { - // Only store this if we actually did the creation - BF_ASSERT(globalValue); - mStaticFieldRefs[fieldInstance] = globalValue; - } + + BF_ASSERT(globalValue); + mStaticFieldRefs[fieldInstance] = globalValue; BfLogSysM("Mod:%p Type:%p ReferenceStaticField %p -> %p\n", this, fieldInstance->mOwner, fieldInstance, globalValue); - } }