|
25 | 25 | #include "llvm/ADT/SmallVector.h"
|
26 | 26 | #include "llvm/ADT/StringExtras.h"
|
27 | 27 | #include "llvm/ADT/Twine.h"
|
| 28 | +#include "llvm/Analysis/DomTreeUpdater.h" |
28 | 29 | #include "llvm/Analysis/LoopInfo.h"
|
29 | 30 | #include "llvm/IR/BasicBlock.h"
|
30 | 31 | #include "llvm/IR/CFG.h"
|
@@ -218,7 +219,7 @@ VPTransformState::VPTransformState(ElementCount VF, unsigned UF, LoopInfo *LI,
|
218 | 219 | DominatorTree *DT, IRBuilderBase &Builder,
|
219 | 220 | InnerLoopVectorizer *ILV, VPlan *Plan,
|
220 | 221 | LLVMContext &Ctx)
|
221 |
| - : VF(VF), UF(UF), LI(LI), DT(DT), Builder(Builder), ILV(ILV), Plan(Plan), |
| 222 | + : VF(VF), UF(UF), CFG(DT), LI(LI), Builder(Builder), ILV(ILV), Plan(Plan), |
222 | 223 | LVer(nullptr),
|
223 | 224 | TypeAnalysis(Plan->getCanonicalIV()->getScalarType(), Ctx) {}
|
224 | 225 |
|
@@ -436,6 +437,7 @@ VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) {
|
436 | 437 | "Trying to reset an existing successor block.");
|
437 | 438 | TermBr->setSuccessor(idx, NewBB);
|
438 | 439 | }
|
| 440 | + CFG.DTU.applyUpdates({{DominatorTree::Insert, PredBB, NewBB}}); |
439 | 441 | }
|
440 | 442 | return NewBB;
|
441 | 443 | }
|
@@ -467,6 +469,7 @@ void VPBasicBlock::execute(VPTransformState *State) {
|
467 | 469 | // The Exit block of a loop is always set to be successor 0 of the Exiting
|
468 | 470 | // block.
|
469 | 471 | cast<BranchInst>(ExitingBB->getTerminator())->setSuccessor(0, NewBB);
|
| 472 | + State->CFG.DTU.applyUpdates({{DominatorTree::Insert, ExitingBB, NewBB}}); |
470 | 473 | } else if (PrevVPBB && /* A */
|
471 | 474 | !((SingleHPred = getSingleHierarchicalPredecessor()) &&
|
472 | 475 | SingleHPred->getExitingBasicBlock() == PrevVPBB &&
|
@@ -829,6 +832,11 @@ void VPlan::execute(VPTransformState *State) {
|
829 | 832 | BasicBlock *VectorPreHeader = State->CFG.PrevBB;
|
830 | 833 | State->Builder.SetInsertPoint(VectorPreHeader->getTerminator());
|
831 | 834 |
|
| 835 | + // Disconnect VectorPreHeader from ExitBB in both the CFG and DT. |
| 836 | + cast<BranchInst>(VectorPreHeader->getTerminator())->setSuccessor(0, nullptr); |
| 837 | + State->CFG.DTU.applyUpdates( |
| 838 | + {{DominatorTree::Delete, VectorPreHeader, State->CFG.ExitBB}}); |
| 839 | + |
832 | 840 | // Generate code in the loop pre-header and body.
|
833 | 841 | for (VPBlockBase *Block : vp_depth_first_shallow(Entry))
|
834 | 842 | Block->execute(State);
|
@@ -891,13 +899,10 @@ void VPlan::execute(VPTransformState *State) {
|
891 | 899 | }
|
892 | 900 | }
|
893 | 901 |
|
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 |
| - } |
| 902 | + State->CFG.DTU.flush(); |
| 903 | + // DT is currently updated for non-native path only. |
| 904 | + assert(EnableVPlanNativePath || State->CFG.DTU.getDomTree().verify( |
| 905 | + DominatorTree::VerificationLevel::Fast)); |
901 | 906 | }
|
902 | 907 |
|
903 | 908 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
@@ -995,44 +1000,6 @@ void VPlan::addLiveOut(PHINode *PN, VPValue *V) {
|
995 | 1000 | LiveOuts.insert({PN, new VPLiveOut(PN, V)});
|
996 | 1001 | }
|
997 | 1002 |
|
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 |
| - |
1036 | 1003 | static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry,
|
1037 | 1004 | DenseMap<VPValue *, VPValue *> &Old2NewVPValues) {
|
1038 | 1005 | // Update the operands of all cloned recipes starting at NewEntry. This
|
|
0 commit comments