summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: fdf8098)
raw | patch | inline | side by side (parent: fdf8098)
author | Rafael Espindola <rafael.espindola@gmail.com> | |
Fri, 28 Nov 2014 16:41:24 +0000 (16:41 +0000) | ||
committer | Rafael Espindola <rafael.espindola@gmail.com> | |
Fri, 28 Nov 2014 16:41:24 +0000 (16:41 +0000) |
The original patch would fail when:
* A dst opaque type (%A) is matched with a src type (%A).
* A src opaque (%E) type is then speculatively matched with %A and the
speculation fails afterward.
* When rolling back the speculation we would cancel the source %A to dest
%A mapping.
The fix is to keep an explicit list of which resolutions are speculative.
Original message:
Fix overly aggressive type merging.
If we find out that two types are *not* isomorphic, we learn nothing about
opaque sub types in both the source and destination.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222923 91177308-0d34-0410-b5e6-96231b3b80d8
* A dst opaque type (%A) is matched with a src type (%A).
* A src opaque (%E) type is then speculatively matched with %A and the
speculation fails afterward.
* When rolling back the speculation we would cancel the source %A to dest
%A mapping.
The fix is to keep an explicit list of which resolutions are speculative.
Original message:
Fix overly aggressive type merging.
If we find out that two types are *not* isomorphic, we learn nothing about
opaque sub types in both the source and destination.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222923 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Linker/LinkModules.cpp | patch | blob | history | |
test/Linker/Inputs/type-unique-opaque.ll | [new file with mode: 0644] | patch | blob |
test/Linker/type-unique-opaque.ll | [new file with mode: 0644] | patch | blob |
index d3cb78c6997517e34cee0348d6ee32ff62640de8..8822a3ae0a52b0bc527ff85fbcc08440b9210a83 100644 (file)
/// roll back.
SmallVector<Type*, 16> SpeculativeTypes;
+ SmallVector<StructType*, 16> SpeculativeDstOpaqueTypes;
+
/// This is a list of non-opaque structs in the source module that are mapped
/// to an opaque struct in the destination module.
SmallVector<StructType*, 16> SrcDefinitionsToResolve;
void TypeMapTy::addTypeMapping(Type *DstTy, Type *SrcTy) {
assert(SpeculativeTypes.empty());
+ assert(SpeculativeDstOpaqueTypes.empty());
// Check to see if these types are recursively isomorphic and establish a
// mapping between them if so.
// any speculative mappings we've established.
for (Type *Ty : SpeculativeTypes)
MappedTypes.erase(Ty);
+
+ SrcDefinitionsToResolve.resize(SrcDefinitionsToResolve.size() -
+ SpeculativeDstOpaqueTypes.size());
+ for (StructType *Ty : SpeculativeDstOpaqueTypes)
+ DstResolvedOpaqueTypes.erase(Ty);
}
SpeculativeTypes.clear();
+ SpeculativeDstOpaqueTypes.clear();
}
/// Recursively walk this pair of types, returning true if they are isomorphic,
// Mapping a non-opaque source type to an opaque dest. If this is the first
// type that we're mapping onto this destination type then we succeed. Keep
- // the dest, but fill it in later. This doesn't need to be speculative. If
- // this is the second (different) type that we're trying to map onto the
- // same opaque type then we fail.
+ // the dest, but fill it in later. If this is the second (different) type
+ // that we're trying to map onto the same opaque type then we fail.
if (cast<StructType>(DstTy)->isOpaque()) {
// We can only map one source type onto the opaque destination type.
if (!DstResolvedOpaqueTypes.insert(cast<StructType>(DstTy)).second)
return false;
SrcDefinitionsToResolve.push_back(SSTy);
+ SpeculativeTypes.push_back(SrcTy);
+ SpeculativeDstOpaqueTypes.push_back(cast<StructType>(DstTy));
Entry = DstTy;
return true;
}
diff --git a/test/Linker/Inputs/type-unique-opaque.ll b/test/Linker/Inputs/type-unique-opaque.ll
--- /dev/null
@@ -0,0 +1,6 @@
+%t = type { i8 }
+%t2 = type { %t*, i16 }
+
+define %t2* @f() {
+ ret %t2* null
+}
diff --git a/test/Linker/type-unique-opaque.ll b/test/Linker/type-unique-opaque.ll
--- /dev/null
@@ -0,0 +1,16 @@
+; RUN: llvm-link -S %s %p/Inputs/type-unique-opaque.ll | FileCheck %s
+
+; Test that a failed attempt at merging %u2 and %t2 (for the other file) will
+; not cause %u and %t to get merged.
+
+; CHECK: %u = type opaque
+; CHECK: define %u* @g() {
+
+%u = type opaque
+%u2 = type { %u*, i8 }
+
+declare %u2* @f()
+
+define %u* @g() {
+ ret %u* null
+}