summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Linker
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-11-28 16:41:24 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-11-28 16:41:24 +0000
commita96f235c157c40b58e12e813faf97d8bc1004aa2 (patch)
tree3f6f81dacefc83afc477ae8bc1b8c8da8964c71d /llvm/lib/Linker
parent3d0974105a8583fdb16e6b7c911f864a8848f962 (diff)
downloadbcm5719-llvm-a96f235c157c40b58e12e813faf97d8bc1004aa2.tar.gz
bcm5719-llvm-a96f235c157c40b58e12e813faf97d8bc1004aa2.zip
Add back r222727 with a fix.
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. llvm-svn: 222923
Diffstat (limited to 'llvm/lib/Linker')
-rw-r--r--llvm/lib/Linker/LinkModules.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp
index d3cb78c6997..8822a3ae0a5 100644
--- a/llvm/lib/Linker/LinkModules.cpp
+++ b/llvm/lib/Linker/LinkModules.cpp
@@ -47,6 +47,8 @@ class TypeMapTy : public ValueMapTypeRemapper {
/// 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;
@@ -95,6 +97,7 @@ private:
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.
@@ -103,8 +106,14 @@ void TypeMapTy::addTypeMapping(Type *DstTy, Type *SrcTy) {
// 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,
@@ -139,14 +148,15 @@ bool TypeMapTy::areTypesIsomorphic(Type *DstTy, Type *SrcTy) {
// 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;
}
OpenPOWER on IntegriCloud