Skip to content

Commit 297fb66

Browse files
committed
Use a deterministic order when updating the DominatorTree
This solves a problem with non-deterministic output from opt due to not performing dominator tree updates in a deterministic order. The problem that was analysed indicated that JumpThreading was using the DomTreeUpdater via llvm::MergeBasicBlockIntoOnlyPred. When preparing the list of updates to send to DomTreeUpdater::applyUpdates we iterated over a SmallPtrSet, which didn't give a well-defined order of updates to perform. The added domtree-updates.ll test case is an example that would result in non-deterministic printouts of the domtree. Semantically those domtree:s are equivalent, but it show the fact that when we use the domtree iterator the order in which nodes are visited depend on the order in which dominator tree updates are performed. Since some passes (at least EarlyCSE) are iterating over nodes in the dominator tree in a similar fashion as the domtree printer, then the order in which transforms are applied by such passes, transitively, also depend on the order in which dominator tree updates are performed. And taking EarlyCSE as an example the end result could be different depending on in which order the transforms are applied. Reviewed By: nikic, kuhar Differential Revision: https://reviews.llvm.org/D110292
1 parent 6180806 commit 297fb66

File tree

6 files changed

+200
-73
lines changed

6 files changed

+200
-73
lines changed

llvm/include/llvm/Support/GenericDomTree.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -528,28 +528,28 @@ class DominatorTreeBase {
528528
/// of CFG edges must not delete the CFG nodes before calling this function.
529529
///
530530
/// The applyUpdates function can reorder the updates and remove redundant
531-
/// ones internally. The batch updater is also able to detect sequences of
532-
/// zero and exactly one update -- it's optimized to do less work in these
533-
/// cases.
531+
/// ones internally (as long as it is done in a deterministic fashion). The
532+
/// batch updater is also able to detect sequences of zero and exactly one
533+
/// update -- it's optimized to do less work in these cases.
534534
///
535535
/// Note that for postdominators it automatically takes care of applying
536536
/// updates on reverse edges internally (so there's no need to swap the
537537
/// From and To pointers when constructing DominatorTree::UpdateType).
538538
/// The type of updates is the same for DomTreeBase<T> and PostDomTreeBase<T>
539539
/// with the same template parameter T.
540540
///
541-
/// \param Updates An unordered sequence of updates to perform. The current
542-
/// CFG and the reverse of these updates provides the pre-view of the CFG.
541+
/// \param Updates An ordered sequence of updates to perform. The current CFG
542+
/// and the reverse of these updates provides the pre-view of the CFG.
543543
///
544544
void applyUpdates(ArrayRef<UpdateType> Updates) {
545545
GraphDiff<NodePtr, IsPostDominator> PreViewCFG(
546546
Updates, /*ReverseApplyUpdates=*/true);
547547
DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, nullptr);
548548
}
549549

550-
/// \param Updates An unordered sequence of updates to perform. The current
551-
/// CFG and the reverse of these updates provides the pre-view of the CFG.
552-
/// \param PostViewUpdates An unordered sequence of update to perform in order
550+
/// \param Updates An ordered sequence of updates to perform. The current CFG
551+
/// and the reverse of these updates provides the pre-view of the CFG.
552+
/// \param PostViewUpdates An ordered sequence of update to perform in order
553553
/// to obtain a post-view of the CFG. The DT will be updated assuming the
554554
/// obtained PostViewCFG is the desired end state.
555555
void applyUpdates(ArrayRef<UpdateType> Updates,

llvm/lib/CodeGen/IndirectBrExpandPass.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,12 @@ bool IndirectBrExpandPass::runOnFunction(Function &F) {
260260
if (DTU) {
261261
// If there were multiple indirectbr's, they may have common successors,
262262
// but in the dominator tree, we only track unique edges.
263-
SmallPtrSet<BasicBlock *, 8> UniqueSuccessors(BBs.begin(), BBs.end());
264-
Updates.reserve(Updates.size() + UniqueSuccessors.size());
265-
for (BasicBlock *BB : UniqueSuccessors)
266-
Updates.push_back({DominatorTree::Insert, SwitchBB, BB});
263+
SmallPtrSet<BasicBlock *, 8> UniqueSuccessors;
264+
Updates.reserve(Updates.size() + BBs.size());
265+
for (BasicBlock *BB : BBs) {
266+
if (UniqueSuccessors.insert(BB).second)
267+
Updates.push_back({DominatorTree::Insert, SwitchBB, BB});
268+
}
267269
DTU->applyUpdates(Updates);
268270
}
269271

llvm/lib/Transforms/Utils/BasicBlockUtils.cpp

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -235,22 +235,26 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU,
235235
// These dominator edges will be redirected from Pred.
236236
std::vector<DominatorTree::UpdateType> Updates;
237237
if (DTU) {
238-
SmallPtrSet<BasicBlock *, 2> SuccsOfBB(succ_begin(BB), succ_end(BB));
238+
// To avoid processing the same predecessor more than once.
239+
SmallPtrSet<BasicBlock *, 8> SeenSuccs;
239240
SmallPtrSet<BasicBlock *, 2> SuccsOfPredBB(succ_begin(PredBB),
240241
succ_end(PredBB));
241-
Updates.reserve(Updates.size() + 2 * SuccsOfBB.size() + 1);
242+
Updates.reserve(Updates.size() + 2 * succ_size(BB) + 1);
242243
// Add insert edges first. Experimentally, for the particular case of two
243244
// blocks that can be merged, with a single successor and single predecessor
244245
// respectively, it is beneficial to have all insert updates first. Deleting
245246
// edges first may lead to unreachable blocks, followed by inserting edges
246247
// making the blocks reachable again. Such DT updates lead to high compile
247248
// times. We add inserts before deletes here to reduce compile time.
248-
for (BasicBlock *SuccOfBB : SuccsOfBB)
249+
for (BasicBlock *SuccOfBB : successors(BB))
249250
// This successor of BB may already be a PredBB's successor.
250251
if (!SuccsOfPredBB.contains(SuccOfBB))
251-
Updates.push_back({DominatorTree::Insert, PredBB, SuccOfBB});
252-
for (BasicBlock *SuccOfBB : SuccsOfBB)
253-
Updates.push_back({DominatorTree::Delete, BB, SuccOfBB});
252+
if (SeenSuccs.insert(SuccOfBB).second)
253+
Updates.push_back({DominatorTree::Insert, PredBB, SuccOfBB});
254+
SeenSuccs.clear();
255+
for (BasicBlock *SuccOfBB : successors(BB))
256+
if (SeenSuccs.insert(SuccOfBB).second)
257+
Updates.push_back({DominatorTree::Delete, BB, SuccOfBB});
254258
Updates.push_back({DominatorTree::Delete, PredBB, BB});
255259
}
256260

@@ -804,14 +808,14 @@ static BasicBlock *SplitBlockImpl(BasicBlock *Old, Instruction *SplitPt,
804808
if (DTU) {
805809
SmallVector<DominatorTree::UpdateType, 8> Updates;
806810
// Old dominates New. New node dominates all other nodes dominated by Old.
807-
SmallPtrSet<BasicBlock *, 8> UniqueSuccessorsOfOld(succ_begin(New),
808-
succ_end(New));
811+
SmallPtrSet<BasicBlock *, 8> UniqueSuccessorsOfOld;
809812
Updates.push_back({DominatorTree::Insert, Old, New});
810-
Updates.reserve(Updates.size() + 2 * UniqueSuccessorsOfOld.size());
811-
for (BasicBlock *UniqueSuccessorOfOld : UniqueSuccessorsOfOld) {
812-
Updates.push_back({DominatorTree::Insert, New, UniqueSuccessorOfOld});
813-
Updates.push_back({DominatorTree::Delete, Old, UniqueSuccessorOfOld});
814-
}
813+
Updates.reserve(Updates.size() + 2 * succ_size(New));
814+
for (BasicBlock *SuccessorOfOld : successors(New))
815+
if (UniqueSuccessorsOfOld.insert(SuccessorOfOld).second) {
816+
Updates.push_back({DominatorTree::Insert, New, SuccessorOfOld});
817+
Updates.push_back({DominatorTree::Delete, Old, SuccessorOfOld});
818+
}
815819

816820
DTU->applyUpdates(Updates);
817821
} else if (DT)
@@ -870,14 +874,14 @@ BasicBlock *llvm::splitBlockBefore(BasicBlock *Old, Instruction *SplitPt,
870874
SmallVector<DominatorTree::UpdateType, 8> DTUpdates;
871875
// New dominates Old. The predecessor nodes of the Old node dominate
872876
// New node.
873-
SmallPtrSet<BasicBlock *, 8> UniquePredecessorsOfOld(pred_begin(New),
874-
pred_end(New));
877+
SmallPtrSet<BasicBlock *, 8> UniquePredecessorsOfOld;
875878
DTUpdates.push_back({DominatorTree::Insert, New, Old});
876-
DTUpdates.reserve(DTUpdates.size() + 2 * UniquePredecessorsOfOld.size());
877-
for (BasicBlock *UniquePredecessorOfOld : UniquePredecessorsOfOld) {
878-
DTUpdates.push_back({DominatorTree::Insert, UniquePredecessorOfOld, New});
879-
DTUpdates.push_back({DominatorTree::Delete, UniquePredecessorOfOld, Old});
880-
}
879+
DTUpdates.reserve(DTUpdates.size() + 2 * pred_size(New));
880+
for (BasicBlock *PredecessorOfOld : predecessors(New))
881+
if (UniquePredecessorsOfOld.insert(PredecessorOfOld).second) {
882+
DTUpdates.push_back({DominatorTree::Insert, PredecessorOfOld, New});
883+
DTUpdates.push_back({DominatorTree::Delete, PredecessorOfOld, Old});
884+
}
881885

882886
DTU->applyUpdates(DTUpdates);
883887

@@ -910,13 +914,14 @@ static void UpdateAnalysisInformation(BasicBlock *OldBB, BasicBlock *NewBB,
910914
} else {
911915
// Split block expects NewBB to have a non-empty set of predecessors.
912916
SmallVector<DominatorTree::UpdateType, 8> Updates;
913-
SmallPtrSet<BasicBlock *, 8> UniquePreds(Preds.begin(), Preds.end());
917+
SmallPtrSet<BasicBlock *, 8> UniquePreds;
914918
Updates.push_back({DominatorTree::Insert, NewBB, OldBB});
915-
Updates.reserve(Updates.size() + 2 * UniquePreds.size());
916-
for (auto *UniquePred : UniquePreds) {
917-
Updates.push_back({DominatorTree::Insert, UniquePred, NewBB});
918-
Updates.push_back({DominatorTree::Delete, UniquePred, OldBB});
919-
}
919+
Updates.reserve(Updates.size() + 2 * Preds.size());
920+
for (auto *Pred : Preds)
921+
if (UniquePreds.insert(Pred).second) {
922+
Updates.push_back({DominatorTree::Insert, Pred, NewBB});
923+
Updates.push_back({DominatorTree::Delete, Pred, OldBB});
924+
}
920925
DTU->applyUpdates(Updates);
921926
}
922927
} else if (DT) {
@@ -1376,14 +1381,14 @@ SplitBlockAndInsertIfThenImpl(Value *Cond, Instruction *SplitBefore,
13761381
BasicBlock *Head = SplitBefore->getParent();
13771382
BasicBlock *Tail = Head->splitBasicBlock(SplitBefore->getIterator());
13781383
if (DTU) {
1379-
SmallPtrSet<BasicBlock *, 8> UniqueSuccessorsOfHead(succ_begin(Tail),
1380-
succ_end(Tail));
1384+
SmallPtrSet<BasicBlock *, 8> UniqueSuccessorsOfHead;
13811385
Updates.push_back({DominatorTree::Insert, Head, Tail});
1382-
Updates.reserve(Updates.size() + 2 * UniqueSuccessorsOfHead.size());
1383-
for (BasicBlock *UniqueSuccessorOfHead : UniqueSuccessorsOfHead) {
1384-
Updates.push_back({DominatorTree::Insert, Tail, UniqueSuccessorOfHead});
1385-
Updates.push_back({DominatorTree::Delete, Head, UniqueSuccessorOfHead});
1386-
}
1386+
Updates.reserve(Updates.size() + 2 * succ_size(Tail));
1387+
for (BasicBlock *SuccessorOfHead : successors(Tail))
1388+
if (UniqueSuccessorsOfHead.insert(SuccessorOfHead).second) {
1389+
Updates.push_back({DominatorTree::Insert, Tail, SuccessorOfHead});
1390+
Updates.push_back({DominatorTree::Delete, Head, SuccessorOfHead});
1391+
}
13871392
}
13881393
Instruction *HeadOldTerm = Head->getTerminator();
13891394
LLVMContext &C = Head->getContext();

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -760,15 +760,18 @@ void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB,
760760
SmallVector<DominatorTree::UpdateType, 32> Updates;
761761

762762
if (DTU) {
763-
SmallPtrSet<BasicBlock *, 2> PredsOfPredBB(pred_begin(PredBB),
764-
pred_end(PredBB));
765-
Updates.reserve(Updates.size() + 2 * PredsOfPredBB.size() + 1);
766-
for (BasicBlock *PredOfPredBB : PredsOfPredBB)
763+
// To avoid processing the same predecessor more than once.
764+
SmallPtrSet<BasicBlock *, 2> SeenPreds;
765+
Updates.reserve(Updates.size() + 2 * pred_size(PredBB) + 1);
766+
for (BasicBlock *PredOfPredBB : predecessors(PredBB))
767767
// This predecessor of PredBB may already have DestBB as a successor.
768768
if (PredOfPredBB != PredBB)
769-
Updates.push_back({DominatorTree::Insert, PredOfPredBB, DestBB});
770-
for (BasicBlock *PredOfPredBB : PredsOfPredBB)
771-
Updates.push_back({DominatorTree::Delete, PredOfPredBB, PredBB});
769+
if (SeenPreds.insert(PredOfPredBB).second)
770+
Updates.push_back({DominatorTree::Insert, PredOfPredBB, DestBB});
771+
SeenPreds.clear();
772+
for (BasicBlock *PredOfPredBB : predecessors(PredBB))
773+
if (SeenPreds.insert(PredOfPredBB).second)
774+
Updates.push_back({DominatorTree::Delete, PredOfPredBB, PredBB});
772775
Updates.push_back({DominatorTree::Delete, PredBB, DestBB});
773776
}
774777

@@ -1096,16 +1099,20 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
10961099

10971100
SmallVector<DominatorTree::UpdateType, 32> Updates;
10981101
if (DTU) {
1102+
// To avoid processing the same predecessor more than once.
1103+
SmallPtrSet<BasicBlock *, 8> SeenPreds;
10991104
// All predecessors of BB will be moved to Succ.
1100-
SmallPtrSet<BasicBlock *, 8> PredsOfBB(pred_begin(BB), pred_end(BB));
11011105
SmallPtrSet<BasicBlock *, 8> PredsOfSucc(pred_begin(Succ), pred_end(Succ));
1102-
Updates.reserve(Updates.size() + 2 * PredsOfBB.size() + 1);
1103-
for (auto *PredOfBB : PredsOfBB)
1106+
Updates.reserve(Updates.size() + 2 * pred_size(BB) + 1);
1107+
for (auto *PredOfBB : predecessors(BB))
11041108
// This predecessor of BB may already have Succ as a successor.
11051109
if (!PredsOfSucc.contains(PredOfBB))
1106-
Updates.push_back({DominatorTree::Insert, PredOfBB, Succ});
1107-
for (auto *PredOfBB : PredsOfBB)
1108-
Updates.push_back({DominatorTree::Delete, PredOfBB, BB});
1110+
if (SeenPreds.insert(PredOfBB).second)
1111+
Updates.push_back({DominatorTree::Insert, PredOfBB, Succ});
1112+
SeenPreds.clear();
1113+
for (auto *PredOfBB : predecessors(BB))
1114+
if (SeenPreds.insert(PredOfBB).second)
1115+
Updates.push_back({DominatorTree::Delete, PredOfBB, BB});
11091116
Updates.push_back({DominatorTree::Delete, BB, Succ});
11101117
}
11111118

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3936,7 +3936,7 @@ bool SimplifyCFGOpt::SimplifyTerminatorOnSelect(Instruction *OldTerm,
39363936
BasicBlock *KeepEdge1 = TrueBB;
39373937
BasicBlock *KeepEdge2 = TrueBB != FalseBB ? FalseBB : nullptr;
39383938

3939-
SmallPtrSet<BasicBlock *, 2> RemovedSuccessors;
3939+
SmallSetVector<BasicBlock *, 2> RemovedSuccessors;
39403940

39413941
// Then remove the rest.
39423942
for (BasicBlock *Succ : successors(OldTerm)) {
@@ -4947,10 +4947,14 @@ static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
49474947
// Gather dead cases.
49484948
SmallVector<ConstantInt *, 8> DeadCases;
49494949
SmallDenseMap<BasicBlock *, int, 8> NumPerSuccessorCases;
4950+
SmallVector<BasicBlock *, 8> UniqueSuccessors;
49504951
for (auto &Case : SI->cases()) {
49514952
auto *Successor = Case.getCaseSuccessor();
4952-
if (DTU)
4953+
if (DTU) {
4954+
if (!NumPerSuccessorCases.count(Successor))
4955+
UniqueSuccessors.push_back(Successor);
49534956
++NumPerSuccessorCases[Successor];
4957+
}
49544958
const APInt &CaseVal = Case.getCaseValue()->getValue();
49554959
if (Known.Zero.intersects(CaseVal) || !Known.One.isSubsetOf(CaseVal) ||
49564960
(CaseVal.getMinSignedBits() > MaxSignificantBitsInCond)) {
@@ -4993,9 +4997,9 @@ static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
49934997

49944998
if (DTU) {
49954999
std::vector<DominatorTree::UpdateType> Updates;
4996-
for (const std::pair<BasicBlock *, int> &I : NumPerSuccessorCases)
4997-
if (I.second == 0)
4998-
Updates.push_back({DominatorTree::Delete, SI->getParent(), I.first});
5000+
for (auto *Successor : UniqueSuccessors)
5001+
if (NumPerSuccessorCases[Successor] == 0)
5002+
Updates.push_back({DominatorTree::Delete, SI->getParent(), Successor});
49995003
DTU->applyUpdates(Updates);
50005004
}
50015005

@@ -6060,15 +6064,13 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
60606064
if (Succ == SI->getDefaultDest())
60616065
continue;
60626066
Succ->removePredecessor(BB);
6063-
RemovedSuccessors.insert(Succ);
6067+
if (DTU && RemovedSuccessors.insert(Succ).second)
6068+
Updates.push_back({DominatorTree::Delete, BB, Succ});
60646069
}
60656070
SI->eraseFromParent();
60666071

6067-
if (DTU) {
6068-
for (BasicBlock *RemovedSuccessor : RemovedSuccessors)
6069-
Updates.push_back({DominatorTree::Delete, BB, RemovedSuccessor});
6072+
if (DTU)
60706073
DTU->applyUpdates(Updates);
6071-
}
60726074

60736075
++NumLookupTables;
60746076
if (NeedMask)
@@ -6235,7 +6237,7 @@ bool SimplifyCFGOpt::simplifyIndirectBr(IndirectBrInst *IBI) {
62356237

62366238
// Eliminate redundant destinations.
62376239
SmallPtrSet<Value *, 8> Succs;
6238-
SmallPtrSet<BasicBlock *, 8> RemovedSuccs;
6240+
SmallSetVector<BasicBlock *, 8> RemovedSuccs;
62396241
for (unsigned i = 0, e = IBI->getNumDestinations(); i != e; ++i) {
62406242
BasicBlock *Dest = IBI->getDestination(i);
62416243
if (!Dest->hasAddressTaken() || !Succs.insert(Dest).second) {
@@ -6325,8 +6327,8 @@ static bool TryToMergeLandingPad(LandingPadInst *LPad, BranchInst *BI,
63256327

63266328
// We've found an identical block. Update our predecessors to take that
63276329
// path instead and make ourselves dead.
6328-
SmallPtrSet<BasicBlock *, 16> Preds(pred_begin(BB), pred_end(BB));
6329-
for (BasicBlock *Pred : Preds) {
6330+
SmallSetVector<BasicBlock *, 16> UniquePreds(pred_begin(BB), pred_end(BB));
6331+
for (BasicBlock *Pred : UniquePreds) {
63306332
InvokeInst *II = cast<InvokeInst>(Pred->getTerminator());
63316333
assert(II->getNormalDest() != BB && II->getUnwindDest() == BB &&
63326334
"unexpected successor");
@@ -6343,8 +6345,8 @@ static bool TryToMergeLandingPad(LandingPadInst *LPad, BranchInst *BI,
63436345
if (isa<DbgInfoIntrinsic>(Inst))
63446346
Inst.eraseFromParent();
63456347

6346-
SmallPtrSet<BasicBlock *, 16> Succs(succ_begin(BB), succ_end(BB));
6347-
for (BasicBlock *Succ : Succs) {
6348+
SmallSetVector<BasicBlock *, 16> UniqueSuccs(succ_begin(BB), succ_end(BB));
6349+
for (BasicBlock *Succ : UniqueSuccs) {
63486350
Succ->removePredecessor(BB);
63496351
if (DTU)
63506352
Updates.push_back({DominatorTree::Delete, BB, Succ});

0 commit comments

Comments
 (0)