mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-02 08:45:55 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222923 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fdf8098678
commit
f716393db9
@ -47,6 +47,8 @@ class TypeMapTy : public ValueMapTypeRemapper {
|
|||||||
/// roll back.
|
/// roll back.
|
||||||
SmallVector<Type*, 16> SpeculativeTypes;
|
SmallVector<Type*, 16> SpeculativeTypes;
|
||||||
|
|
||||||
|
SmallVector<StructType*, 16> SpeculativeDstOpaqueTypes;
|
||||||
|
|
||||||
/// This is a list of non-opaque structs in the source module that are mapped
|
/// This is a list of non-opaque structs in the source module that are mapped
|
||||||
/// to an opaque struct in the destination module.
|
/// to an opaque struct in the destination module.
|
||||||
SmallVector<StructType*, 16> SrcDefinitionsToResolve;
|
SmallVector<StructType*, 16> SrcDefinitionsToResolve;
|
||||||
@ -95,6 +97,7 @@ private:
|
|||||||
|
|
||||||
void TypeMapTy::addTypeMapping(Type *DstTy, Type *SrcTy) {
|
void TypeMapTy::addTypeMapping(Type *DstTy, Type *SrcTy) {
|
||||||
assert(SpeculativeTypes.empty());
|
assert(SpeculativeTypes.empty());
|
||||||
|
assert(SpeculativeDstOpaqueTypes.empty());
|
||||||
|
|
||||||
// Check to see if these types are recursively isomorphic and establish a
|
// Check to see if these types are recursively isomorphic and establish a
|
||||||
// mapping between them if so.
|
// mapping between them if so.
|
||||||
@ -103,8 +106,14 @@ void TypeMapTy::addTypeMapping(Type *DstTy, Type *SrcTy) {
|
|||||||
// any speculative mappings we've established.
|
// any speculative mappings we've established.
|
||||||
for (Type *Ty : SpeculativeTypes)
|
for (Type *Ty : SpeculativeTypes)
|
||||||
MappedTypes.erase(Ty);
|
MappedTypes.erase(Ty);
|
||||||
|
|
||||||
|
SrcDefinitionsToResolve.resize(SrcDefinitionsToResolve.size() -
|
||||||
|
SpeculativeDstOpaqueTypes.size());
|
||||||
|
for (StructType *Ty : SpeculativeDstOpaqueTypes)
|
||||||
|
DstResolvedOpaqueTypes.erase(Ty);
|
||||||
}
|
}
|
||||||
SpeculativeTypes.clear();
|
SpeculativeTypes.clear();
|
||||||
|
SpeculativeDstOpaqueTypes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recursively walk this pair of types, returning true if they are isomorphic,
|
/// 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
|
// 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
|
// 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
|
// the dest, but fill it in later. If this is the second (different) type
|
||||||
// this is the second (different) type that we're trying to map onto the
|
// that we're trying to map onto the same opaque type then we fail.
|
||||||
// same opaque type then we fail.
|
|
||||||
if (cast<StructType>(DstTy)->isOpaque()) {
|
if (cast<StructType>(DstTy)->isOpaque()) {
|
||||||
// We can only map one source type onto the opaque destination type.
|
// We can only map one source type onto the opaque destination type.
|
||||||
if (!DstResolvedOpaqueTypes.insert(cast<StructType>(DstTy)).second)
|
if (!DstResolvedOpaqueTypes.insert(cast<StructType>(DstTy)).second)
|
||||||
return false;
|
return false;
|
||||||
SrcDefinitionsToResolve.push_back(SSTy);
|
SrcDefinitionsToResolve.push_back(SSTy);
|
||||||
|
SpeculativeTypes.push_back(SrcTy);
|
||||||
|
SpeculativeDstOpaqueTypes.push_back(cast<StructType>(DstTy));
|
||||||
Entry = DstTy;
|
Entry = DstTy;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
6
test/Linker/Inputs/type-unique-opaque.ll
Normal file
6
test/Linker/Inputs/type-unique-opaque.ll
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
%t = type { i8 }
|
||||||
|
%t2 = type { %t*, i16 }
|
||||||
|
|
||||||
|
define %t2* @f() {
|
||||||
|
ret %t2* null
|
||||||
|
}
|
16
test/Linker/type-unique-opaque.ll
Normal file
16
test/Linker/type-unique-opaque.ll
Normal file
@ -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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user