xref: /src/contrib/llvm-project/llvm/lib/Transforms/Scalar/LoopBoundSplit.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1344a3780SDimitry Andric //===------- LoopBoundSplit.cpp - Split Loop Bound --------------*- C++ -*-===//
2344a3780SDimitry Andric //
3344a3780SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4344a3780SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5344a3780SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6344a3780SDimitry Andric //
7344a3780SDimitry Andric //===----------------------------------------------------------------------===//
8344a3780SDimitry Andric 
9344a3780SDimitry Andric #include "llvm/Transforms/Scalar/LoopBoundSplit.h"
10c0981da4SDimitry Andric #include "llvm/ADT/Sequence.h"
11344a3780SDimitry Andric #include "llvm/Analysis/LoopAnalysisManager.h"
12344a3780SDimitry Andric #include "llvm/Analysis/LoopInfo.h"
13344a3780SDimitry Andric #include "llvm/Analysis/ScalarEvolution.h"
14344a3780SDimitry Andric #include "llvm/Analysis/ScalarEvolutionExpressions.h"
15344a3780SDimitry Andric #include "llvm/IR/PatternMatch.h"
16145449b1SDimitry Andric #include "llvm/Transforms/Scalar/LoopPassManager.h"
17344a3780SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h"
18344a3780SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h"
19344a3780SDimitry Andric #include "llvm/Transforms/Utils/LoopSimplify.h"
20344a3780SDimitry Andric #include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
21344a3780SDimitry Andric 
22344a3780SDimitry Andric #define DEBUG_TYPE "loop-bound-split"
23344a3780SDimitry Andric 
24344a3780SDimitry Andric namespace llvm {
25344a3780SDimitry Andric 
26344a3780SDimitry Andric using namespace PatternMatch;
27344a3780SDimitry Andric 
28344a3780SDimitry Andric namespace {
29344a3780SDimitry Andric struct ConditionInfo {
30344a3780SDimitry Andric   /// Branch instruction with this condition
31145449b1SDimitry Andric   BranchInst *BI = nullptr;
32344a3780SDimitry Andric   /// ICmp instruction with this condition
33145449b1SDimitry Andric   ICmpInst *ICmp = nullptr;
34344a3780SDimitry Andric   /// Preciate info
35145449b1SDimitry Andric   ICmpInst::Predicate Pred = ICmpInst::BAD_ICMP_PREDICATE;
36344a3780SDimitry Andric   /// AddRec llvm value
37145449b1SDimitry Andric   Value *AddRecValue = nullptr;
38c0981da4SDimitry Andric   /// Non PHI AddRec llvm value
39c0981da4SDimitry Andric   Value *NonPHIAddRecValue;
40344a3780SDimitry Andric   /// Bound llvm value
41145449b1SDimitry Andric   Value *BoundValue = nullptr;
42344a3780SDimitry Andric   /// AddRec SCEV
43145449b1SDimitry Andric   const SCEVAddRecExpr *AddRecSCEV = nullptr;
44344a3780SDimitry Andric   /// Bound SCEV
45145449b1SDimitry Andric   const SCEV *BoundSCEV = nullptr;
46344a3780SDimitry Andric 
47145449b1SDimitry Andric   ConditionInfo() = default;
48344a3780SDimitry Andric };
49344a3780SDimitry Andric } // namespace
50344a3780SDimitry Andric 
analyzeICmp(ScalarEvolution & SE,ICmpInst * ICmp,ConditionInfo & Cond,const Loop & L)51344a3780SDimitry Andric static void analyzeICmp(ScalarEvolution &SE, ICmpInst *ICmp,
52c0981da4SDimitry Andric                         ConditionInfo &Cond, const Loop &L) {
53344a3780SDimitry Andric   Cond.ICmp = ICmp;
54344a3780SDimitry Andric   if (match(ICmp, m_ICmp(Cond.Pred, m_Value(Cond.AddRecValue),
55344a3780SDimitry Andric                          m_Value(Cond.BoundValue)))) {
56c0981da4SDimitry Andric     const SCEV *AddRecSCEV = SE.getSCEV(Cond.AddRecValue);
57c0981da4SDimitry Andric     const SCEV *BoundSCEV = SE.getSCEV(Cond.BoundValue);
58c0981da4SDimitry Andric     const SCEVAddRecExpr *LHSAddRecSCEV = dyn_cast<SCEVAddRecExpr>(AddRecSCEV);
59c0981da4SDimitry Andric     const SCEVAddRecExpr *RHSAddRecSCEV = dyn_cast<SCEVAddRecExpr>(BoundSCEV);
60344a3780SDimitry Andric     // Locate AddRec in LHSSCEV and Bound in RHSSCEV.
61c0981da4SDimitry Andric     if (!LHSAddRecSCEV && RHSAddRecSCEV) {
62344a3780SDimitry Andric       std::swap(Cond.AddRecValue, Cond.BoundValue);
63c0981da4SDimitry Andric       std::swap(AddRecSCEV, BoundSCEV);
64344a3780SDimitry Andric       Cond.Pred = ICmpInst::getSwappedPredicate(Cond.Pred);
65344a3780SDimitry Andric     }
66c0981da4SDimitry Andric 
67c0981da4SDimitry Andric     Cond.AddRecSCEV = dyn_cast<SCEVAddRecExpr>(AddRecSCEV);
68c0981da4SDimitry Andric     Cond.BoundSCEV = BoundSCEV;
69c0981da4SDimitry Andric     Cond.NonPHIAddRecValue = Cond.AddRecValue;
70c0981da4SDimitry Andric 
71c0981da4SDimitry Andric     // If the Cond.AddRecValue is PHI node, update Cond.NonPHIAddRecValue with
72c0981da4SDimitry Andric     // value from backedge.
73c0981da4SDimitry Andric     if (Cond.AddRecSCEV && isa<PHINode>(Cond.AddRecValue)) {
74c0981da4SDimitry Andric       PHINode *PN = cast<PHINode>(Cond.AddRecValue);
75c0981da4SDimitry Andric       Cond.NonPHIAddRecValue = PN->getIncomingValueForBlock(L.getLoopLatch());
76c0981da4SDimitry Andric     }
77344a3780SDimitry Andric   }
78344a3780SDimitry Andric }
79344a3780SDimitry Andric 
calculateUpperBound(const Loop & L,ScalarEvolution & SE,ConditionInfo & Cond,bool IsExitCond)80344a3780SDimitry Andric static bool calculateUpperBound(const Loop &L, ScalarEvolution &SE,
81344a3780SDimitry Andric                                 ConditionInfo &Cond, bool IsExitCond) {
82344a3780SDimitry Andric   if (IsExitCond) {
83344a3780SDimitry Andric     const SCEV *ExitCount = SE.getExitCount(&L, Cond.ICmp->getParent());
84344a3780SDimitry Andric     if (isa<SCEVCouldNotCompute>(ExitCount))
85344a3780SDimitry Andric       return false;
86344a3780SDimitry Andric 
87344a3780SDimitry Andric     Cond.BoundSCEV = ExitCount;
88344a3780SDimitry Andric     return true;
89344a3780SDimitry Andric   }
90344a3780SDimitry Andric 
91344a3780SDimitry Andric   // For non-exit condtion, if pred is LT, keep existing bound.
92344a3780SDimitry Andric   if (Cond.Pred == ICmpInst::ICMP_SLT || Cond.Pred == ICmpInst::ICMP_ULT)
93344a3780SDimitry Andric     return true;
94344a3780SDimitry Andric 
95344a3780SDimitry Andric   // For non-exit condition, if pre is LE, try to convert it to LT.
96344a3780SDimitry Andric   //      Range                 Range
97344a3780SDimitry Andric   // AddRec <= Bound  -->  AddRec < Bound + 1
98344a3780SDimitry Andric   if (Cond.Pred != ICmpInst::ICMP_ULE && Cond.Pred != ICmpInst::ICMP_SLE)
99344a3780SDimitry Andric     return false;
100344a3780SDimitry Andric 
101344a3780SDimitry Andric   if (IntegerType *BoundSCEVIntType =
102344a3780SDimitry Andric           dyn_cast<IntegerType>(Cond.BoundSCEV->getType())) {
103344a3780SDimitry Andric     unsigned BitWidth = BoundSCEVIntType->getBitWidth();
104344a3780SDimitry Andric     APInt Max = ICmpInst::isSigned(Cond.Pred)
105344a3780SDimitry Andric                     ? APInt::getSignedMaxValue(BitWidth)
106344a3780SDimitry Andric                     : APInt::getMaxValue(BitWidth);
107344a3780SDimitry Andric     const SCEV *MaxSCEV = SE.getConstant(Max);
108344a3780SDimitry Andric     // Check Bound < INT_MAX
109344a3780SDimitry Andric     ICmpInst::Predicate Pred =
110344a3780SDimitry Andric         ICmpInst::isSigned(Cond.Pred) ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
111344a3780SDimitry Andric     if (SE.isKnownPredicate(Pred, Cond.BoundSCEV, MaxSCEV)) {
112344a3780SDimitry Andric       const SCEV *BoundPlusOneSCEV =
113344a3780SDimitry Andric           SE.getAddExpr(Cond.BoundSCEV, SE.getOne(BoundSCEVIntType));
114344a3780SDimitry Andric       Cond.BoundSCEV = BoundPlusOneSCEV;
115344a3780SDimitry Andric       Cond.Pred = Pred;
116344a3780SDimitry Andric       return true;
117344a3780SDimitry Andric     }
118344a3780SDimitry Andric   }
119344a3780SDimitry Andric 
120344a3780SDimitry Andric   // ToDo: Support ICMP_NE/EQ.
121344a3780SDimitry Andric 
122344a3780SDimitry Andric   return false;
123344a3780SDimitry Andric }
124344a3780SDimitry Andric 
hasProcessableCondition(const Loop & L,ScalarEvolution & SE,ICmpInst * ICmp,ConditionInfo & Cond,bool IsExitCond)125344a3780SDimitry Andric static bool hasProcessableCondition(const Loop &L, ScalarEvolution &SE,
126344a3780SDimitry Andric                                     ICmpInst *ICmp, ConditionInfo &Cond,
127344a3780SDimitry Andric                                     bool IsExitCond) {
128c0981da4SDimitry Andric   analyzeICmp(SE, ICmp, Cond, L);
129344a3780SDimitry Andric 
130344a3780SDimitry Andric   // The BoundSCEV should be evaluated at loop entry.
131344a3780SDimitry Andric   if (!SE.isAvailableAtLoopEntry(Cond.BoundSCEV, &L))
132344a3780SDimitry Andric     return false;
133344a3780SDimitry Andric 
134344a3780SDimitry Andric   // Allowed AddRec as induction variable.
135c0981da4SDimitry Andric   if (!Cond.AddRecSCEV)
136344a3780SDimitry Andric     return false;
137344a3780SDimitry Andric 
138c0981da4SDimitry Andric   if (!Cond.AddRecSCEV->isAffine())
139344a3780SDimitry Andric     return false;
140344a3780SDimitry Andric 
141c0981da4SDimitry Andric   const SCEV *StepRecSCEV = Cond.AddRecSCEV->getStepRecurrence(SE);
142344a3780SDimitry Andric   // Allowed constant step.
143344a3780SDimitry Andric   if (!isa<SCEVConstant>(StepRecSCEV))
144344a3780SDimitry Andric     return false;
145344a3780SDimitry Andric 
146344a3780SDimitry Andric   ConstantInt *StepCI = cast<SCEVConstant>(StepRecSCEV)->getValue();
147344a3780SDimitry Andric   // Allowed positive step for now.
148344a3780SDimitry Andric   // TODO: Support negative step.
149344a3780SDimitry Andric   if (StepCI->isNegative() || StepCI->isZero())
150344a3780SDimitry Andric     return false;
151344a3780SDimitry Andric 
152344a3780SDimitry Andric   // Calculate upper bound.
153344a3780SDimitry Andric   if (!calculateUpperBound(L, SE, Cond, IsExitCond))
154344a3780SDimitry Andric     return false;
155344a3780SDimitry Andric 
156344a3780SDimitry Andric   return true;
157344a3780SDimitry Andric }
158344a3780SDimitry Andric 
isProcessableCondBI(const ScalarEvolution & SE,const BranchInst * BI)159344a3780SDimitry Andric static bool isProcessableCondBI(const ScalarEvolution &SE,
160344a3780SDimitry Andric                                 const BranchInst *BI) {
161344a3780SDimitry Andric   BasicBlock *TrueSucc = nullptr;
162344a3780SDimitry Andric   BasicBlock *FalseSucc = nullptr;
163344a3780SDimitry Andric   ICmpInst::Predicate Pred;
164344a3780SDimitry Andric   Value *LHS, *RHS;
165344a3780SDimitry Andric   if (!match(BI, m_Br(m_ICmp(Pred, m_Value(LHS), m_Value(RHS)),
166344a3780SDimitry Andric                       m_BasicBlock(TrueSucc), m_BasicBlock(FalseSucc))))
167344a3780SDimitry Andric     return false;
168344a3780SDimitry Andric 
169344a3780SDimitry Andric   if (!SE.isSCEVable(LHS->getType()))
170344a3780SDimitry Andric     return false;
171344a3780SDimitry Andric   assert(SE.isSCEVable(RHS->getType()) && "Expected RHS's type is SCEVable");
172344a3780SDimitry Andric 
173344a3780SDimitry Andric   if (TrueSucc == FalseSucc)
174344a3780SDimitry Andric     return false;
175344a3780SDimitry Andric 
176344a3780SDimitry Andric   return true;
177344a3780SDimitry Andric }
178344a3780SDimitry Andric 
canSplitLoopBound(const Loop & L,const DominatorTree & DT,ScalarEvolution & SE,ConditionInfo & Cond)179344a3780SDimitry Andric static bool canSplitLoopBound(const Loop &L, const DominatorTree &DT,
180344a3780SDimitry Andric                               ScalarEvolution &SE, ConditionInfo &Cond) {
181344a3780SDimitry Andric   // Skip function with optsize.
182344a3780SDimitry Andric   if (L.getHeader()->getParent()->hasOptSize())
183344a3780SDimitry Andric     return false;
184344a3780SDimitry Andric 
185344a3780SDimitry Andric   // Split only innermost loop.
186344a3780SDimitry Andric   if (!L.isInnermost())
187344a3780SDimitry Andric     return false;
188344a3780SDimitry Andric 
189344a3780SDimitry Andric   // Check loop is in simplified form.
190344a3780SDimitry Andric   if (!L.isLoopSimplifyForm())
191344a3780SDimitry Andric     return false;
192344a3780SDimitry Andric 
193344a3780SDimitry Andric   // Check loop is in LCSSA form.
194344a3780SDimitry Andric   if (!L.isLCSSAForm(DT))
195344a3780SDimitry Andric     return false;
196344a3780SDimitry Andric 
197344a3780SDimitry Andric   // Skip loop that cannot be cloned.
198344a3780SDimitry Andric   if (!L.isSafeToClone())
199344a3780SDimitry Andric     return false;
200344a3780SDimitry Andric 
201344a3780SDimitry Andric   BasicBlock *ExitingBB = L.getExitingBlock();
202344a3780SDimitry Andric   // Assumed only one exiting block.
203344a3780SDimitry Andric   if (!ExitingBB)
204344a3780SDimitry Andric     return false;
205344a3780SDimitry Andric 
206344a3780SDimitry Andric   BranchInst *ExitingBI = dyn_cast<BranchInst>(ExitingBB->getTerminator());
207344a3780SDimitry Andric   if (!ExitingBI)
208344a3780SDimitry Andric     return false;
209344a3780SDimitry Andric 
210344a3780SDimitry Andric   // Allowed only conditional branch with ICmp.
211344a3780SDimitry Andric   if (!isProcessableCondBI(SE, ExitingBI))
212344a3780SDimitry Andric     return false;
213344a3780SDimitry Andric 
214344a3780SDimitry Andric   // Check the condition is processable.
215344a3780SDimitry Andric   ICmpInst *ICmp = cast<ICmpInst>(ExitingBI->getCondition());
216344a3780SDimitry Andric   if (!hasProcessableCondition(L, SE, ICmp, Cond, /*IsExitCond*/ true))
217344a3780SDimitry Andric     return false;
218344a3780SDimitry Andric 
219344a3780SDimitry Andric   Cond.BI = ExitingBI;
220344a3780SDimitry Andric   return true;
221344a3780SDimitry Andric }
222344a3780SDimitry Andric 
isProfitableToTransform(const Loop & L,const BranchInst * BI)223344a3780SDimitry Andric static bool isProfitableToTransform(const Loop &L, const BranchInst *BI) {
224344a3780SDimitry Andric   // If the conditional branch splits a loop into two halves, we could
225344a3780SDimitry Andric   // generally say it is profitable.
226344a3780SDimitry Andric   //
227344a3780SDimitry Andric   // ToDo: Add more profitable cases here.
228344a3780SDimitry Andric 
229344a3780SDimitry Andric   // Check this branch causes diamond CFG.
230344a3780SDimitry Andric   BasicBlock *Succ0 = BI->getSuccessor(0);
231344a3780SDimitry Andric   BasicBlock *Succ1 = BI->getSuccessor(1);
232344a3780SDimitry Andric 
233344a3780SDimitry Andric   BasicBlock *Succ0Succ = Succ0->getSingleSuccessor();
234344a3780SDimitry Andric   BasicBlock *Succ1Succ = Succ1->getSingleSuccessor();
235344a3780SDimitry Andric   if (!Succ0Succ || !Succ1Succ || Succ0Succ != Succ1Succ)
236344a3780SDimitry Andric     return false;
237344a3780SDimitry Andric 
238344a3780SDimitry Andric   // ToDo: Calculate each successor's instruction cost.
239344a3780SDimitry Andric 
240344a3780SDimitry Andric   return true;
241344a3780SDimitry Andric }
242344a3780SDimitry Andric 
findSplitCandidate(const Loop & L,ScalarEvolution & SE,ConditionInfo & ExitingCond,ConditionInfo & SplitCandidateCond)243344a3780SDimitry Andric static BranchInst *findSplitCandidate(const Loop &L, ScalarEvolution &SE,
244344a3780SDimitry Andric                                       ConditionInfo &ExitingCond,
245344a3780SDimitry Andric                                       ConditionInfo &SplitCandidateCond) {
246344a3780SDimitry Andric   for (auto *BB : L.blocks()) {
247344a3780SDimitry Andric     // Skip condition of backedge.
248344a3780SDimitry Andric     if (L.getLoopLatch() == BB)
249344a3780SDimitry Andric       continue;
250344a3780SDimitry Andric 
251344a3780SDimitry Andric     auto *BI = dyn_cast<BranchInst>(BB->getTerminator());
252344a3780SDimitry Andric     if (!BI)
253344a3780SDimitry Andric       continue;
254344a3780SDimitry Andric 
255344a3780SDimitry Andric     // Check conditional branch with ICmp.
256344a3780SDimitry Andric     if (!isProcessableCondBI(SE, BI))
257344a3780SDimitry Andric       continue;
258344a3780SDimitry Andric 
259344a3780SDimitry Andric     // Skip loop invariant condition.
260344a3780SDimitry Andric     if (L.isLoopInvariant(BI->getCondition()))
261344a3780SDimitry Andric       continue;
262344a3780SDimitry Andric 
263344a3780SDimitry Andric     // Check the condition is processable.
264344a3780SDimitry Andric     ICmpInst *ICmp = cast<ICmpInst>(BI->getCondition());
265344a3780SDimitry Andric     if (!hasProcessableCondition(L, SE, ICmp, SplitCandidateCond,
266344a3780SDimitry Andric                                  /*IsExitCond*/ false))
267344a3780SDimitry Andric       continue;
268344a3780SDimitry Andric 
269344a3780SDimitry Andric     if (ExitingCond.BoundSCEV->getType() !=
270344a3780SDimitry Andric         SplitCandidateCond.BoundSCEV->getType())
271344a3780SDimitry Andric       continue;
272344a3780SDimitry Andric 
273c0981da4SDimitry Andric     // After transformation, we assume the split condition of the pre-loop is
274c0981da4SDimitry Andric     // always true. In order to guarantee it, we need to check the start value
275c0981da4SDimitry Andric     // of the split cond AddRec satisfies the split condition.
276c0981da4SDimitry Andric     if (!SE.isLoopEntryGuardedByCond(&L, SplitCandidateCond.Pred,
277c0981da4SDimitry Andric                                      SplitCandidateCond.AddRecSCEV->getStart(),
278c0981da4SDimitry Andric                                      SplitCandidateCond.BoundSCEV))
279c0981da4SDimitry Andric       continue;
280c0981da4SDimitry Andric 
281344a3780SDimitry Andric     SplitCandidateCond.BI = BI;
282344a3780SDimitry Andric     return BI;
283344a3780SDimitry Andric   }
284344a3780SDimitry Andric 
285344a3780SDimitry Andric   return nullptr;
286344a3780SDimitry Andric }
287344a3780SDimitry Andric 
splitLoopBound(Loop & L,DominatorTree & DT,LoopInfo & LI,ScalarEvolution & SE,LPMUpdater & U)288344a3780SDimitry Andric static bool splitLoopBound(Loop &L, DominatorTree &DT, LoopInfo &LI,
289344a3780SDimitry Andric                            ScalarEvolution &SE, LPMUpdater &U) {
290344a3780SDimitry Andric   ConditionInfo SplitCandidateCond;
291344a3780SDimitry Andric   ConditionInfo ExitingCond;
292344a3780SDimitry Andric 
293344a3780SDimitry Andric   // Check we can split this loop's bound.
294344a3780SDimitry Andric   if (!canSplitLoopBound(L, DT, SE, ExitingCond))
295344a3780SDimitry Andric     return false;
296344a3780SDimitry Andric 
297344a3780SDimitry Andric   if (!findSplitCandidate(L, SE, ExitingCond, SplitCandidateCond))
298344a3780SDimitry Andric     return false;
299344a3780SDimitry Andric 
300344a3780SDimitry Andric   if (!isProfitableToTransform(L, SplitCandidateCond.BI))
301344a3780SDimitry Andric     return false;
302344a3780SDimitry Andric 
303344a3780SDimitry Andric   // Now, we have a split candidate. Let's build a form as below.
304344a3780SDimitry Andric   //    +--------------------+
305344a3780SDimitry Andric   //    |     preheader      |
306344a3780SDimitry Andric   //    |  set up newbound   |
307344a3780SDimitry Andric   //    +--------------------+
308344a3780SDimitry Andric   //             |     /----------------\
309344a3780SDimitry Andric   //    +--------v----v------+          |
310344a3780SDimitry Andric   //    |      header        |---\      |
311344a3780SDimitry Andric   //    | with true condition|   |      |
312344a3780SDimitry Andric   //    +--------------------+   |      |
313344a3780SDimitry Andric   //             |               |      |
314344a3780SDimitry Andric   //    +--------v-----------+   |      |
315344a3780SDimitry Andric   //    |     if.then.BB     |   |      |
316344a3780SDimitry Andric   //    +--------------------+   |      |
317344a3780SDimitry Andric   //             |               |      |
318344a3780SDimitry Andric   //    +--------v-----------<---/      |
319344a3780SDimitry Andric   //    |       latch        >----------/
320344a3780SDimitry Andric   //    |   with newbound    |
321344a3780SDimitry Andric   //    +--------------------+
322344a3780SDimitry Andric   //             |
323344a3780SDimitry Andric   //    +--------v-----------+
324344a3780SDimitry Andric   //    |     preheader2     |--------------\
325344a3780SDimitry Andric   //    | if (AddRec i !=    |              |
326344a3780SDimitry Andric   //    |     org bound)     |              |
327344a3780SDimitry Andric   //    +--------------------+              |
328344a3780SDimitry Andric   //             |     /----------------\   |
329344a3780SDimitry Andric   //    +--------v----v------+          |   |
330344a3780SDimitry Andric   //    |      header2       |---\      |   |
331344a3780SDimitry Andric   //    | conditional branch |   |      |   |
332344a3780SDimitry Andric   //    |with false condition|   |      |   |
333344a3780SDimitry Andric   //    +--------------------+   |      |   |
334344a3780SDimitry Andric   //             |               |      |   |
335344a3780SDimitry Andric   //    +--------v-----------+   |      |   |
336344a3780SDimitry Andric   //    |    if.then.BB2     |   |      |   |
337344a3780SDimitry Andric   //    +--------------------+   |      |   |
338344a3780SDimitry Andric   //             |               |      |   |
339344a3780SDimitry Andric   //    +--------v-----------<---/      |   |
340344a3780SDimitry Andric   //    |       latch2       >----------/   |
341344a3780SDimitry Andric   //    |   with org bound   |              |
342344a3780SDimitry Andric   //    +--------v-----------+              |
343344a3780SDimitry Andric   //             |                          |
344344a3780SDimitry Andric   //             |  +---------------+       |
345344a3780SDimitry Andric   //             +-->     exit      <-------/
346344a3780SDimitry Andric   //                +---------------+
347344a3780SDimitry Andric 
348344a3780SDimitry Andric   // Let's create post loop.
349344a3780SDimitry Andric   SmallVector<BasicBlock *, 8> PostLoopBlocks;
350344a3780SDimitry Andric   Loop *PostLoop;
351344a3780SDimitry Andric   ValueToValueMapTy VMap;
352344a3780SDimitry Andric   BasicBlock *PreHeader = L.getLoopPreheader();
353344a3780SDimitry Andric   BasicBlock *SplitLoopPH = SplitEdge(PreHeader, L.getHeader(), &DT, &LI);
354344a3780SDimitry Andric   PostLoop = cloneLoopWithPreheader(L.getExitBlock(), SplitLoopPH, &L, VMap,
355344a3780SDimitry Andric                                     ".split", &LI, &DT, PostLoopBlocks);
356344a3780SDimitry Andric   remapInstructionsInBlocks(PostLoopBlocks, VMap);
357344a3780SDimitry Andric 
358344a3780SDimitry Andric   BasicBlock *PostLoopPreHeader = PostLoop->getLoopPreheader();
359c0981da4SDimitry Andric   IRBuilder<> Builder(&PostLoopPreHeader->front());
360c0981da4SDimitry Andric 
361c0981da4SDimitry Andric   // Update phi nodes in header of post-loop.
362c0981da4SDimitry Andric   bool isExitingLatch =
363c0981da4SDimitry Andric       (L.getExitingBlock() == L.getLoopLatch()) ? true : false;
364c0981da4SDimitry Andric   Value *ExitingCondLCSSAPhi = nullptr;
365c0981da4SDimitry Andric   for (PHINode &PN : L.getHeader()->phis()) {
366c0981da4SDimitry Andric     // Create LCSSA phi node in preheader of post-loop.
367c0981da4SDimitry Andric     PHINode *LCSSAPhi =
368c0981da4SDimitry Andric         Builder.CreatePHI(PN.getType(), 1, PN.getName() + ".lcssa");
369c0981da4SDimitry Andric     LCSSAPhi->setDebugLoc(PN.getDebugLoc());
370c0981da4SDimitry Andric     // If the exiting block is loop latch, the phi does not have the update at
371c0981da4SDimitry Andric     // last iteration. In this case, update lcssa phi with value from backedge.
372c0981da4SDimitry Andric     LCSSAPhi->addIncoming(
373c0981da4SDimitry Andric         isExitingLatch ? PN.getIncomingValueForBlock(L.getLoopLatch()) : &PN,
374c0981da4SDimitry Andric         L.getExitingBlock());
375c0981da4SDimitry Andric 
376c0981da4SDimitry Andric     // Update the start value of phi node in post-loop with the LCSSA phi node.
377c0981da4SDimitry Andric     PHINode *PostLoopPN = cast<PHINode>(VMap[&PN]);
378c0981da4SDimitry Andric     PostLoopPN->setIncomingValueForBlock(PostLoopPreHeader, LCSSAPhi);
379c0981da4SDimitry Andric 
380c0981da4SDimitry Andric     // Find PHI with exiting condition from pre-loop. The PHI should be
381c0981da4SDimitry Andric     // SCEVAddRecExpr and have same incoming value from backedge with
382c0981da4SDimitry Andric     // ExitingCond.
383c0981da4SDimitry Andric     if (!SE.isSCEVable(PN.getType()))
384c0981da4SDimitry Andric       continue;
385c0981da4SDimitry Andric 
386c0981da4SDimitry Andric     const SCEVAddRecExpr *PhiSCEV = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(&PN));
387c0981da4SDimitry Andric     if (PhiSCEV && ExitingCond.NonPHIAddRecValue ==
388c0981da4SDimitry Andric                        PN.getIncomingValueForBlock(L.getLoopLatch()))
389c0981da4SDimitry Andric       ExitingCondLCSSAPhi = LCSSAPhi;
390c0981da4SDimitry Andric   }
391c0981da4SDimitry Andric 
392c0981da4SDimitry Andric   // Add conditional branch to check we can skip post-loop in its preheader.
393344a3780SDimitry Andric   Instruction *OrigBI = PostLoopPreHeader->getTerminator();
394344a3780SDimitry Andric   ICmpInst::Predicate Pred = ICmpInst::ICMP_NE;
395344a3780SDimitry Andric   Value *Cond =
396c0981da4SDimitry Andric       Builder.CreateICmp(Pred, ExitingCondLCSSAPhi, ExitingCond.BoundValue);
397344a3780SDimitry Andric   Builder.CreateCondBr(Cond, PostLoop->getHeader(), PostLoop->getExitBlock());
398344a3780SDimitry Andric   OrigBI->eraseFromParent();
399344a3780SDimitry Andric 
400344a3780SDimitry Andric   // Create new loop bound and add it into preheader of pre-loop.
401344a3780SDimitry Andric   const SCEV *NewBoundSCEV = ExitingCond.BoundSCEV;
402344a3780SDimitry Andric   const SCEV *SplitBoundSCEV = SplitCandidateCond.BoundSCEV;
403344a3780SDimitry Andric   NewBoundSCEV = ICmpInst::isSigned(ExitingCond.Pred)
404344a3780SDimitry Andric                      ? SE.getSMinExpr(NewBoundSCEV, SplitBoundSCEV)
405344a3780SDimitry Andric                      : SE.getUMinExpr(NewBoundSCEV, SplitBoundSCEV);
406344a3780SDimitry Andric 
407344a3780SDimitry Andric   SCEVExpander Expander(
408ac9a064cSDimitry Andric       SE, L.getHeader()->getDataLayout(), "split");
409344a3780SDimitry Andric   Instruction *InsertPt = SplitLoopPH->getTerminator();
410344a3780SDimitry Andric   Value *NewBoundValue =
411344a3780SDimitry Andric       Expander.expandCodeFor(NewBoundSCEV, NewBoundSCEV->getType(), InsertPt);
412344a3780SDimitry Andric   NewBoundValue->setName("new.bound");
413344a3780SDimitry Andric 
414344a3780SDimitry Andric   // Replace exiting bound value of pre-loop NewBound.
415344a3780SDimitry Andric   ExitingCond.ICmp->setOperand(1, NewBoundValue);
416344a3780SDimitry Andric 
417344a3780SDimitry Andric   // Replace SplitCandidateCond.BI's condition of pre-loop by True.
418344a3780SDimitry Andric   LLVMContext &Context = PreHeader->getContext();
419344a3780SDimitry Andric   SplitCandidateCond.BI->setCondition(ConstantInt::getTrue(Context));
420344a3780SDimitry Andric 
421344a3780SDimitry Andric   // Replace cloned SplitCandidateCond.BI's condition in post-loop by False.
422344a3780SDimitry Andric   BranchInst *ClonedSplitCandidateBI =
423344a3780SDimitry Andric       cast<BranchInst>(VMap[SplitCandidateCond.BI]);
424344a3780SDimitry Andric   ClonedSplitCandidateBI->setCondition(ConstantInt::getFalse(Context));
425344a3780SDimitry Andric 
426344a3780SDimitry Andric   // Replace exit branch target of pre-loop by post-loop's preheader.
427344a3780SDimitry Andric   if (L.getExitBlock() == ExitingCond.BI->getSuccessor(0))
428344a3780SDimitry Andric     ExitingCond.BI->setSuccessor(0, PostLoopPreHeader);
429344a3780SDimitry Andric   else
430344a3780SDimitry Andric     ExitingCond.BI->setSuccessor(1, PostLoopPreHeader);
431344a3780SDimitry Andric 
432c0981da4SDimitry Andric   // Update phi node in exit block of post-loop.
433b1c73532SDimitry Andric   Builder.SetInsertPoint(PostLoopPreHeader, PostLoopPreHeader->begin());
434c0981da4SDimitry Andric   for (PHINode &PN : PostLoop->getExitBlock()->phis()) {
435c0981da4SDimitry Andric     for (auto i : seq<int>(0, PN.getNumOperands())) {
436c0981da4SDimitry Andric       // Check incoming block is pre-loop's exiting block.
437c0981da4SDimitry Andric       if (PN.getIncomingBlock(i) == L.getExitingBlock()) {
438c0981da4SDimitry Andric         Value *IncomingValue = PN.getIncomingValue(i);
439c0981da4SDimitry Andric 
440c0981da4SDimitry Andric         // Create LCSSA phi node for incoming value.
441c0981da4SDimitry Andric         PHINode *LCSSAPhi =
442c0981da4SDimitry Andric             Builder.CreatePHI(PN.getType(), 1, PN.getName() + ".lcssa");
443c0981da4SDimitry Andric         LCSSAPhi->setDebugLoc(PN.getDebugLoc());
444c0981da4SDimitry Andric         LCSSAPhi->addIncoming(IncomingValue, PN.getIncomingBlock(i));
445c0981da4SDimitry Andric 
446c0981da4SDimitry Andric         // Replace pre-loop's exiting block by post-loop's preheader.
447c0981da4SDimitry Andric         PN.setIncomingBlock(i, PostLoopPreHeader);
448c0981da4SDimitry Andric         // Replace incoming value by LCSSAPhi.
449c0981da4SDimitry Andric         PN.setIncomingValue(i, LCSSAPhi);
450c0981da4SDimitry Andric         // Add a new incoming value with post-loop's exiting block.
451c0981da4SDimitry Andric         PN.addIncoming(VMap[IncomingValue], PostLoop->getExitingBlock());
452c0981da4SDimitry Andric       }
453c0981da4SDimitry Andric     }
454c0981da4SDimitry Andric   }
455c0981da4SDimitry Andric 
456344a3780SDimitry Andric   // Update dominator tree.
457344a3780SDimitry Andric   DT.changeImmediateDominator(PostLoopPreHeader, L.getExitingBlock());
458344a3780SDimitry Andric   DT.changeImmediateDominator(PostLoop->getExitBlock(), PostLoopPreHeader);
459344a3780SDimitry Andric 
460344a3780SDimitry Andric   // Invalidate cached SE information.
461344a3780SDimitry Andric   SE.forgetLoop(&L);
462344a3780SDimitry Andric 
463344a3780SDimitry Andric   // Canonicalize loops.
464344a3780SDimitry Andric   simplifyLoop(&L, &DT, &LI, &SE, nullptr, nullptr, true);
465344a3780SDimitry Andric   simplifyLoop(PostLoop, &DT, &LI, &SE, nullptr, nullptr, true);
466344a3780SDimitry Andric 
467344a3780SDimitry Andric   // Add new post-loop to loop pass manager.
468344a3780SDimitry Andric   U.addSiblingLoops(PostLoop);
469344a3780SDimitry Andric 
470344a3780SDimitry Andric   return true;
471344a3780SDimitry Andric }
472344a3780SDimitry Andric 
run(Loop & L,LoopAnalysisManager & AM,LoopStandardAnalysisResults & AR,LPMUpdater & U)473344a3780SDimitry Andric PreservedAnalyses LoopBoundSplitPass::run(Loop &L, LoopAnalysisManager &AM,
474344a3780SDimitry Andric                                           LoopStandardAnalysisResults &AR,
475344a3780SDimitry Andric                                           LPMUpdater &U) {
476344a3780SDimitry Andric   Function &F = *L.getHeader()->getParent();
477344a3780SDimitry Andric   (void)F;
478344a3780SDimitry Andric 
479344a3780SDimitry Andric   LLVM_DEBUG(dbgs() << "Spliting bound of loop in " << F.getName() << ": " << L
480344a3780SDimitry Andric                     << "\n");
481344a3780SDimitry Andric 
482344a3780SDimitry Andric   if (!splitLoopBound(L, AR.DT, AR.LI, AR.SE, U))
483344a3780SDimitry Andric     return PreservedAnalyses::all();
484344a3780SDimitry Andric 
485344a3780SDimitry Andric   assert(AR.DT.verify(DominatorTree::VerificationLevel::Fast));
486344a3780SDimitry Andric   AR.LI.verify(AR.DT);
487344a3780SDimitry Andric 
488344a3780SDimitry Andric   return getLoopPassPreservedAnalyses();
489344a3780SDimitry Andric }
490344a3780SDimitry Andric 
491344a3780SDimitry Andric } // end namespace llvm
492