Skip to content

Commit 4c51627

Browse files
committed
[VPlan] Use DomTreeUpdater to automatically update DT for vector loop.
Use DTU to queue DominatorTree updates directly when connecting basic blocks during VPlan execution. This simplifies DT updates and also automatically allows updating the DT for the VPlan-native path as additional benefit.
1 parent 1e7d047 commit 4c51627

File tree

4 files changed

+24
-71
lines changed

4 files changed

+24
-71
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10390,15 +10390,9 @@ PreservedAnalyses LoopVectorizePass::run(Function &F,
1039010390
RemoveRedundantDbgInstrs(&BB);
1039110391
}
1039210392

10393-
// We currently do not preserve dominator analyses with outer loop
10394-
// vectorization. Until this is addressed, mark these analyses as preserved
10395-
// only for non-VPlan-native path.
10396-
// TODO: Preserve Dominator analysis for VPlan-native path.
10397-
if (!EnableVPlanNativePath) {
10398-
PA.preserve<DominatorTreeAnalysis>();
10399-
PA.preserve<ScalarEvolutionAnalysis>();
10400-
}
1040110393
PA.preserve<LoopAnalysis>();
10394+
PA.preserve<DominatorTreeAnalysis>();
10395+
PA.preserve<ScalarEvolutionAnalysis>();
1040210396

1040310397
if (Result.MadeCFGChange) {
1040410398
// Making CFG changes likely means a loop got vectorized. Indicate that

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 15 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/ADT/SmallVector.h"
2626
#include "llvm/ADT/StringExtras.h"
2727
#include "llvm/ADT/Twine.h"
28+
#include "llvm/Analysis/DomTreeUpdater.h"
2829
#include "llvm/Analysis/LoopInfo.h"
2930
#include "llvm/IR/BasicBlock.h"
3031
#include "llvm/IR/CFG.h"
@@ -218,9 +219,9 @@ VPTransformState::VPTransformState(ElementCount VF, unsigned UF, LoopInfo *LI,
218219
DominatorTree *DT, IRBuilderBase &Builder,
219220
InnerLoopVectorizer *ILV, VPlan *Plan,
220221
LLVMContext &Ctx)
221-
: VF(VF), UF(UF), LI(LI), DT(DT), Builder(Builder), ILV(ILV), Plan(Plan),
222-
LVer(nullptr),
223-
TypeAnalysis(Plan->getCanonicalIV()->getScalarType(), Ctx) {}
222+
: VF(VF), UF(UF), LI(LI), Builder(Builder), ILV(ILV), Plan(Plan),
223+
LVer(nullptr), TypeAnalysis(Plan->getCanonicalIV()->getScalarType(), Ctx),
224+
DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy) {}
224225

225226
Value *VPTransformState::get(VPValue *Def, const VPIteration &Instance) {
226227
if (Def->isLiveIn())
@@ -399,8 +400,8 @@ void VPTransformState::packScalarIntoVectorValue(VPValue *Def,
399400
set(Def, VectorValue, Instance.Part);
400401
}
401402

402-
BasicBlock *
403-
VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) {
403+
BasicBlock *VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG,
404+
DomTreeUpdater &DTU) {
404405
// BB stands for IR BasicBlocks. VPBB stands for VPlan VPBasicBlocks.
405406
// Pred stands for Predessor. Prev stands for Previous - last visited/created.
406407
BasicBlock *PrevBB = CFG.PrevBB;
@@ -436,6 +437,7 @@ VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) {
436437
"Trying to reset an existing successor block.");
437438
TermBr->setSuccessor(idx, NewBB);
438439
}
440+
DTU.applyUpdates({{DominatorTree::Insert, PredBB, NewBB}});
439441
}
440442
return NewBB;
441443
}
@@ -467,6 +469,7 @@ void VPBasicBlock::execute(VPTransformState *State) {
467469
// The Exit block of a loop is always set to be successor 0 of the Exiting
468470
// block.
469471
cast<BranchInst>(ExitingBB->getTerminator())->setSuccessor(0, NewBB);
472+
State->DTU.applyUpdates({{DominatorTree::Insert, ExitingBB, NewBB}});
470473
} else if (PrevVPBB && /* A */
471474
!((SingleHPred = getSingleHierarchicalPredecessor()) &&
472475
SingleHPred->getExitingBasicBlock() == PrevVPBB &&
@@ -483,7 +486,7 @@ void VPBasicBlock::execute(VPTransformState *State) {
483486
// is the exiting VPBB of this region from a previous instance, or the
484487
// predecessor of this region.
485488

486-
NewBB = createEmptyBasicBlock(State->CFG);
489+
NewBB = createEmptyBasicBlock(State->CFG, State->DTU);
487490
State->Builder.SetInsertPoint(NewBB);
488491
// Temporarily terminate with unreachable until CFG is rewired.
489492
UnreachableInst *Terminator = State->Builder.CreateUnreachable();
@@ -829,6 +832,9 @@ void VPlan::execute(VPTransformState *State) {
829832
BasicBlock *VectorPreHeader = State->CFG.PrevBB;
830833
State->Builder.SetInsertPoint(VectorPreHeader->getTerminator());
831834

835+
State->DTU.applyUpdates(
836+
{{DominatorTree::Delete, VectorPreHeader, State->CFG.ExitBB}});
837+
832838
// Generate code in the loop pre-header and body.
833839
for (VPBlockBase *Block : vp_depth_first_shallow(Entry))
834840
Block->execute(State);
@@ -891,13 +897,9 @@ void VPlan::execute(VPTransformState *State) {
891897
}
892898
}
893899

894-
// We do not attempt to preserve DT for outer loop vectorization currently.
895-
if (!EnableVPlanNativePath) {
896-
BasicBlock *VectorHeaderBB = State->CFG.VPBB2IRBB[Header];
897-
State->DT->addNewBlock(VectorHeaderBB, VectorPreHeader);
898-
updateDominatorTree(State->DT, VectorHeaderBB, VectorLatchBB,
899-
State->CFG.ExitBB);
900-
}
900+
State->DTU.flush();
901+
assert(
902+
State->DTU.getDomTree().verify(DominatorTree::VerificationLevel::Fast));
901903
}
902904

903905
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
@@ -995,44 +997,6 @@ void VPlan::addLiveOut(PHINode *PN, VPValue *V) {
995997
LiveOuts.insert({PN, new VPLiveOut(PN, V)});
996998
}
997999

998-
void VPlan::updateDominatorTree(DominatorTree *DT, BasicBlock *LoopHeaderBB,
999-
BasicBlock *LoopLatchBB,
1000-
BasicBlock *LoopExitBB) {
1001-
// The vector body may be more than a single basic-block by this point.
1002-
// Update the dominator tree information inside the vector body by propagating
1003-
// it from header to latch, expecting only triangular control-flow, if any.
1004-
BasicBlock *PostDomSucc = nullptr;
1005-
for (auto *BB = LoopHeaderBB; BB != LoopLatchBB; BB = PostDomSucc) {
1006-
// Get the list of successors of this block.
1007-
std::vector<BasicBlock *> Succs(succ_begin(BB), succ_end(BB));
1008-
assert(Succs.size() <= 2 &&
1009-
"Basic block in vector loop has more than 2 successors.");
1010-
PostDomSucc = Succs[0];
1011-
if (Succs.size() == 1) {
1012-
assert(PostDomSucc->getSinglePredecessor() &&
1013-
"PostDom successor has more than one predecessor.");
1014-
DT->addNewBlock(PostDomSucc, BB);
1015-
continue;
1016-
}
1017-
BasicBlock *InterimSucc = Succs[1];
1018-
if (PostDomSucc->getSingleSuccessor() == InterimSucc) {
1019-
PostDomSucc = Succs[1];
1020-
InterimSucc = Succs[0];
1021-
}
1022-
assert(InterimSucc->getSingleSuccessor() == PostDomSucc &&
1023-
"One successor of a basic block does not lead to the other.");
1024-
assert(InterimSucc->getSinglePredecessor() &&
1025-
"Interim successor has more than one predecessor.");
1026-
assert(PostDomSucc->hasNPredecessors(2) &&
1027-
"PostDom successor has more than two predecessors.");
1028-
DT->addNewBlock(InterimSucc, BB);
1029-
DT->addNewBlock(PostDomSucc, BB);
1030-
}
1031-
// Latch block is a new dominator for the loop exit.
1032-
DT->changeImmediateDominator(LoopExitBB, LoopLatchBB);
1033-
assert(DT->verify(DominatorTree::VerificationLevel::Fast));
1034-
}
1035-
10361000
static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry,
10371001
DenseMap<VPValue *, VPValue *> &Old2NewVPValues) {
10381002
// Update the operands of all cloned recipes starting at NewEntry. This

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "llvm/ADT/Twine.h"
3636
#include "llvm/ADT/ilist.h"
3737
#include "llvm/ADT/ilist_node.h"
38+
#include "llvm/Analysis/DomTreeUpdater.h"
3839
#include "llvm/Analysis/IVDescriptors.h"
3940
#include "llvm/Analysis/LoopInfo.h"
4041
#include "llvm/Analysis/VectorUtils.h"
@@ -382,9 +383,6 @@ struct VPTransformState {
382383
/// Hold a pointer to LoopInfo to register new basic blocks in the loop.
383384
LoopInfo *LI;
384385

385-
/// Hold a pointer to Dominator Tree to register new basic blocks in the loop.
386-
DominatorTree *DT;
387-
388386
/// Hold a reference to the IRBuilder used to generate output IR code.
389387
IRBuilderBase &Builder;
390388

@@ -410,6 +408,9 @@ struct VPTransformState {
410408

411409
/// VPlan-based type analysis.
412410
VPTypeAnalysis TypeAnalysis;
411+
412+
/// Updater for the DominatorTree.
413+
DomTreeUpdater DTU;
413414
};
414415

415416
/// VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
@@ -2946,7 +2947,8 @@ class VPBasicBlock : public VPBlockBase {
29462947
private:
29472948
/// Create an IR BasicBlock to hold the output instructions generated by this
29482949
/// VPBasicBlock, and return it. Update the CFGState accordingly.
2949-
BasicBlock *createEmptyBasicBlock(VPTransformState::CFGState &CFG);
2950+
BasicBlock *createEmptyBasicBlock(VPTransformState::CFGState &CFG,
2951+
DomTreeUpdater &DTU);
29502952
};
29512953

29522954
/// VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks
@@ -3289,13 +3291,6 @@ class VPlan {
32893291
/// Clone the current VPlan, update all VPValues of the new VPlan and cloned
32903292
/// recipes to refer to the clones, and return it.
32913293
VPlan *duplicate();
3292-
3293-
private:
3294-
/// Add to the given dominator tree the header block and every new basic block
3295-
/// that was created between it and the latch block, inclusive.
3296-
static void updateDominatorTree(DominatorTree *DT, BasicBlock *LoopHeaderBB,
3297-
BasicBlock *LoopLatchBB,
3298-
BasicBlock *LoopExitBB);
32993294
};
33003295

33013296
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

llvm/test/Transforms/LoopVectorize/outer_loop_test1.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
; }
1414
; }
1515
;
16-
; RUN: opt -S -passes=loop-vectorize -enable-vplan-native-path -verify-loop-info < %s | FileCheck %s
16+
; RUN: opt -S -passes=loop-vectorize -enable-vplan-native-path -verify-loop-info -verify-dom-info < %s | FileCheck %s
1717
; CHECK-LABEL: vector.ph:
1818
; CHECK: %[[SplatVal:.*]] = insertelement <4 x i32> poison, i32 %n, i64 0
1919
; CHECK: %[[Splat:.*]] = shufflevector <4 x i32> %[[SplatVal]], <4 x i32> poison, <4 x i32> zeroinitializer

0 commit comments

Comments
 (0)