summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-11-25 05:59:24 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-11-25 05:59:24 +0000
commit86911440c2af76382db3a5354eb3acd76d8e927e (patch)
tree3ded38966b7fb9512d29af1af65416568c9b57c8 /llvm/lib
parent84f4651f9a4c9d75f75736bae9eca5e75ff8a7ee (diff)
downloadbcm5719-llvm-86911440c2af76382db3a5354eb3acd76d8e927e.tar.gz
bcm5719-llvm-86911440c2af76382db3a5354eb3acd76d8e927e.zip
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: 222727
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Linker/LinkModules.cpp27
1 files changed, 19 insertions, 8 deletions
diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp
index a8dc324daa2..e57a37fb4a0 100644
--- a/llvm/lib/Linker/LinkModules.cpp
+++ b/llvm/lib/Linker/LinkModules.cpp
@@ -107,12 +107,23 @@ void TypeMapTy::addTypeMapping(Type *DstTy, Type *SrcTy) {
// Check to see if these types are recursively isomorphic and establish a
// mapping between them if so.
- if (!areTypesIsomorphic(DstTy, SrcTy)) {
- // Oops, they aren't isomorphic. Just discard this request by rolling out
- // any speculative mappings we've established.
- for (unsigned i = 0, e = SpeculativeTypes.size(); i != e; ++i)
- MappedTypes.erase(SpeculativeTypes[i]);
+ if (areTypesIsomorphic(DstTy, SrcTy)) {
+ SpeculativeTypes.clear();
+ return;
+ }
+
+ // Oops, they aren't isomorphic. Just discard this request by rolling out
+ // any speculative mappings we've established.
+ unsigned Removed = 0;
+ for (unsigned I = 0, E = SpeculativeTypes.size(); I != E; ++I) {
+ Type *SrcTy = SpeculativeTypes[I];
+ auto Iter = MappedTypes.find(SrcTy);
+ auto *DstTy = dyn_cast<StructType>(Iter->second);
+ if (DstTy && DstResolvedOpaqueTypes.erase(DstTy))
+ Removed++;
+ MappedTypes.erase(Iter);
}
+ SrcDefinitionsToResolve.resize(SrcDefinitionsToResolve.size() - Removed);
SpeculativeTypes.clear();
}
@@ -147,14 +158,14 @@ 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);
Entry = DstTy;
return true;
}
OpenPOWER on IntegriCloud