173471bf0Spatrick //===------- LoopBoundSplit.cpp - Split Loop Bound --------------*- C++ -*-===//
273471bf0Spatrick //
373471bf0Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
473471bf0Spatrick // See https://llvm.org/LICENSE.txt for license information.
573471bf0Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
673471bf0Spatrick //
773471bf0Spatrick //===----------------------------------------------------------------------===//
873471bf0Spatrick
973471bf0Spatrick #include "llvm/Transforms/Scalar/LoopBoundSplit.h"
10*d415bd75Srobert #include "llvm/ADT/Sequence.h"
1173471bf0Spatrick #include "llvm/Analysis/LoopAnalysisManager.h"
1273471bf0Spatrick #include "llvm/Analysis/LoopInfo.h"
1373471bf0Spatrick #include "llvm/Analysis/ScalarEvolution.h"
1473471bf0Spatrick #include "llvm/Analysis/ScalarEvolutionExpressions.h"
1573471bf0Spatrick #include "llvm/IR/PatternMatch.h"
16*d415bd75Srobert #include "llvm/Transforms/Scalar/LoopPassManager.h"
1773471bf0Spatrick #include "llvm/Transforms/Utils/BasicBlockUtils.h"
1873471bf0Spatrick #include "llvm/Transforms/Utils/Cloning.h"
1973471bf0Spatrick #include "llvm/Transforms/Utils/LoopSimplify.h"
2073471bf0Spatrick #include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
2173471bf0Spatrick
2273471bf0Spatrick #define DEBUG_TYPE "loop-bound-split"
2373471bf0Spatrick
2473471bf0Spatrick namespace llvm {
2573471bf0Spatrick
2673471bf0Spatrick using namespace PatternMatch;
2773471bf0Spatrick
2873471bf0Spatrick namespace {
2973471bf0Spatrick struct ConditionInfo {
3073471bf0Spatrick /// Branch instruction with this condition
31*d415bd75Srobert BranchInst *BI = nullptr;
3273471bf0Spatrick /// ICmp instruction with this condition
33*d415bd75Srobert ICmpInst *ICmp = nullptr;
3473471bf0Spatrick /// Preciate info
35*d415bd75Srobert ICmpInst::Predicate Pred = ICmpInst::BAD_ICMP_PREDICATE;
3673471bf0Spatrick /// AddRec llvm value
37*d415bd75Srobert Value *AddRecValue = nullptr;
38*d415bd75Srobert /// Non PHI AddRec llvm value
39*d415bd75Srobert Value *NonPHIAddRecValue;
4073471bf0Spatrick /// Bound llvm value
41*d415bd75Srobert Value *BoundValue = nullptr;
4273471bf0Spatrick /// AddRec SCEV
43*d415bd75Srobert const SCEVAddRecExpr *AddRecSCEV = nullptr;
4473471bf0Spatrick /// Bound SCEV
45*d415bd75Srobert const SCEV *BoundSCEV = nullptr;
4673471bf0Spatrick
47*d415bd75Srobert ConditionInfo() = default;
4873471bf0Spatrick };
4973471bf0Spatrick } // namespace
5073471bf0Spatrick
analyzeICmp(ScalarEvolution & SE,ICmpInst * ICmp,ConditionInfo & Cond,const Loop & L)5173471bf0Spatrick static void analyzeICmp(ScalarEvolution &SE, ICmpInst *ICmp,
52*d415bd75Srobert ConditionInfo &Cond, const Loop &L) {
5373471bf0Spatrick Cond.ICmp = ICmp;
5473471bf0Spatrick if (match(ICmp, m_ICmp(Cond.Pred, m_Value(Cond.AddRecValue),
5573471bf0Spatrick m_Value(Cond.BoundValue)))) {
56*d415bd75Srobert const SCEV *AddRecSCEV = SE.getSCEV(Cond.AddRecValue);
57*d415bd75Srobert const SCEV *BoundSCEV = SE.getSCEV(Cond.BoundValue);
58*d415bd75Srobert const SCEVAddRecExpr *LHSAddRecSCEV = dyn_cast<SCEVAddRecExpr>(AddRecSCEV);
59*d415bd75Srobert const SCEVAddRecExpr *RHSAddRecSCEV = dyn_cast<SCEVAddRecExpr>(BoundSCEV);
6073471bf0Spatrick // Locate AddRec in LHSSCEV and Bound in RHSSCEV.
61*d415bd75Srobert if (!LHSAddRecSCEV && RHSAddRecSCEV) {
6273471bf0Spatrick std::swap(Cond.AddRecValue, Cond.BoundValue);
63*d415bd75Srobert std::swap(AddRecSCEV, BoundSCEV);
6473471bf0Spatrick Cond.Pred = ICmpInst::getSwappedPredicate(Cond.Pred);
6573471bf0Spatrick }
66*d415bd75Srobert
67*d415bd75Srobert Cond.AddRecSCEV = dyn_cast<SCEVAddRecExpr>(AddRecSCEV);
68*d415bd75Srobert Cond.BoundSCEV = BoundSCEV;
69*d415bd75Srobert Cond.NonPHIAddRecValue = Cond.AddRecValue;
70*d415bd75Srobert
71*d415bd75Srobert // If the Cond.AddRecValue is PHI node, update Cond.NonPHIAddRecValue with
72*d415bd75Srobert // value from backedge.
73*d415bd75Srobert if (Cond.AddRecSCEV && isa<PHINode>(Cond.AddRecValue)) {
74*d415bd75Srobert PHINode *PN = cast<PHINode>(Cond.AddRecValue);
75*d415bd75Srobert Cond.NonPHIAddRecValue = PN->getIncomingValueForBlock(L.getLoopLatch());
76*d415bd75Srobert }
7773471bf0Spatrick }
7873471bf0Spatrick }
7973471bf0Spatrick
calculateUpperBound(const Loop & L,ScalarEvolution & SE,ConditionInfo & Cond,bool IsExitCond)8073471bf0Spatrick static bool calculateUpperBound(const Loop &L, ScalarEvolution &SE,
8173471bf0Spatrick ConditionInfo &Cond, bool IsExitCond) {
8273471bf0Spatrick if (IsExitCond) {
8373471bf0Spatrick const SCEV *ExitCount = SE.getExitCount(&L, Cond.ICmp->getParent());
8473471bf0Spatrick if (isa<SCEVCouldNotCompute>(ExitCount))
8573471bf0Spatrick return false;
8673471bf0Spatrick
8773471bf0Spatrick Cond.BoundSCEV = ExitCount;
8873471bf0Spatrick return true;
8973471bf0Spatrick }
9073471bf0Spatrick
9173471bf0Spatrick // For non-exit condtion, if pred is LT, keep existing bound.
9273471bf0Spatrick if (Cond.Pred == ICmpInst::ICMP_SLT || Cond.Pred == ICmpInst::ICMP_ULT)
9373471bf0Spatrick return true;
9473471bf0Spatrick
9573471bf0Spatrick // For non-exit condition, if pre is LE, try to convert it to LT.
9673471bf0Spatrick // Range Range
9773471bf0Spatrick // AddRec <= Bound --> AddRec < Bound + 1
9873471bf0Spatrick if (Cond.Pred != ICmpInst::ICMP_ULE && Cond.Pred != ICmpInst::ICMP_SLE)
9973471bf0Spatrick return false;
10073471bf0Spatrick
10173471bf0Spatrick if (IntegerType *BoundSCEVIntType =
10273471bf0Spatrick dyn_cast<IntegerType>(Cond.BoundSCEV->getType())) {
10373471bf0Spatrick unsigned BitWidth = BoundSCEVIntType->getBitWidth();
10473471bf0Spatrick APInt Max = ICmpInst::isSigned(Cond.Pred)
10573471bf0Spatrick ? APInt::getSignedMaxValue(BitWidth)
10673471bf0Spatrick : APInt::getMaxValue(BitWidth);
10773471bf0Spatrick const SCEV *MaxSCEV = SE.getConstant(Max);
10873471bf0Spatrick // Check Bound < INT_MAX
10973471bf0Spatrick ICmpInst::Predicate Pred =
11073471bf0Spatrick ICmpInst::isSigned(Cond.Pred) ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
11173471bf0Spatrick if (SE.isKnownPredicate(Pred, Cond.BoundSCEV, MaxSCEV)) {
11273471bf0Spatrick const SCEV *BoundPlusOneSCEV =
11373471bf0Spatrick SE.getAddExpr(Cond.BoundSCEV, SE.getOne(BoundSCEVIntType));
11473471bf0Spatrick Cond.BoundSCEV = BoundPlusOneSCEV;
11573471bf0Spatrick Cond.Pred = Pred;
11673471bf0Spatrick return true;
11773471bf0Spatrick }
11873471bf0Spatrick }
11973471bf0Spatrick
12073471bf0Spatrick // ToDo: Support ICMP_NE/EQ.
12173471bf0Spatrick
12273471bf0Spatrick return false;
12373471bf0Spatrick }
12473471bf0Spatrick
hasProcessableCondition(const Loop & L,ScalarEvolution & SE,ICmpInst * ICmp,ConditionInfo & Cond,bool IsExitCond)12573471bf0Spatrick static bool hasProcessableCondition(const Loop &L, ScalarEvolution &SE,
12673471bf0Spatrick ICmpInst *ICmp, ConditionInfo &Cond,
12773471bf0Spatrick bool IsExitCond) {
128*d415bd75Srobert analyzeICmp(SE, ICmp, Cond, L);
12973471bf0Spatrick
13073471bf0Spatrick // The BoundSCEV should be evaluated at loop entry.
13173471bf0Spatrick if (!SE.isAvailableAtLoopEntry(Cond.BoundSCEV, &L))
13273471bf0Spatrick return false;
13373471bf0Spatrick
13473471bf0Spatrick // Allowed AddRec as induction variable.
135*d415bd75Srobert if (!Cond.AddRecSCEV)
13673471bf0Spatrick return false;
13773471bf0Spatrick
138*d415bd75Srobert if (!Cond.AddRecSCEV->isAffine())
13973471bf0Spatrick return false;
14073471bf0Spatrick
141*d415bd75Srobert const SCEV *StepRecSCEV = Cond.AddRecSCEV->getStepRecurrence(SE);
14273471bf0Spatrick // Allowed constant step.
14373471bf0Spatrick if (!isa<SCEVConstant>(StepRecSCEV))
14473471bf0Spatrick return false;
14573471bf0Spatrick
14673471bf0Spatrick ConstantInt *StepCI = cast<SCEVConstant>(StepRecSCEV)->getValue();
14773471bf0Spatrick // Allowed positive step for now.
14873471bf0Spatrick // TODO: Support negative step.
14973471bf0Spatrick if (StepCI->isNegative() || StepCI->isZero())
15073471bf0Spatrick return false;
15173471bf0Spatrick
15273471bf0Spatrick // Calculate upper bound.
15373471bf0Spatrick if (!calculateUpperBound(L, SE, Cond, IsExitCond))
15473471bf0Spatrick return false;
15573471bf0Spatrick
15673471bf0Spatrick return true;
15773471bf0Spatrick }
15873471bf0Spatrick
isProcessableCondBI(const ScalarEvolution & SE,const BranchInst * BI)15973471bf0Spatrick static bool isProcessableCondBI(const ScalarEvolution &SE,
16073471bf0Spatrick const BranchInst *BI) {
16173471bf0Spatrick BasicBlock *TrueSucc = nullptr;
16273471bf0Spatrick BasicBlock *FalseSucc = nullptr;
16373471bf0Spatrick ICmpInst::Predicate Pred;
16473471bf0Spatrick Value *LHS, *RHS;
16573471bf0Spatrick if (!match(BI, m_Br(m_ICmp(Pred, m_Value(LHS), m_Value(RHS)),
16673471bf0Spatrick m_BasicBlock(TrueSucc), m_BasicBlock(FalseSucc))))
16773471bf0Spatrick return false;
16873471bf0Spatrick
16973471bf0Spatrick if (!SE.isSCEVable(LHS->getType()))
17073471bf0Spatrick return false;
17173471bf0Spatrick assert(SE.isSCEVable(RHS->getType()) && "Expected RHS's type is SCEVable");
17273471bf0Spatrick
17373471bf0Spatrick if (TrueSucc == FalseSucc)
17473471bf0Spatrick return false;
17573471bf0Spatrick
17673471bf0Spatrick return true;
17773471bf0Spatrick }
17873471bf0Spatrick
canSplitLoopBound(const Loop & L,const DominatorTree & DT,ScalarEvolution & SE,ConditionInfo & Cond)17973471bf0Spatrick static bool canSplitLoopBound(const Loop &L, const DominatorTree &DT,
18073471bf0Spatrick ScalarEvolution &SE, ConditionInfo &Cond) {
18173471bf0Spatrick // Skip function with optsize.
18273471bf0Spatrick if (L.getHeader()->getParent()->hasOptSize())
18373471bf0Spatrick return false;
18473471bf0Spatrick
18573471bf0Spatrick // Split only innermost loop.
18673471bf0Spatrick if (!L.isInnermost())
18773471bf0Spatrick return false;
18873471bf0Spatrick
18973471bf0Spatrick // Check loop is in simplified form.
19073471bf0Spatrick if (!L.isLoopSimplifyForm())
19173471bf0Spatrick return false;
19273471bf0Spatrick
19373471bf0Spatrick // Check loop is in LCSSA form.
19473471bf0Spatrick if (!L.isLCSSAForm(DT))
19573471bf0Spatrick return false;
19673471bf0Spatrick
19773471bf0Spatrick // Skip loop that cannot be cloned.
19873471bf0Spatrick if (!L.isSafeToClone())
19973471bf0Spatrick return false;
20073471bf0Spatrick
20173471bf0Spatrick BasicBlock *ExitingBB = L.getExitingBlock();
20273471bf0Spatrick // Assumed only one exiting block.
20373471bf0Spatrick if (!ExitingBB)
20473471bf0Spatrick return false;
20573471bf0Spatrick
20673471bf0Spatrick BranchInst *ExitingBI = dyn_cast<BranchInst>(ExitingBB->getTerminator());
20773471bf0Spatrick if (!ExitingBI)
20873471bf0Spatrick return false;
20973471bf0Spatrick
21073471bf0Spatrick // Allowed only conditional branch with ICmp.
21173471bf0Spatrick if (!isProcessableCondBI(SE, ExitingBI))
21273471bf0Spatrick return false;
21373471bf0Spatrick
21473471bf0Spatrick // Check the condition is processable.
21573471bf0Spatrick ICmpInst *ICmp = cast<ICmpInst>(ExitingBI->getCondition());
21673471bf0Spatrick if (!hasProcessableCondition(L, SE, ICmp, Cond, /*IsExitCond*/ true))
21773471bf0Spatrick return false;
21873471bf0Spatrick
21973471bf0Spatrick Cond.BI = ExitingBI;
22073471bf0Spatrick return true;
22173471bf0Spatrick }
22273471bf0Spatrick
isProfitableToTransform(const Loop & L,const BranchInst * BI)22373471bf0Spatrick static bool isProfitableToTransform(const Loop &L, const BranchInst *BI) {
22473471bf0Spatrick // If the conditional branch splits a loop into two halves, we could
22573471bf0Spatrick // generally say it is profitable.
22673471bf0Spatrick //
22773471bf0Spatrick // ToDo: Add more profitable cases here.
22873471bf0Spatrick
22973471bf0Spatrick // Check this branch causes diamond CFG.
23073471bf0Spatrick BasicBlock *Succ0 = BI->getSuccessor(0);
23173471bf0Spatrick BasicBlock *Succ1 = BI->getSuccessor(1);
23273471bf0Spatrick
23373471bf0Spatrick BasicBlock *Succ0Succ = Succ0->getSingleSuccessor();
23473471bf0Spatrick BasicBlock *Succ1Succ = Succ1->getSingleSuccessor();
23573471bf0Spatrick if (!Succ0Succ || !Succ1Succ || Succ0Succ != Succ1Succ)
23673471bf0Spatrick return false;
23773471bf0Spatrick
23873471bf0Spatrick // ToDo: Calculate each successor's instruction cost.
23973471bf0Spatrick
24073471bf0Spatrick return true;
24173471bf0Spatrick }
24273471bf0Spatrick
findSplitCandidate(const Loop & L,ScalarEvolution & SE,ConditionInfo & ExitingCond,ConditionInfo & SplitCandidateCond)24373471bf0Spatrick static BranchInst *findSplitCandidate(const Loop &L, ScalarEvolution &SE,
24473471bf0Spatrick ConditionInfo &ExitingCond,
24573471bf0Spatrick ConditionInfo &SplitCandidateCond) {
24673471bf0Spatrick for (auto *BB : L.blocks()) {
24773471bf0Spatrick // Skip condition of backedge.
24873471bf0Spatrick if (L.getLoopLatch() == BB)
24973471bf0Spatrick continue;
25073471bf0Spatrick
25173471bf0Spatrick auto *BI = dyn_cast<BranchInst>(BB->getTerminator());
25273471bf0Spatrick if (!BI)
25373471bf0Spatrick continue;
25473471bf0Spatrick
25573471bf0Spatrick // Check conditional branch with ICmp.
25673471bf0Spatrick if (!isProcessableCondBI(SE, BI))
25773471bf0Spatrick continue;
25873471bf0Spatrick
25973471bf0Spatrick // Skip loop invariant condition.
26073471bf0Spatrick if (L.isLoopInvariant(BI->getCondition()))
26173471bf0Spatrick continue;
26273471bf0Spatrick
26373471bf0Spatrick // Check the condition is processable.
26473471bf0Spatrick ICmpInst *ICmp = cast<ICmpInst>(BI->getCondition());
26573471bf0Spatrick if (!hasProcessableCondition(L, SE, ICmp, SplitCandidateCond,
26673471bf0Spatrick /*IsExitCond*/ false))
26773471bf0Spatrick continue;
26873471bf0Spatrick
26973471bf0Spatrick if (ExitingCond.BoundSCEV->getType() !=
27073471bf0Spatrick SplitCandidateCond.BoundSCEV->getType())
27173471bf0Spatrick continue;
27273471bf0Spatrick
273*d415bd75Srobert // After transformation, we assume the split condition of the pre-loop is
274*d415bd75Srobert // always true. In order to guarantee it, we need to check the start value
275*d415bd75Srobert // of the split cond AddRec satisfies the split condition.
276*d415bd75Srobert if (!SE.isLoopEntryGuardedByCond(&L, SplitCandidateCond.Pred,
277*d415bd75Srobert SplitCandidateCond.AddRecSCEV->getStart(),
278*d415bd75Srobert SplitCandidateCond.BoundSCEV))
279*d415bd75Srobert continue;
280*d415bd75Srobert
28173471bf0Spatrick SplitCandidateCond.BI = BI;
28273471bf0Spatrick return BI;
28373471bf0Spatrick }
28473471bf0Spatrick
28573471bf0Spatrick return nullptr;
28673471bf0Spatrick }
28773471bf0Spatrick
splitLoopBound(Loop & L,DominatorTree & DT,LoopInfo & LI,ScalarEvolution & SE,LPMUpdater & U)28873471bf0Spatrick static bool splitLoopBound(Loop &L, DominatorTree &DT, LoopInfo &LI,
28973471bf0Spatrick ScalarEvolution &SE, LPMUpdater &U) {
29073471bf0Spatrick ConditionInfo SplitCandidateCond;
29173471bf0Spatrick ConditionInfo ExitingCond;
29273471bf0Spatrick
29373471bf0Spatrick // Check we can split this loop's bound.
29473471bf0Spatrick if (!canSplitLoopBound(L, DT, SE, ExitingCond))
29573471bf0Spatrick return false;
29673471bf0Spatrick
29773471bf0Spatrick if (!findSplitCandidate(L, SE, ExitingCond, SplitCandidateCond))
29873471bf0Spatrick return false;
29973471bf0Spatrick
30073471bf0Spatrick if (!isProfitableToTransform(L, SplitCandidateCond.BI))
30173471bf0Spatrick return false;
30273471bf0Spatrick
30373471bf0Spatrick // Now, we have a split candidate. Let's build a form as below.
30473471bf0Spatrick // +--------------------+
30573471bf0Spatrick // | preheader |
30673471bf0Spatrick // | set up newbound |
30773471bf0Spatrick // +--------------------+
30873471bf0Spatrick // | /----------------\
30973471bf0Spatrick // +--------v----v------+ |
31073471bf0Spatrick // | header |---\ |
31173471bf0Spatrick // | with true condition| | |
31273471bf0Spatrick // +--------------------+ | |
31373471bf0Spatrick // | | |
31473471bf0Spatrick // +--------v-----------+ | |
31573471bf0Spatrick // | if.then.BB | | |
31673471bf0Spatrick // +--------------------+ | |
31773471bf0Spatrick // | | |
31873471bf0Spatrick // +--------v-----------<---/ |
31973471bf0Spatrick // | latch >----------/
32073471bf0Spatrick // | with newbound |
32173471bf0Spatrick // +--------------------+
32273471bf0Spatrick // |
32373471bf0Spatrick // +--------v-----------+
32473471bf0Spatrick // | preheader2 |--------------\
32573471bf0Spatrick // | if (AddRec i != | |
32673471bf0Spatrick // | org bound) | |
32773471bf0Spatrick // +--------------------+ |
32873471bf0Spatrick // | /----------------\ |
32973471bf0Spatrick // +--------v----v------+ | |
33073471bf0Spatrick // | header2 |---\ | |
33173471bf0Spatrick // | conditional branch | | | |
33273471bf0Spatrick // |with false condition| | | |
33373471bf0Spatrick // +--------------------+ | | |
33473471bf0Spatrick // | | | |
33573471bf0Spatrick // +--------v-----------+ | | |
33673471bf0Spatrick // | if.then.BB2 | | | |
33773471bf0Spatrick // +--------------------+ | | |
33873471bf0Spatrick // | | | |
33973471bf0Spatrick // +--------v-----------<---/ | |
34073471bf0Spatrick // | latch2 >----------/ |
34173471bf0Spatrick // | with org bound | |
34273471bf0Spatrick // +--------v-----------+ |
34373471bf0Spatrick // | |
34473471bf0Spatrick // | +---------------+ |
34573471bf0Spatrick // +--> exit <-------/
34673471bf0Spatrick // +---------------+
34773471bf0Spatrick
34873471bf0Spatrick // Let's create post loop.
34973471bf0Spatrick SmallVector<BasicBlock *, 8> PostLoopBlocks;
35073471bf0Spatrick Loop *PostLoop;
35173471bf0Spatrick ValueToValueMapTy VMap;
35273471bf0Spatrick BasicBlock *PreHeader = L.getLoopPreheader();
35373471bf0Spatrick BasicBlock *SplitLoopPH = SplitEdge(PreHeader, L.getHeader(), &DT, &LI);
35473471bf0Spatrick PostLoop = cloneLoopWithPreheader(L.getExitBlock(), SplitLoopPH, &L, VMap,
35573471bf0Spatrick ".split", &LI, &DT, PostLoopBlocks);
35673471bf0Spatrick remapInstructionsInBlocks(PostLoopBlocks, VMap);
35773471bf0Spatrick
35873471bf0Spatrick BasicBlock *PostLoopPreHeader = PostLoop->getLoopPreheader();
359*d415bd75Srobert IRBuilder<> Builder(&PostLoopPreHeader->front());
360*d415bd75Srobert
361*d415bd75Srobert // Update phi nodes in header of post-loop.
362*d415bd75Srobert bool isExitingLatch =
363*d415bd75Srobert (L.getExitingBlock() == L.getLoopLatch()) ? true : false;
364*d415bd75Srobert Value *ExitingCondLCSSAPhi = nullptr;
365*d415bd75Srobert for (PHINode &PN : L.getHeader()->phis()) {
366*d415bd75Srobert // Create LCSSA phi node in preheader of post-loop.
367*d415bd75Srobert PHINode *LCSSAPhi =
368*d415bd75Srobert Builder.CreatePHI(PN.getType(), 1, PN.getName() + ".lcssa");
369*d415bd75Srobert LCSSAPhi->setDebugLoc(PN.getDebugLoc());
370*d415bd75Srobert // If the exiting block is loop latch, the phi does not have the update at
371*d415bd75Srobert // last iteration. In this case, update lcssa phi with value from backedge.
372*d415bd75Srobert LCSSAPhi->addIncoming(
373*d415bd75Srobert isExitingLatch ? PN.getIncomingValueForBlock(L.getLoopLatch()) : &PN,
374*d415bd75Srobert L.getExitingBlock());
375*d415bd75Srobert
376*d415bd75Srobert // Update the start value of phi node in post-loop with the LCSSA phi node.
377*d415bd75Srobert PHINode *PostLoopPN = cast<PHINode>(VMap[&PN]);
378*d415bd75Srobert PostLoopPN->setIncomingValueForBlock(PostLoopPreHeader, LCSSAPhi);
379*d415bd75Srobert
380*d415bd75Srobert // Find PHI with exiting condition from pre-loop. The PHI should be
381*d415bd75Srobert // SCEVAddRecExpr and have same incoming value from backedge with
382*d415bd75Srobert // ExitingCond.
383*d415bd75Srobert if (!SE.isSCEVable(PN.getType()))
384*d415bd75Srobert continue;
385*d415bd75Srobert
386*d415bd75Srobert const SCEVAddRecExpr *PhiSCEV = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(&PN));
387*d415bd75Srobert if (PhiSCEV && ExitingCond.NonPHIAddRecValue ==
388*d415bd75Srobert PN.getIncomingValueForBlock(L.getLoopLatch()))
389*d415bd75Srobert ExitingCondLCSSAPhi = LCSSAPhi;
390*d415bd75Srobert }
391*d415bd75Srobert
392*d415bd75Srobert // Add conditional branch to check we can skip post-loop in its preheader.
39373471bf0Spatrick Instruction *OrigBI = PostLoopPreHeader->getTerminator();
39473471bf0Spatrick ICmpInst::Predicate Pred = ICmpInst::ICMP_NE;
39573471bf0Spatrick Value *Cond =
396*d415bd75Srobert Builder.CreateICmp(Pred, ExitingCondLCSSAPhi, ExitingCond.BoundValue);
39773471bf0Spatrick Builder.CreateCondBr(Cond, PostLoop->getHeader(), PostLoop->getExitBlock());
39873471bf0Spatrick OrigBI->eraseFromParent();
39973471bf0Spatrick
40073471bf0Spatrick // Create new loop bound and add it into preheader of pre-loop.
40173471bf0Spatrick const SCEV *NewBoundSCEV = ExitingCond.BoundSCEV;
40273471bf0Spatrick const SCEV *SplitBoundSCEV = SplitCandidateCond.BoundSCEV;
40373471bf0Spatrick NewBoundSCEV = ICmpInst::isSigned(ExitingCond.Pred)
40473471bf0Spatrick ? SE.getSMinExpr(NewBoundSCEV, SplitBoundSCEV)
40573471bf0Spatrick : SE.getUMinExpr(NewBoundSCEV, SplitBoundSCEV);
40673471bf0Spatrick
40773471bf0Spatrick SCEVExpander Expander(
40873471bf0Spatrick SE, L.getHeader()->getParent()->getParent()->getDataLayout(), "split");
40973471bf0Spatrick Instruction *InsertPt = SplitLoopPH->getTerminator();
41073471bf0Spatrick Value *NewBoundValue =
41173471bf0Spatrick Expander.expandCodeFor(NewBoundSCEV, NewBoundSCEV->getType(), InsertPt);
41273471bf0Spatrick NewBoundValue->setName("new.bound");
41373471bf0Spatrick
41473471bf0Spatrick // Replace exiting bound value of pre-loop NewBound.
41573471bf0Spatrick ExitingCond.ICmp->setOperand(1, NewBoundValue);
41673471bf0Spatrick
41773471bf0Spatrick // Replace SplitCandidateCond.BI's condition of pre-loop by True.
41873471bf0Spatrick LLVMContext &Context = PreHeader->getContext();
41973471bf0Spatrick SplitCandidateCond.BI->setCondition(ConstantInt::getTrue(Context));
42073471bf0Spatrick
42173471bf0Spatrick // Replace cloned SplitCandidateCond.BI's condition in post-loop by False.
42273471bf0Spatrick BranchInst *ClonedSplitCandidateBI =
42373471bf0Spatrick cast<BranchInst>(VMap[SplitCandidateCond.BI]);
42473471bf0Spatrick ClonedSplitCandidateBI->setCondition(ConstantInt::getFalse(Context));
42573471bf0Spatrick
42673471bf0Spatrick // Replace exit branch target of pre-loop by post-loop's preheader.
42773471bf0Spatrick if (L.getExitBlock() == ExitingCond.BI->getSuccessor(0))
42873471bf0Spatrick ExitingCond.BI->setSuccessor(0, PostLoopPreHeader);
42973471bf0Spatrick else
43073471bf0Spatrick ExitingCond.BI->setSuccessor(1, PostLoopPreHeader);
43173471bf0Spatrick
432*d415bd75Srobert // Update phi node in exit block of post-loop.
433*d415bd75Srobert Builder.SetInsertPoint(&PostLoopPreHeader->front());
434*d415bd75Srobert for (PHINode &PN : PostLoop->getExitBlock()->phis()) {
435*d415bd75Srobert for (auto i : seq<int>(0, PN.getNumOperands())) {
436*d415bd75Srobert // Check incoming block is pre-loop's exiting block.
437*d415bd75Srobert if (PN.getIncomingBlock(i) == L.getExitingBlock()) {
438*d415bd75Srobert Value *IncomingValue = PN.getIncomingValue(i);
439*d415bd75Srobert
440*d415bd75Srobert // Create LCSSA phi node for incoming value.
441*d415bd75Srobert PHINode *LCSSAPhi =
442*d415bd75Srobert Builder.CreatePHI(PN.getType(), 1, PN.getName() + ".lcssa");
443*d415bd75Srobert LCSSAPhi->setDebugLoc(PN.getDebugLoc());
444*d415bd75Srobert LCSSAPhi->addIncoming(IncomingValue, PN.getIncomingBlock(i));
445*d415bd75Srobert
446*d415bd75Srobert // Replace pre-loop's exiting block by post-loop's preheader.
447*d415bd75Srobert PN.setIncomingBlock(i, PostLoopPreHeader);
448*d415bd75Srobert // Replace incoming value by LCSSAPhi.
449*d415bd75Srobert PN.setIncomingValue(i, LCSSAPhi);
450*d415bd75Srobert // Add a new incoming value with post-loop's exiting block.
451*d415bd75Srobert PN.addIncoming(VMap[IncomingValue], PostLoop->getExitingBlock());
452*d415bd75Srobert }
453*d415bd75Srobert }
454*d415bd75Srobert }
455*d415bd75Srobert
45673471bf0Spatrick // Update dominator tree.
45773471bf0Spatrick DT.changeImmediateDominator(PostLoopPreHeader, L.getExitingBlock());
45873471bf0Spatrick DT.changeImmediateDominator(PostLoop->getExitBlock(), PostLoopPreHeader);
45973471bf0Spatrick
46073471bf0Spatrick // Invalidate cached SE information.
46173471bf0Spatrick SE.forgetLoop(&L);
46273471bf0Spatrick
46373471bf0Spatrick // Canonicalize loops.
46473471bf0Spatrick simplifyLoop(&L, &DT, &LI, &SE, nullptr, nullptr, true);
46573471bf0Spatrick simplifyLoop(PostLoop, &DT, &LI, &SE, nullptr, nullptr, true);
46673471bf0Spatrick
46773471bf0Spatrick // Add new post-loop to loop pass manager.
46873471bf0Spatrick U.addSiblingLoops(PostLoop);
46973471bf0Spatrick
47073471bf0Spatrick return true;
47173471bf0Spatrick }
47273471bf0Spatrick
run(Loop & L,LoopAnalysisManager & AM,LoopStandardAnalysisResults & AR,LPMUpdater & U)47373471bf0Spatrick PreservedAnalyses LoopBoundSplitPass::run(Loop &L, LoopAnalysisManager &AM,
47473471bf0Spatrick LoopStandardAnalysisResults &AR,
47573471bf0Spatrick LPMUpdater &U) {
47673471bf0Spatrick Function &F = *L.getHeader()->getParent();
47773471bf0Spatrick (void)F;
47873471bf0Spatrick
47973471bf0Spatrick LLVM_DEBUG(dbgs() << "Spliting bound of loop in " << F.getName() << ": " << L
48073471bf0Spatrick << "\n");
48173471bf0Spatrick
48273471bf0Spatrick if (!splitLoopBound(L, AR.DT, AR.LI, AR.SE, U))
48373471bf0Spatrick return PreservedAnalyses::all();
48473471bf0Spatrick
48573471bf0Spatrick assert(AR.DT.verify(DominatorTree::VerificationLevel::Fast));
48673471bf0Spatrick AR.LI.verify(AR.DT);
48773471bf0Spatrick
48873471bf0Spatrick return getLoopPassPreservedAnalyses();
48973471bf0Spatrick }
49073471bf0Spatrick
49173471bf0Spatrick } // end namespace llvm
492