summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/IR/GVMaterializer.h4
-rw-r--r--llvm/include/llvm/IR/Module.h2
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp23
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.h5
-rw-r--r--llvm/lib/IR/Module.cpp14
-rw-r--r--llvm/lib/Linker/LinkModules.cpp6
-rw-r--r--llvm/test/Linker/Inputs/pr21374.ll4
-rw-r--r--llvm/test/Linker/pr21374.ll20
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
+}
OpenPOWER on IntegriCloud