[llvm] r331573 - LowerTypeTests: Fix non-determinism in code that handles icall branch funnels.
Peter Collingbourne via llvm-commits
llvm-commits at lists.llvm.org
Fri May 4 17:51:55 PDT 2018
Author: pcc
Date: Fri May 4 17:51:55 2018
New Revision: 331573
URL: http://llvm.org/viewvc/llvm-project?rev=331573&view=rev
Log:
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
Modified:
llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp
Modified: llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp?rev=331573&r1=331572&r2=331573&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp Fri May 4 17:51:55 2018
@@ -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);
}
More information about the llvm-commits
mailing list