42
42
#include " llvm/ADT/SmallPtrSet.h"
43
43
#include " llvm/ADT/SmallVector.h"
44
44
#include " llvm/ADT/Statistic.h"
45
- #include " llvm/Analysis/DomTreeUpdater.h"
46
45
#include " llvm/Analysis/GlobalsModRef.h"
47
46
#include " llvm/IR/BasicBlock.h"
48
47
#include " llvm/IR/CFG.h"
@@ -228,20 +227,20 @@ class ModelledPHI {
228
227
ModelledPHI () = default ;
229
228
230
229
ModelledPHI (const PHINode *PN,
231
- const DenseMap<const BasicBlock *, unsigned > &DFS ) {
230
+ const DenseMap<const BasicBlock *, unsigned > &BlockOrder ) {
232
231
// BasicBlock comes first so we sort by basic block pointer order,
233
232
// then by value pointer order. No need to call `verifyModelledPHI`
234
- // As the Values and Blocks are populated in DFSOrder already .
233
+ // As the Values and Blocks are populated in a deterministic order .
235
234
using OpsType = std::pair<BasicBlock *, Value *>;
236
235
SmallVector<OpsType, 4 > Ops;
237
236
for (unsigned I = 0 , E = PN->getNumIncomingValues (); I != E; ++I)
238
237
Ops.push_back ({PN->getIncomingBlock (I), PN->getIncomingValue (I)});
239
238
240
- auto DFSOrder = [DFS ](OpsType O1, OpsType O2) {
241
- return DFS .lookup (O1.first ) < DFS .lookup (O2.first );
239
+ auto ComesBefore = [BlockOrder ](OpsType O1, OpsType O2) {
240
+ return BlockOrder .lookup (O1.first ) < BlockOrder .lookup (O2.first );
242
241
};
243
- // Sort by DFSNumber to have a deterministic order.
244
- llvm::sort (Ops, DFSOrder );
242
+ // Sort in a deterministic order.
243
+ llvm::sort (Ops, ComesBefore );
245
244
246
245
for (auto &P : Ops) {
247
246
Blocks.push_back (P.first );
@@ -258,13 +257,15 @@ class ModelledPHI {
258
257
return M;
259
258
}
260
259
261
- void verifyModelledPHI (const DenseMap<const BasicBlock *, unsigned > &DFS) {
260
+ void
261
+ verifyModelledPHI (const DenseMap<const BasicBlock *, unsigned > &BlockOrder) {
262
262
assert (Values.size () > 1 && Blocks.size () > 1 &&
263
263
" Modelling PHI with less than 2 values" );
264
- auto DFSOrder = [DFS](const BasicBlock *BB1, const BasicBlock *BB2) {
265
- return DFS.lookup (BB1) < DFS.lookup (BB2);
264
+ auto ComesBefore = [BlockOrder](const BasicBlock *BB1,
265
+ const BasicBlock *BB2) {
266
+ return BlockOrder.lookup (BB1) < BlockOrder.lookup (BB2);
266
267
};
267
- assert (llvm::is_sorted (Blocks, DFSOrder ));
268
+ assert (llvm::is_sorted (Blocks, ComesBefore ));
268
269
int C = 0 ;
269
270
llvm::for_each (Values, [&C, this ](const Value *V) {
270
271
if (!isa<UndefValue>(V)) {
@@ -277,11 +278,11 @@ class ModelledPHI {
277
278
// / Create a PHI from an array of incoming values and incoming blocks.
278
279
ModelledPHI (SmallVectorImpl<Instruction *> &V,
279
280
SmallSetVector<BasicBlock *, 4 > &B,
280
- const DenseMap<const BasicBlock *, unsigned > &DFS ) {
281
- // The order of Values and Blocks are already as per their DFSNumbers .
281
+ const DenseMap<const BasicBlock *, unsigned > &BlockOrder ) {
282
+ // The order of Values and Blocks are already ordered by the caller .
282
283
llvm::copy (V, std::back_inserter (Values));
283
284
llvm::copy (B, std::back_inserter (Blocks));
284
- verifyModelledPHI (DFS );
285
+ verifyModelledPHI (BlockOrder );
285
286
}
286
287
287
288
// / Create a PHI from [I[OpNum] for I in Insts].
@@ -328,7 +329,7 @@ class ModelledPHI {
328
329
329
330
// Hash functor
330
331
unsigned hash () const {
331
- // Is deterministic because Values are saved in DFSOrder .
332
+ // Is deterministic because Values are saved in a specific order .
332
333
return (unsigned )hash_combine_range (Values.begin (), Values.end ());
333
334
}
334
335
@@ -598,7 +599,7 @@ class ValueTable {
598
599
599
600
class GVNSink {
600
601
public:
601
- GVNSink (DominatorTree *DT) : DT(DT ) {}
602
+ GVNSink () {}
602
603
603
604
bool run (Function &F) {
604
605
LLVM_DEBUG (dbgs () << " GVNSink: running on function @" << F.getName ()
@@ -607,13 +608,16 @@ class GVNSink {
607
608
unsigned NumSunk = 0 ;
608
609
ReversePostOrderTraversal<Function*> RPOT (&F);
609
610
VN.setReachableBBs (BasicBlocksSet (RPOT.begin (), RPOT.end ()));
610
- // Populated DFSNumbers ahead of time to avoid updating dominator tree
611
- // when CFG is modified. The DFSNumbers of newly created basic blocks
612
- // are irrelevant because RPOT is also obtained ahead of time and only
613
- // DFSNumbers of original CFG are relevant for sinkable candidates.
611
+ // Populate reverse post-order to order basic blocks in deterministic
612
+ // order. Any arbitrary ordering will work in this case as long as they are
613
+ // deterministic. The node ordering of newly created basic blocks
614
+ // are irrelevant because RPOT(for computing sinkable candidates) is also
615
+ // obtained ahead of time and only their order are relevant for this pass.
616
+ unsigned NodeOrdering = 0 ;
617
+ RPOTOrder[*RPOT.begin ()] = ++NodeOrdering;
614
618
for (auto *BB : RPOT)
615
- if (DT-> getNode (BB))
616
- DFSNumbers [BB] = DT-> getNode (BB)-> getDFSNumIn () ;
619
+ if (! pred_empty (BB))
620
+ RPOTOrder [BB] = ++NodeOrdering ;
617
621
for (auto *N : RPOT)
618
622
NumSunk += sinkBB (N);
619
623
@@ -622,8 +626,7 @@ class GVNSink {
622
626
623
627
private:
624
628
ValueTable VN;
625
- DominatorTree *DT;
626
- DenseMap<const BasicBlock *, unsigned > DFSNumbers;
629
+ DenseMap<const BasicBlock *, unsigned > RPOTOrder;
627
630
628
631
bool shouldAvoidSinkingInstruction (Instruction *I) {
629
632
// These instructions may change or break semantics if moved.
@@ -644,7 +647,7 @@ class GVNSink {
644
647
void analyzeInitialPHIs (BasicBlock *BB, ModelledPHISet &PHIs,
645
648
SmallPtrSetImpl<Value *> &PHIContents) {
646
649
for (PHINode &PN : BB->phis ()) {
647
- auto MPHI = ModelledPHI (&PN, DFSNumbers );
650
+ auto MPHI = ModelledPHI (&PN, RPOTOrder );
648
651
PHIs.insert (MPHI);
649
652
for (auto *V : MPHI.getValues ())
650
653
PHIContents.insert (V);
@@ -732,7 +735,7 @@ GVNSink::analyzeInstructionForSinking(LockstepReverseIterator &LRI,
732
735
}
733
736
734
737
// The sunk instruction's results.
735
- ModelledPHI NewPHI (NewInsts, ActivePreds, DFSNumbers );
738
+ ModelledPHI NewPHI (NewInsts, ActivePreds, RPOTOrder );
736
739
737
740
// Does sinking this instruction render previous PHIs redundant?
738
741
if (NeededPHIs.erase (NewPHI))
@@ -807,8 +810,8 @@ unsigned GVNSink::sinkBB(BasicBlock *BBEnd) {
807
810
BBEnd->printAsOperand (dbgs ()); dbgs () << " \n " );
808
811
SmallVector<BasicBlock *, 4 > Preds;
809
812
for (auto *B : predecessors (BBEnd)) {
810
- // Bailout on malformed CFG where BasicBlock has no predecessor(PR42346).
811
- if (!DFSNumbers .count (B))
813
+ // Bailout on basic blocks without predecessor(PR42346).
814
+ if (!RPOTOrder .count (B))
812
815
return 0 ;
813
816
auto *T = B->getTerminator ();
814
817
if (isa<BranchInst>(T) || isa<SwitchInst>(T))
@@ -818,11 +821,11 @@ unsigned GVNSink::sinkBB(BasicBlock *BBEnd) {
818
821
}
819
822
if (Preds.size () < 2 )
820
823
return 0 ;
821
- auto DFSOrder = [this ](const BasicBlock *BB1, const BasicBlock *BB2) {
822
- return DFSNumbers .lookup (BB1) < DFSNumbers .lookup (BB2);
824
+ auto ComesBefore = [this ](const BasicBlock *BB1, const BasicBlock *BB2) {
825
+ return RPOTOrder .lookup (BB1) < RPOTOrder .lookup (BB2);
823
826
};
824
- // Sort by DFSNumber to have a deterministic order.
825
- llvm::sort (Preds, DFSOrder );
827
+ // Sort in a deterministic order.
828
+ llvm::sort (Preds, ComesBefore );
826
829
827
830
unsigned NumOrigPreds = Preds.size ();
828
831
// We can only sink instructions through unconditional branches.
@@ -859,12 +862,11 @@ unsigned GVNSink::sinkBB(BasicBlock *BBEnd) {
859
862
auto C = Candidates.front ();
860
863
861
864
LLVM_DEBUG (dbgs () << " -- Sinking: " << C << " \n " );
862
- DomTreeUpdater DTU (DT, DomTreeUpdater::UpdateStrategy::Eager);
863
865
BasicBlock *InsertBB = BBEnd;
864
866
if (C.Blocks .size () < NumOrigPreds) {
865
867
LLVM_DEBUG (dbgs () << " -- Splitting edge to " ;
866
868
BBEnd->printAsOperand (dbgs ()); dbgs () << " \n " );
867
- InsertBB = SplitBlockPredecessors (BBEnd, C.Blocks , " .gvnsink.split" , &DTU );
869
+ InsertBB = SplitBlockPredecessors (BBEnd, C.Blocks , " .gvnsink.split" );
868
870
if (!InsertBB) {
869
871
LLVM_DEBUG (dbgs () << " -- FAILED to split edge!\n " );
870
872
// Edge couldn't be split.
@@ -935,13 +937,9 @@ void GVNSink::sinkLastInstruction(ArrayRef<BasicBlock *> Blocks,
935
937
} // end anonymous namespace
936
938
937
939
PreservedAnalyses GVNSinkPass::run (Function &F, FunctionAnalysisManager &AM) {
938
- auto &DT = AM.getResult <DominatorTreeAnalysis>(F);
939
- GVNSink G (&DT);
940
- DT.updateDFSNumbers ();
940
+ GVNSink G;
941
941
if (!G.run (F))
942
942
return PreservedAnalyses::all ();
943
943
944
- PreservedAnalyses PA;
945
- PA.preserve <DominatorTreeAnalysis>();
946
- return PA;
944
+ return PreservedAnalyses::none ();
947
945
}
0 commit comments