diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2018-05-05 00:51:55 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2018-05-05 00:51:55 +0000 |
commit | e04ecc88de83af096d9d293ea11bb70ee564de1c (patch) | |
tree | dda7f221b7ee6ad88443b91204845bed1b63bdc6 /llvm | |
parent | 60609c9f12de46dc1b6b59d7ee78604e67980b3d (diff) | |
download | bcm5719-llvm-e04ecc88de83af096d9d293ea11bb70ee564de1c.tar.gz bcm5719-llvm-e04ecc88de83af096d9d293ea11bb70ee564de1c.zip |
LowerTypeTests: Fix non-determinism in code that handles icall branch funnels.
This was exposed by enabling expensive checks, which causes llvm::sort
to sort randomly.
Differential Revision: https://reviews.llvm.org/D45901
llvm-svn: 331573
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Transforms/IPO/LowerTypeTests.cpp | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp index 1e17d13faec..c861373bd41 100644 --- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp +++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp @@ -297,11 +297,13 @@ public: struct ICallBranchFunnel final : TrailingObjects<ICallBranchFunnel, GlobalTypeMember *> { static ICallBranchFunnel *create(BumpPtrAllocator &Alloc, CallInst *CI, - ArrayRef<GlobalTypeMember *> Targets) { + ArrayRef<GlobalTypeMember *> Targets, + unsigned UniqueId) { auto *Call = static_cast<ICallBranchFunnel *>( Alloc.Allocate(totalSizeToAlloc<GlobalTypeMember *>(Targets.size()), alignof(ICallBranchFunnel))); Call->CI = CI; + Call->UniqueId = UniqueId; Call->NTargets = Targets.size(); std::uninitialized_copy(Targets.begin(), Targets.end(), Call->getTrailingObjects<GlobalTypeMember *>()); @@ -313,6 +315,8 @@ struct ICallBranchFunnel final return makeArrayRef(getTrailingObjects<GlobalTypeMember *>(), NTargets); } + unsigned UniqueId; + private: size_t NTargets; }; @@ -1664,11 +1668,11 @@ bool LowerTypeTestsModule::lower() { // identifiers. BumpPtrAllocator Alloc; struct TIInfo { - unsigned Index; + unsigned UniqueId; std::vector<GlobalTypeMember *> RefGlobals; }; DenseMap<Metadata *, TIInfo> TypeIdInfo; - unsigned I = 0; + unsigned CurUniqueId = 0; SmallVector<MDNode *, 2> Types; struct ExportedFunctionInfo { @@ -1756,7 +1760,7 @@ bool LowerTypeTestsModule::lower() { for (MDNode *Type : Types) { verifyTypeMDNode(&GO, Type); auto &Info = TypeIdInfo[Type->getOperand(1)]; - Info.Index = ++I; + Info.UniqueId = ++CurUniqueId; Info.RefGlobals.push_back(GTM); } } @@ -1825,8 +1829,9 @@ bool LowerTypeTestsModule::lower() { } GlobalClasses.unionSets( - CurSet, GlobalClasses.findLeader(GlobalClasses.insert( - ICallBranchFunnel::create(Alloc, CI, Targets)))); + CurSet, GlobalClasses.findLeader( + GlobalClasses.insert(ICallBranchFunnel::create( + Alloc, CI, Targets, ++CurUniqueId)))); } } @@ -1863,13 +1868,15 @@ bool LowerTypeTestsModule::lower() { continue; ++NumTypeIdDisjointSets; - unsigned MaxIndex = 0; + unsigned MaxUniqueId = 0; for (GlobalClassesTy::member_iterator MI = GlobalClasses.member_begin(I); MI != GlobalClasses.member_end(); ++MI) { - if ((*MI).is<Metadata *>()) - MaxIndex = std::max(MaxIndex, TypeIdInfo[MI->get<Metadata *>()].Index); + if (auto *MD = MI->dyn_cast<Metadata *>()) + MaxUniqueId = std::max(MaxUniqueId, TypeIdInfo[MD].UniqueId); + else if (auto *BF = MI->dyn_cast<ICallBranchFunnel *>()) + MaxUniqueId = std::max(MaxUniqueId, BF->UniqueId); } - Sets.emplace_back(I, MaxIndex); + Sets.emplace_back(I, MaxUniqueId); } llvm::sort(Sets.begin(), Sets.end(), [](const std::pair<GlobalClassesTy::iterator, unsigned> &S1, @@ -1894,12 +1901,18 @@ bool LowerTypeTestsModule::lower() { ICallBranchFunnels.push_back(MI->get<ICallBranchFunnel *>()); } - // Order type identifiers by global index for determinism. This ordering is - // stable as there is a one-to-one mapping between metadata and indices. + // Order type identifiers by unique ID for determinism. This ordering is + // stable as there is a one-to-one mapping between metadata and unique IDs. llvm::sort(TypeIds.begin(), TypeIds.end(), [&](Metadata *M1, Metadata *M2) { - return TypeIdInfo[M1].Index < TypeIdInfo[M2].Index; + return TypeIdInfo[M1].UniqueId < TypeIdInfo[M2].UniqueId; }); + // Same for the branch funnels. + llvm::sort(ICallBranchFunnels.begin(), ICallBranchFunnels.end(), + [&](ICallBranchFunnel *F1, ICallBranchFunnel *F2) { + return F1->UniqueId < F2->UniqueId; + }); + // Build bitsets for this disjoint set. buildBitSetsFromDisjointSet(TypeIds, Globals, ICallBranchFunnels); } |