diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/IR/GVMaterializer.h | 4 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Module.h | 2 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 23 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.h | 5 | ||||
-rw-r--r-- | llvm/lib/IR/Module.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Linker/LinkModules.cpp | 6 | ||||
-rw-r--r-- | llvm/test/Linker/Inputs/pr21374.ll | 4 | ||||
-rw-r--r-- | llvm/test/Linker/pr21374.ll | 20 |
8 files changed, 71 insertions, 7 deletions
diff --git a/llvm/include/llvm/IR/GVMaterializer.h b/llvm/include/llvm/IR/GVMaterializer.h index a7d68eccba5..6f57dc2a98a 100644 --- a/llvm/include/llvm/IR/GVMaterializer.h +++ b/llvm/include/llvm/IR/GVMaterializer.h @@ -19,11 +19,13 @@ #define LLVM_IR_GVMATERIALIZER_H #include <system_error> +#include <vector> namespace llvm { class Function; class GlobalValue; class Module; +class StructType; class GVMaterializer { protected: @@ -50,6 +52,8 @@ public: /// Make sure the entire Module has been completely read. /// virtual std::error_code MaterializeModule(Module *M) = 0; + + virtual std::vector<StructType *> getIdentifiedStructTypes() const = 0; }; } // End llvm namespace diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index 7fff80ae24b..30d3d7c4833 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -327,6 +327,8 @@ public: /// name. StructType *getTypeByName(StringRef Name) const; + std::vector<StructType *> getIdentifiedStructTypes() const; + /// @} /// @name Function Accessors /// @{ diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 5dab73991de..25efa609a19 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -487,7 +487,20 @@ Type *BitcodeReader::getTypeByID(unsigned ID) { // If we have a forward reference, the only possible case is when it is to a // named struct. Just create a placeholder for now. - return TypeList[ID] = StructType::create(Context); + return TypeList[ID] = createIdentifiedStructType(Context); +} + +StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context, + StringRef Name) { + auto *Ret = StructType::create(Context, Name); + IdentifiedStructTypes.push_back(Ret); + return Ret; +} + +StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context) { + auto *Ret = StructType::create(Context); + IdentifiedStructTypes.push_back(Ret); + return Ret; } @@ -922,7 +935,7 @@ std::error_code BitcodeReader::ParseTypeTableBody() { Res->setName(TypeName); TypeList[NumRecords] = nullptr; } else // Otherwise, create a new struct. - Res = StructType::create(Context, TypeName); + Res = createIdentifiedStructType(Context, TypeName); TypeName.clear(); SmallVector<Type*, 8> EltTys; @@ -951,7 +964,7 @@ std::error_code BitcodeReader::ParseTypeTableBody() { Res->setName(TypeName); TypeList[NumRecords] = nullptr; } else // Otherwise, create a new struct with no body. - Res = StructType::create(Context, TypeName); + Res = createIdentifiedStructType(Context, TypeName); TypeName.clear(); ResultTy = Res; break; @@ -3416,6 +3429,10 @@ std::error_code BitcodeReader::MaterializeModule(Module *M) { return std::error_code(); } +std::vector<StructType *> BitcodeReader::getIdentifiedStructTypes() const { + return IdentifiedStructTypes; +} + std::error_code BitcodeReader::InitStream() { if (LazyStreamer) return InitLazyStream(); diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.h b/llvm/lib/Bitcode/Reader/BitcodeReader.h index 070300ac3e0..10f870b59b8 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.h +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.h @@ -227,6 +227,7 @@ public: bool isDematerializable(const GlobalValue *GV) const override; std::error_code materialize(GlobalValue *GV) override; std::error_code MaterializeModule(Module *M) override; + std::vector<StructType *> getIdentifiedStructTypes() const override; void Dematerialize(GlobalValue *GV) override; /// @brief Main interface to parsing a bitcode buffer. @@ -240,6 +241,10 @@ public: static uint64_t decodeSignRotatedValue(uint64_t V); private: + std::vector<StructType *> IdentifiedStructTypes; + StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name); + StructType *createIdentifiedStructType(LLVMContext &Context); + Type *getTypeByID(unsigned ID); Value *getFnValueByID(unsigned ID, Type *Ty) { if (Ty && Ty->isMetadataTy()) diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 14e534b8b1b..065c66e1491 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -23,6 +23,7 @@ #include "llvm/IR/InstrTypes.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LeakDetector.h" +#include "llvm/IR/TypeFinder.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/Path.h" #include "llvm/Support/RandomNumberGenerator.h" @@ -425,6 +426,19 @@ std::error_code Module::materializeAllPermanently() { // Other module related stuff. // +std::vector<StructType *> Module::getIdentifiedStructTypes() const { + // If we have a materializer, it is possible that some unread function + // uses a type that is currently not visible to a TypeFinder, so ask + // the materializer which types it created. + if (Materializer) + return Materializer->getIdentifiedStructTypes(); + + std::vector<StructType *> Ret; + TypeFinder SrcStructTypes; + SrcStructTypes.run(*this, true); + Ret.assign(SrcStructTypes.begin(), SrcStructTypes.end()); + return Ret; +} // dropAllReferences() - This function causes all the subelements to "let go" // of all references that they are maintaining. This allows one to 'delete' a diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp index ebb790201fd..ecfb9431974 100644 --- a/llvm/lib/Linker/LinkModules.cpp +++ b/llvm/lib/Linker/LinkModules.cpp @@ -791,10 +791,8 @@ void ModuleLinker::computeTypeMapping() { // At this point, the destination module may have a type "%foo = { i32 }" for // example. When the source module got loaded into the same LLVMContext, if // it had the same type, it would have been renamed to "%foo.42 = { i32 }". - TypeFinder SrcStructTypes; - SrcStructTypes.run(*SrcM, true); - - for (StructType *ST : SrcStructTypes) { + std::vector<StructType *> Types = SrcM->getIdentifiedStructTypes(); + for (StructType *ST : Types) { if (!ST->hasName()) continue; diff --git a/llvm/test/Linker/Inputs/pr21374.ll b/llvm/test/Linker/Inputs/pr21374.ll new file mode 100644 index 00000000000..fcddeafc2e7 --- /dev/null +++ b/llvm/test/Linker/Inputs/pr21374.ll @@ -0,0 +1,4 @@ +%foo = type { i8* } +define void @g(%foo* %x) { + ret void +} diff --git a/llvm/test/Linker/pr21374.ll b/llvm/test/Linker/pr21374.ll new file mode 100644 index 00000000000..d777971aded --- /dev/null +++ b/llvm/test/Linker/pr21374.ll @@ -0,0 +1,20 @@ +; RUN: llvm-link -S -o - %p/pr21374.ll %p/Inputs/pr21374.ll | FileCheck %s +; RUN: llvm-link -S -o - %p/Inputs/pr21374.ll %p/pr21374.ll | FileCheck %s + +; RUN: llvm-as -o %t1.bc %p/pr21374.ll +; RUN: llvm-as -o %t2.bc %p/Inputs/pr21374.ll + +; RUN: llvm-link -S -o - %t1.bc %t2.bc | FileCheck %s +; RUN: llvm-link -S -o - %t2.bc %t1.bc | FileCheck %s + +; Test that we get the same result with or without lazy loading. + +; CHECK: %foo = type { i8* } +; CHECK-DAG: bitcast i32* null to %foo* +; CHECK-DAG: define void @g(%foo* %x) + +%foo = type { i8* } +define void @f() { + bitcast i32* null to %foo* + ret void +} |