Skip to content

Commit e313e61

Browse files
committed
Fix issues with DT update, use DFSNumbers
1 parent 057b4e0 commit e313e61

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

llvm/lib/Transforms/Scalar/GVNSink.cpp

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "llvm/ADT/SmallPtrSet.h"
4343
#include "llvm/ADT/SmallVector.h"
4444
#include "llvm/ADT/Statistic.h"
45+
#include "llvm/Analysis/DomTreeUpdater.h"
4546
#include "llvm/Analysis/GlobalsModRef.h"
4647
#include "llvm/IR/BasicBlock.h"
4748
#include "llvm/IR/CFG.h"
@@ -228,14 +229,17 @@ class ModelledPHI {
228229
ModelledPHI() = default;
229230

230231
ModelledPHI(const PHINode *PN, DominatorTree *DT) : DT(DT) {
231-
// BasicBlock comes first so we sort by basic block pointer order, then by value pointer order.
232+
// BasicBlock comes first so we sort by basic block pointer order,
233+
// then by value pointer order. No need to call `verifyModelledPHI`
234+
// As the Values and Blocks are populated in DFSOrder already.
232235
using OpsType = std::pair<BasicBlock *, Value *>;
233236
SmallVector<OpsType, 4> Ops;
234237
for (unsigned I = 0, E = PN->getNumIncomingValues(); I != E; ++I)
235238
Ops.push_back({PN->getIncomingBlock(I), PN->getIncomingValue(I)});
236239

237240
auto DFSOrder = [DT](OpsType O1, OpsType O2) {
238-
return DT->getNode(O1.first) < DT->getNode(O2.first);
241+
return DT->getNode(O1.first)->getDFSNumIn() <
242+
DT->getNode(O2.first)->getDFSNumIn();
239243
};
240244
// Sort by DFSNumber to have a deterministic order.
241245
llvm::sort(Ops, DFSOrder);
@@ -244,7 +248,6 @@ class ModelledPHI {
244248
Blocks.push_back(P.first);
245249
Values.push_back(P.second);
246250
}
247-
verifyModelledPHI();
248251
}
249252

250253
/// Create a dummy ModelledPHI that will compare unequal to any other ModelledPHI
@@ -260,13 +263,16 @@ class ModelledPHI {
260263
assert(Values.size() > 1 && Blocks.size() > 1 &&
261264
"Modelling PHI with less than 2 values");
262265
auto DFSOrder = [this](const BasicBlock *BB1, const BasicBlock *BB2) {
263-
return this->DT->getNode(BB1) < this->DT->getNode(BB2);
266+
return DT->getNode(BB1)->getDFSNumIn() < DT->getNode(BB2)->getDFSNumIn();
264267
};
265268
assert(llvm::is_sorted(Blocks, DFSOrder));
266269
int C = 0;
267270
llvm::for_each(Values, [&C, this](const Value *V) {
268-
const Instruction *I = cast<Instruction>(V);
269-
assert(I->getParent() == this->Blocks[C++]);
271+
if (!isa<UndefValue>(V)) {
272+
const Instruction *I = cast<Instruction>(V);
273+
assert(I->getParent() == this->Blocks[C]);
274+
}
275+
C++;
270276
});
271277
}
272278
/// Create a PHI from an array of incoming values and incoming blocks.
@@ -280,13 +286,13 @@ class ModelledPHI {
280286
}
281287

282288
/// Create a PHI from [I[OpNum] for I in Insts].
289+
/// TODO: Figure out a way to verifyModelledPHI in this constructor.
283290
ModelledPHI(ArrayRef<Instruction *> Insts, unsigned OpNum,
284291
SmallSetVector<BasicBlock *, 4> &B, DominatorTree *DT)
285292
: DT(DT) {
286293
llvm::copy(B, std::back_inserter(Blocks));
287294
for (auto *I : Insts)
288295
Values.push_back(I->getOperand(OpNum));
289-
verifyModelledPHI();
290296
}
291297

292298
/// Restrict the PHI's contents down to only \c NewBlocks.
@@ -795,6 +801,9 @@ unsigned GVNSink::sinkBB(BasicBlock *BBEnd) {
795801
BBEnd->printAsOperand(dbgs()); dbgs() << "\n");
796802
SmallVector<BasicBlock *, 4> Preds;
797803
for (auto *B : predecessors(BBEnd)) {
804+
// Bailout on malformed CFG where BasicBlock has no predecessor(PR42346).
805+
if (!DT->getNode(B))
806+
return 0;
798807
auto *T = B->getTerminator();
799808
if (isa<BranchInst>(T) || isa<SwitchInst>(T))
800809
Preds.push_back(B);
@@ -804,7 +813,7 @@ unsigned GVNSink::sinkBB(BasicBlock *BBEnd) {
804813
if (Preds.size() < 2)
805814
return 0;
806815
auto DFSOrder = [this](const BasicBlock *BB1, const BasicBlock *BB2) {
807-
return this->DT->getNode(BB1) < this->DT->getNode(BB2);
816+
return DT->getNode(BB1)->getDFSNumIn() < DT->getNode(BB2)->getDFSNumIn();
808817
};
809818
// Sort by DFSNumber to have a deterministic order.
810819
llvm::sort(Preds, DFSOrder);
@@ -844,11 +853,12 @@ unsigned GVNSink::sinkBB(BasicBlock *BBEnd) {
844853
auto C = Candidates.front();
845854

846855
LLVM_DEBUG(dbgs() << " -- Sinking: " << C << "\n");
856+
DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
847857
BasicBlock *InsertBB = BBEnd;
848858
if (C.Blocks.size() < NumOrigPreds) {
849859
LLVM_DEBUG(dbgs() << " -- Splitting edge to ";
850860
BBEnd->printAsOperand(dbgs()); dbgs() << "\n");
851-
InsertBB = SplitBlockPredecessors(BBEnd, C.Blocks, ".gvnsink.split");
861+
InsertBB = SplitBlockPredecessors(BBEnd, C.Blocks, ".gvnsink.split", &DTU);
852862
if (!InsertBB) {
853863
LLVM_DEBUG(dbgs() << " -- FAILED to split edge!\n");
854864
// Edge couldn't be split.
@@ -921,10 +931,11 @@ void GVNSink::sinkLastInstruction(ArrayRef<BasicBlock *> Blocks,
921931
PreservedAnalyses GVNSinkPass::run(Function &F, FunctionAnalysisManager &AM) {
922932
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
923933
GVNSink G(&DT);
934+
DT.updateDFSNumbers();
924935
if (!G.run(F))
925936
return PreservedAnalyses::all();
926937

927-
// PHI nodes get inserted which haven't been added to the Dominator Tree.
928-
// FIXME: Update DominatorTree to account for sunk instructions.
929-
return PreservedAnalyses::none();
938+
PreservedAnalyses PA;
939+
PA.preserve<DominatorTreeAnalysis>();
940+
return PA;
930941
}

0 commit comments

Comments
 (0)