xref: /aosp_15_r20/external/llvm/lib/Transforms/Utils/LoopUtils.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- LoopUtils.cpp - Loop Utility functions -------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file defines common loop utility functions.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/AliasAnalysis.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/BasicAliasAnalysis.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/LoopInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/GlobalsModRef.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolution.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolutionExpander.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolutionExpressions.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Dominators.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/PatternMatch.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/ValueHandle.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Pass.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/LoopUtils.h"
30*9880d681SAndroid Build Coastguard Worker 
31*9880d681SAndroid Build Coastguard Worker using namespace llvm;
32*9880d681SAndroid Build Coastguard Worker using namespace llvm::PatternMatch;
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "loop-utils"
35*9880d681SAndroid Build Coastguard Worker 
areAllUsesIn(Instruction * I,SmallPtrSetImpl<Instruction * > & Set)36*9880d681SAndroid Build Coastguard Worker bool RecurrenceDescriptor::areAllUsesIn(Instruction *I,
37*9880d681SAndroid Build Coastguard Worker                                         SmallPtrSetImpl<Instruction *> &Set) {
38*9880d681SAndroid Build Coastguard Worker   for (User::op_iterator Use = I->op_begin(), E = I->op_end(); Use != E; ++Use)
39*9880d681SAndroid Build Coastguard Worker     if (!Set.count(dyn_cast<Instruction>(*Use)))
40*9880d681SAndroid Build Coastguard Worker       return false;
41*9880d681SAndroid Build Coastguard Worker   return true;
42*9880d681SAndroid Build Coastguard Worker }
43*9880d681SAndroid Build Coastguard Worker 
isIntegerRecurrenceKind(RecurrenceKind Kind)44*9880d681SAndroid Build Coastguard Worker bool RecurrenceDescriptor::isIntegerRecurrenceKind(RecurrenceKind Kind) {
45*9880d681SAndroid Build Coastguard Worker   switch (Kind) {
46*9880d681SAndroid Build Coastguard Worker   default:
47*9880d681SAndroid Build Coastguard Worker     break;
48*9880d681SAndroid Build Coastguard Worker   case RK_IntegerAdd:
49*9880d681SAndroid Build Coastguard Worker   case RK_IntegerMult:
50*9880d681SAndroid Build Coastguard Worker   case RK_IntegerOr:
51*9880d681SAndroid Build Coastguard Worker   case RK_IntegerAnd:
52*9880d681SAndroid Build Coastguard Worker   case RK_IntegerXor:
53*9880d681SAndroid Build Coastguard Worker   case RK_IntegerMinMax:
54*9880d681SAndroid Build Coastguard Worker     return true;
55*9880d681SAndroid Build Coastguard Worker   }
56*9880d681SAndroid Build Coastguard Worker   return false;
57*9880d681SAndroid Build Coastguard Worker }
58*9880d681SAndroid Build Coastguard Worker 
isFloatingPointRecurrenceKind(RecurrenceKind Kind)59*9880d681SAndroid Build Coastguard Worker bool RecurrenceDescriptor::isFloatingPointRecurrenceKind(RecurrenceKind Kind) {
60*9880d681SAndroid Build Coastguard Worker   return (Kind != RK_NoRecurrence) && !isIntegerRecurrenceKind(Kind);
61*9880d681SAndroid Build Coastguard Worker }
62*9880d681SAndroid Build Coastguard Worker 
isArithmeticRecurrenceKind(RecurrenceKind Kind)63*9880d681SAndroid Build Coastguard Worker bool RecurrenceDescriptor::isArithmeticRecurrenceKind(RecurrenceKind Kind) {
64*9880d681SAndroid Build Coastguard Worker   switch (Kind) {
65*9880d681SAndroid Build Coastguard Worker   default:
66*9880d681SAndroid Build Coastguard Worker     break;
67*9880d681SAndroid Build Coastguard Worker   case RK_IntegerAdd:
68*9880d681SAndroid Build Coastguard Worker   case RK_IntegerMult:
69*9880d681SAndroid Build Coastguard Worker   case RK_FloatAdd:
70*9880d681SAndroid Build Coastguard Worker   case RK_FloatMult:
71*9880d681SAndroid Build Coastguard Worker     return true;
72*9880d681SAndroid Build Coastguard Worker   }
73*9880d681SAndroid Build Coastguard Worker   return false;
74*9880d681SAndroid Build Coastguard Worker }
75*9880d681SAndroid Build Coastguard Worker 
76*9880d681SAndroid Build Coastguard Worker Instruction *
lookThroughAnd(PHINode * Phi,Type * & RT,SmallPtrSetImpl<Instruction * > & Visited,SmallPtrSetImpl<Instruction * > & CI)77*9880d681SAndroid Build Coastguard Worker RecurrenceDescriptor::lookThroughAnd(PHINode *Phi, Type *&RT,
78*9880d681SAndroid Build Coastguard Worker                                      SmallPtrSetImpl<Instruction *> &Visited,
79*9880d681SAndroid Build Coastguard Worker                                      SmallPtrSetImpl<Instruction *> &CI) {
80*9880d681SAndroid Build Coastguard Worker   if (!Phi->hasOneUse())
81*9880d681SAndroid Build Coastguard Worker     return Phi;
82*9880d681SAndroid Build Coastguard Worker 
83*9880d681SAndroid Build Coastguard Worker   const APInt *M = nullptr;
84*9880d681SAndroid Build Coastguard Worker   Instruction *I, *J = cast<Instruction>(Phi->use_begin()->getUser());
85*9880d681SAndroid Build Coastguard Worker 
86*9880d681SAndroid Build Coastguard Worker   // Matches either I & 2^x-1 or 2^x-1 & I. If we find a match, we update RT
87*9880d681SAndroid Build Coastguard Worker   // with a new integer type of the corresponding bit width.
88*9880d681SAndroid Build Coastguard Worker   if (match(J, m_CombineOr(m_And(m_Instruction(I), m_APInt(M)),
89*9880d681SAndroid Build Coastguard Worker                            m_And(m_APInt(M), m_Instruction(I))))) {
90*9880d681SAndroid Build Coastguard Worker     int32_t Bits = (*M + 1).exactLogBase2();
91*9880d681SAndroid Build Coastguard Worker     if (Bits > 0) {
92*9880d681SAndroid Build Coastguard Worker       RT = IntegerType::get(Phi->getContext(), Bits);
93*9880d681SAndroid Build Coastguard Worker       Visited.insert(Phi);
94*9880d681SAndroid Build Coastguard Worker       CI.insert(J);
95*9880d681SAndroid Build Coastguard Worker       return J;
96*9880d681SAndroid Build Coastguard Worker     }
97*9880d681SAndroid Build Coastguard Worker   }
98*9880d681SAndroid Build Coastguard Worker   return Phi;
99*9880d681SAndroid Build Coastguard Worker }
100*9880d681SAndroid Build Coastguard Worker 
getSourceExtensionKind(Instruction * Start,Instruction * Exit,Type * RT,bool & IsSigned,SmallPtrSetImpl<Instruction * > & Visited,SmallPtrSetImpl<Instruction * > & CI)101*9880d681SAndroid Build Coastguard Worker bool RecurrenceDescriptor::getSourceExtensionKind(
102*9880d681SAndroid Build Coastguard Worker     Instruction *Start, Instruction *Exit, Type *RT, bool &IsSigned,
103*9880d681SAndroid Build Coastguard Worker     SmallPtrSetImpl<Instruction *> &Visited,
104*9880d681SAndroid Build Coastguard Worker     SmallPtrSetImpl<Instruction *> &CI) {
105*9880d681SAndroid Build Coastguard Worker 
106*9880d681SAndroid Build Coastguard Worker   SmallVector<Instruction *, 8> Worklist;
107*9880d681SAndroid Build Coastguard Worker   bool FoundOneOperand = false;
108*9880d681SAndroid Build Coastguard Worker   unsigned DstSize = RT->getPrimitiveSizeInBits();
109*9880d681SAndroid Build Coastguard Worker   Worklist.push_back(Exit);
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker   // Traverse the instructions in the reduction expression, beginning with the
112*9880d681SAndroid Build Coastguard Worker   // exit value.
113*9880d681SAndroid Build Coastguard Worker   while (!Worklist.empty()) {
114*9880d681SAndroid Build Coastguard Worker     Instruction *I = Worklist.pop_back_val();
115*9880d681SAndroid Build Coastguard Worker     for (Use &U : I->operands()) {
116*9880d681SAndroid Build Coastguard Worker 
117*9880d681SAndroid Build Coastguard Worker       // Terminate the traversal if the operand is not an instruction, or we
118*9880d681SAndroid Build Coastguard Worker       // reach the starting value.
119*9880d681SAndroid Build Coastguard Worker       Instruction *J = dyn_cast<Instruction>(U.get());
120*9880d681SAndroid Build Coastguard Worker       if (!J || J == Start)
121*9880d681SAndroid Build Coastguard Worker         continue;
122*9880d681SAndroid Build Coastguard Worker 
123*9880d681SAndroid Build Coastguard Worker       // Otherwise, investigate the operation if it is also in the expression.
124*9880d681SAndroid Build Coastguard Worker       if (Visited.count(J)) {
125*9880d681SAndroid Build Coastguard Worker         Worklist.push_back(J);
126*9880d681SAndroid Build Coastguard Worker         continue;
127*9880d681SAndroid Build Coastguard Worker       }
128*9880d681SAndroid Build Coastguard Worker 
129*9880d681SAndroid Build Coastguard Worker       // If the operand is not in Visited, it is not a reduction operation, but
130*9880d681SAndroid Build Coastguard Worker       // it does feed into one. Make sure it is either a single-use sign- or
131*9880d681SAndroid Build Coastguard Worker       // zero-extend instruction.
132*9880d681SAndroid Build Coastguard Worker       CastInst *Cast = dyn_cast<CastInst>(J);
133*9880d681SAndroid Build Coastguard Worker       bool IsSExtInst = isa<SExtInst>(J);
134*9880d681SAndroid Build Coastguard Worker       if (!Cast || !Cast->hasOneUse() || !(isa<ZExtInst>(J) || IsSExtInst))
135*9880d681SAndroid Build Coastguard Worker         return false;
136*9880d681SAndroid Build Coastguard Worker 
137*9880d681SAndroid Build Coastguard Worker       // Ensure the source type of the extend is no larger than the reduction
138*9880d681SAndroid Build Coastguard Worker       // type. It is not necessary for the types to be identical.
139*9880d681SAndroid Build Coastguard Worker       unsigned SrcSize = Cast->getSrcTy()->getPrimitiveSizeInBits();
140*9880d681SAndroid Build Coastguard Worker       if (SrcSize > DstSize)
141*9880d681SAndroid Build Coastguard Worker         return false;
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker       // Furthermore, ensure that all such extends are of the same kind.
144*9880d681SAndroid Build Coastguard Worker       if (FoundOneOperand) {
145*9880d681SAndroid Build Coastguard Worker         if (IsSigned != IsSExtInst)
146*9880d681SAndroid Build Coastguard Worker           return false;
147*9880d681SAndroid Build Coastguard Worker       } else {
148*9880d681SAndroid Build Coastguard Worker         FoundOneOperand = true;
149*9880d681SAndroid Build Coastguard Worker         IsSigned = IsSExtInst;
150*9880d681SAndroid Build Coastguard Worker       }
151*9880d681SAndroid Build Coastguard Worker 
152*9880d681SAndroid Build Coastguard Worker       // Lastly, if the source type of the extend matches the reduction type,
153*9880d681SAndroid Build Coastguard Worker       // add the extend to CI so that we can avoid accounting for it in the
154*9880d681SAndroid Build Coastguard Worker       // cost model.
155*9880d681SAndroid Build Coastguard Worker       if (SrcSize == DstSize)
156*9880d681SAndroid Build Coastguard Worker         CI.insert(Cast);
157*9880d681SAndroid Build Coastguard Worker     }
158*9880d681SAndroid Build Coastguard Worker   }
159*9880d681SAndroid Build Coastguard Worker   return true;
160*9880d681SAndroid Build Coastguard Worker }
161*9880d681SAndroid Build Coastguard Worker 
AddReductionVar(PHINode * Phi,RecurrenceKind Kind,Loop * TheLoop,bool HasFunNoNaNAttr,RecurrenceDescriptor & RedDes)162*9880d681SAndroid Build Coastguard Worker bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurrenceKind Kind,
163*9880d681SAndroid Build Coastguard Worker                                            Loop *TheLoop, bool HasFunNoNaNAttr,
164*9880d681SAndroid Build Coastguard Worker                                            RecurrenceDescriptor &RedDes) {
165*9880d681SAndroid Build Coastguard Worker   if (Phi->getNumIncomingValues() != 2)
166*9880d681SAndroid Build Coastguard Worker     return false;
167*9880d681SAndroid Build Coastguard Worker 
168*9880d681SAndroid Build Coastguard Worker   // Reduction variables are only found in the loop header block.
169*9880d681SAndroid Build Coastguard Worker   if (Phi->getParent() != TheLoop->getHeader())
170*9880d681SAndroid Build Coastguard Worker     return false;
171*9880d681SAndroid Build Coastguard Worker 
172*9880d681SAndroid Build Coastguard Worker   // Obtain the reduction start value from the value that comes from the loop
173*9880d681SAndroid Build Coastguard Worker   // preheader.
174*9880d681SAndroid Build Coastguard Worker   Value *RdxStart = Phi->getIncomingValueForBlock(TheLoop->getLoopPreheader());
175*9880d681SAndroid Build Coastguard Worker 
176*9880d681SAndroid Build Coastguard Worker   // ExitInstruction is the single value which is used outside the loop.
177*9880d681SAndroid Build Coastguard Worker   // We only allow for a single reduction value to be used outside the loop.
178*9880d681SAndroid Build Coastguard Worker   // This includes users of the reduction, variables (which form a cycle
179*9880d681SAndroid Build Coastguard Worker   // which ends in the phi node).
180*9880d681SAndroid Build Coastguard Worker   Instruction *ExitInstruction = nullptr;
181*9880d681SAndroid Build Coastguard Worker   // Indicates that we found a reduction operation in our scan.
182*9880d681SAndroid Build Coastguard Worker   bool FoundReduxOp = false;
183*9880d681SAndroid Build Coastguard Worker 
184*9880d681SAndroid Build Coastguard Worker   // We start with the PHI node and scan for all of the users of this
185*9880d681SAndroid Build Coastguard Worker   // instruction. All users must be instructions that can be used as reduction
186*9880d681SAndroid Build Coastguard Worker   // variables (such as ADD). We must have a single out-of-block user. The cycle
187*9880d681SAndroid Build Coastguard Worker   // must include the original PHI.
188*9880d681SAndroid Build Coastguard Worker   bool FoundStartPHI = false;
189*9880d681SAndroid Build Coastguard Worker 
190*9880d681SAndroid Build Coastguard Worker   // To recognize min/max patterns formed by a icmp select sequence, we store
191*9880d681SAndroid Build Coastguard Worker   // the number of instruction we saw from the recognized min/max pattern,
192*9880d681SAndroid Build Coastguard Worker   //  to make sure we only see exactly the two instructions.
193*9880d681SAndroid Build Coastguard Worker   unsigned NumCmpSelectPatternInst = 0;
194*9880d681SAndroid Build Coastguard Worker   InstDesc ReduxDesc(false, nullptr);
195*9880d681SAndroid Build Coastguard Worker 
196*9880d681SAndroid Build Coastguard Worker   // Data used for determining if the recurrence has been type-promoted.
197*9880d681SAndroid Build Coastguard Worker   Type *RecurrenceType = Phi->getType();
198*9880d681SAndroid Build Coastguard Worker   SmallPtrSet<Instruction *, 4> CastInsts;
199*9880d681SAndroid Build Coastguard Worker   Instruction *Start = Phi;
200*9880d681SAndroid Build Coastguard Worker   bool IsSigned = false;
201*9880d681SAndroid Build Coastguard Worker 
202*9880d681SAndroid Build Coastguard Worker   SmallPtrSet<Instruction *, 8> VisitedInsts;
203*9880d681SAndroid Build Coastguard Worker   SmallVector<Instruction *, 8> Worklist;
204*9880d681SAndroid Build Coastguard Worker 
205*9880d681SAndroid Build Coastguard Worker   // Return early if the recurrence kind does not match the type of Phi. If the
206*9880d681SAndroid Build Coastguard Worker   // recurrence kind is arithmetic, we attempt to look through AND operations
207*9880d681SAndroid Build Coastguard Worker   // resulting from the type promotion performed by InstCombine.  Vector
208*9880d681SAndroid Build Coastguard Worker   // operations are not limited to the legal integer widths, so we may be able
209*9880d681SAndroid Build Coastguard Worker   // to evaluate the reduction in the narrower width.
210*9880d681SAndroid Build Coastguard Worker   if (RecurrenceType->isFloatingPointTy()) {
211*9880d681SAndroid Build Coastguard Worker     if (!isFloatingPointRecurrenceKind(Kind))
212*9880d681SAndroid Build Coastguard Worker       return false;
213*9880d681SAndroid Build Coastguard Worker   } else {
214*9880d681SAndroid Build Coastguard Worker     if (!isIntegerRecurrenceKind(Kind))
215*9880d681SAndroid Build Coastguard Worker       return false;
216*9880d681SAndroid Build Coastguard Worker     if (isArithmeticRecurrenceKind(Kind))
217*9880d681SAndroid Build Coastguard Worker       Start = lookThroughAnd(Phi, RecurrenceType, VisitedInsts, CastInsts);
218*9880d681SAndroid Build Coastguard Worker   }
219*9880d681SAndroid Build Coastguard Worker 
220*9880d681SAndroid Build Coastguard Worker   Worklist.push_back(Start);
221*9880d681SAndroid Build Coastguard Worker   VisitedInsts.insert(Start);
222*9880d681SAndroid Build Coastguard Worker 
223*9880d681SAndroid Build Coastguard Worker   // A value in the reduction can be used:
224*9880d681SAndroid Build Coastguard Worker   //  - By the reduction:
225*9880d681SAndroid Build Coastguard Worker   //      - Reduction operation:
226*9880d681SAndroid Build Coastguard Worker   //        - One use of reduction value (safe).
227*9880d681SAndroid Build Coastguard Worker   //        - Multiple use of reduction value (not safe).
228*9880d681SAndroid Build Coastguard Worker   //      - PHI:
229*9880d681SAndroid Build Coastguard Worker   //        - All uses of the PHI must be the reduction (safe).
230*9880d681SAndroid Build Coastguard Worker   //        - Otherwise, not safe.
231*9880d681SAndroid Build Coastguard Worker   //  - By one instruction outside of the loop (safe).
232*9880d681SAndroid Build Coastguard Worker   //  - By further instructions outside of the loop (not safe).
233*9880d681SAndroid Build Coastguard Worker   //  - By an instruction that is not part of the reduction (not safe).
234*9880d681SAndroid Build Coastguard Worker   //    This is either:
235*9880d681SAndroid Build Coastguard Worker   //      * An instruction type other than PHI or the reduction operation.
236*9880d681SAndroid Build Coastguard Worker   //      * A PHI in the header other than the initial PHI.
237*9880d681SAndroid Build Coastguard Worker   while (!Worklist.empty()) {
238*9880d681SAndroid Build Coastguard Worker     Instruction *Cur = Worklist.back();
239*9880d681SAndroid Build Coastguard Worker     Worklist.pop_back();
240*9880d681SAndroid Build Coastguard Worker 
241*9880d681SAndroid Build Coastguard Worker     // No Users.
242*9880d681SAndroid Build Coastguard Worker     // If the instruction has no users then this is a broken chain and can't be
243*9880d681SAndroid Build Coastguard Worker     // a reduction variable.
244*9880d681SAndroid Build Coastguard Worker     if (Cur->use_empty())
245*9880d681SAndroid Build Coastguard Worker       return false;
246*9880d681SAndroid Build Coastguard Worker 
247*9880d681SAndroid Build Coastguard Worker     bool IsAPhi = isa<PHINode>(Cur);
248*9880d681SAndroid Build Coastguard Worker 
249*9880d681SAndroid Build Coastguard Worker     // A header PHI use other than the original PHI.
250*9880d681SAndroid Build Coastguard Worker     if (Cur != Phi && IsAPhi && Cur->getParent() == Phi->getParent())
251*9880d681SAndroid Build Coastguard Worker       return false;
252*9880d681SAndroid Build Coastguard Worker 
253*9880d681SAndroid Build Coastguard Worker     // Reductions of instructions such as Div, and Sub is only possible if the
254*9880d681SAndroid Build Coastguard Worker     // LHS is the reduction variable.
255*9880d681SAndroid Build Coastguard Worker     if (!Cur->isCommutative() && !IsAPhi && !isa<SelectInst>(Cur) &&
256*9880d681SAndroid Build Coastguard Worker         !isa<ICmpInst>(Cur) && !isa<FCmpInst>(Cur) &&
257*9880d681SAndroid Build Coastguard Worker         !VisitedInsts.count(dyn_cast<Instruction>(Cur->getOperand(0))))
258*9880d681SAndroid Build Coastguard Worker       return false;
259*9880d681SAndroid Build Coastguard Worker 
260*9880d681SAndroid Build Coastguard Worker     // Any reduction instruction must be of one of the allowed kinds. We ignore
261*9880d681SAndroid Build Coastguard Worker     // the starting value (the Phi or an AND instruction if the Phi has been
262*9880d681SAndroid Build Coastguard Worker     // type-promoted).
263*9880d681SAndroid Build Coastguard Worker     if (Cur != Start) {
264*9880d681SAndroid Build Coastguard Worker       ReduxDesc = isRecurrenceInstr(Cur, Kind, ReduxDesc, HasFunNoNaNAttr);
265*9880d681SAndroid Build Coastguard Worker       if (!ReduxDesc.isRecurrence())
266*9880d681SAndroid Build Coastguard Worker         return false;
267*9880d681SAndroid Build Coastguard Worker     }
268*9880d681SAndroid Build Coastguard Worker 
269*9880d681SAndroid Build Coastguard Worker     // A reduction operation must only have one use of the reduction value.
270*9880d681SAndroid Build Coastguard Worker     if (!IsAPhi && Kind != RK_IntegerMinMax && Kind != RK_FloatMinMax &&
271*9880d681SAndroid Build Coastguard Worker         hasMultipleUsesOf(Cur, VisitedInsts))
272*9880d681SAndroid Build Coastguard Worker       return false;
273*9880d681SAndroid Build Coastguard Worker 
274*9880d681SAndroid Build Coastguard Worker     // All inputs to a PHI node must be a reduction value.
275*9880d681SAndroid Build Coastguard Worker     if (IsAPhi && Cur != Phi && !areAllUsesIn(Cur, VisitedInsts))
276*9880d681SAndroid Build Coastguard Worker       return false;
277*9880d681SAndroid Build Coastguard Worker 
278*9880d681SAndroid Build Coastguard Worker     if (Kind == RK_IntegerMinMax &&
279*9880d681SAndroid Build Coastguard Worker         (isa<ICmpInst>(Cur) || isa<SelectInst>(Cur)))
280*9880d681SAndroid Build Coastguard Worker       ++NumCmpSelectPatternInst;
281*9880d681SAndroid Build Coastguard Worker     if (Kind == RK_FloatMinMax && (isa<FCmpInst>(Cur) || isa<SelectInst>(Cur)))
282*9880d681SAndroid Build Coastguard Worker       ++NumCmpSelectPatternInst;
283*9880d681SAndroid Build Coastguard Worker 
284*9880d681SAndroid Build Coastguard Worker     // Check  whether we found a reduction operator.
285*9880d681SAndroid Build Coastguard Worker     FoundReduxOp |= !IsAPhi && Cur != Start;
286*9880d681SAndroid Build Coastguard Worker 
287*9880d681SAndroid Build Coastguard Worker     // Process users of current instruction. Push non-PHI nodes after PHI nodes
288*9880d681SAndroid Build Coastguard Worker     // onto the stack. This way we are going to have seen all inputs to PHI
289*9880d681SAndroid Build Coastguard Worker     // nodes once we get to them.
290*9880d681SAndroid Build Coastguard Worker     SmallVector<Instruction *, 8> NonPHIs;
291*9880d681SAndroid Build Coastguard Worker     SmallVector<Instruction *, 8> PHIs;
292*9880d681SAndroid Build Coastguard Worker     for (User *U : Cur->users()) {
293*9880d681SAndroid Build Coastguard Worker       Instruction *UI = cast<Instruction>(U);
294*9880d681SAndroid Build Coastguard Worker 
295*9880d681SAndroid Build Coastguard Worker       // Check if we found the exit user.
296*9880d681SAndroid Build Coastguard Worker       BasicBlock *Parent = UI->getParent();
297*9880d681SAndroid Build Coastguard Worker       if (!TheLoop->contains(Parent)) {
298*9880d681SAndroid Build Coastguard Worker         // Exit if you find multiple outside users or if the header phi node is
299*9880d681SAndroid Build Coastguard Worker         // being used. In this case the user uses the value of the previous
300*9880d681SAndroid Build Coastguard Worker         // iteration, in which case we would loose "VF-1" iterations of the
301*9880d681SAndroid Build Coastguard Worker         // reduction operation if we vectorize.
302*9880d681SAndroid Build Coastguard Worker         if (ExitInstruction != nullptr || Cur == Phi)
303*9880d681SAndroid Build Coastguard Worker           return false;
304*9880d681SAndroid Build Coastguard Worker 
305*9880d681SAndroid Build Coastguard Worker         // The instruction used by an outside user must be the last instruction
306*9880d681SAndroid Build Coastguard Worker         // before we feed back to the reduction phi. Otherwise, we loose VF-1
307*9880d681SAndroid Build Coastguard Worker         // operations on the value.
308*9880d681SAndroid Build Coastguard Worker         if (std::find(Phi->op_begin(), Phi->op_end(), Cur) == Phi->op_end())
309*9880d681SAndroid Build Coastguard Worker           return false;
310*9880d681SAndroid Build Coastguard Worker 
311*9880d681SAndroid Build Coastguard Worker         ExitInstruction = Cur;
312*9880d681SAndroid Build Coastguard Worker         continue;
313*9880d681SAndroid Build Coastguard Worker       }
314*9880d681SAndroid Build Coastguard Worker 
315*9880d681SAndroid Build Coastguard Worker       // Process instructions only once (termination). Each reduction cycle
316*9880d681SAndroid Build Coastguard Worker       // value must only be used once, except by phi nodes and min/max
317*9880d681SAndroid Build Coastguard Worker       // reductions which are represented as a cmp followed by a select.
318*9880d681SAndroid Build Coastguard Worker       InstDesc IgnoredVal(false, nullptr);
319*9880d681SAndroid Build Coastguard Worker       if (VisitedInsts.insert(UI).second) {
320*9880d681SAndroid Build Coastguard Worker         if (isa<PHINode>(UI))
321*9880d681SAndroid Build Coastguard Worker           PHIs.push_back(UI);
322*9880d681SAndroid Build Coastguard Worker         else
323*9880d681SAndroid Build Coastguard Worker           NonPHIs.push_back(UI);
324*9880d681SAndroid Build Coastguard Worker       } else if (!isa<PHINode>(UI) &&
325*9880d681SAndroid Build Coastguard Worker                  ((!isa<FCmpInst>(UI) && !isa<ICmpInst>(UI) &&
326*9880d681SAndroid Build Coastguard Worker                    !isa<SelectInst>(UI)) ||
327*9880d681SAndroid Build Coastguard Worker                   !isMinMaxSelectCmpPattern(UI, IgnoredVal).isRecurrence()))
328*9880d681SAndroid Build Coastguard Worker         return false;
329*9880d681SAndroid Build Coastguard Worker 
330*9880d681SAndroid Build Coastguard Worker       // Remember that we completed the cycle.
331*9880d681SAndroid Build Coastguard Worker       if (UI == Phi)
332*9880d681SAndroid Build Coastguard Worker         FoundStartPHI = true;
333*9880d681SAndroid Build Coastguard Worker     }
334*9880d681SAndroid Build Coastguard Worker     Worklist.append(PHIs.begin(), PHIs.end());
335*9880d681SAndroid Build Coastguard Worker     Worklist.append(NonPHIs.begin(), NonPHIs.end());
336*9880d681SAndroid Build Coastguard Worker   }
337*9880d681SAndroid Build Coastguard Worker 
338*9880d681SAndroid Build Coastguard Worker   // This means we have seen one but not the other instruction of the
339*9880d681SAndroid Build Coastguard Worker   // pattern or more than just a select and cmp.
340*9880d681SAndroid Build Coastguard Worker   if ((Kind == RK_IntegerMinMax || Kind == RK_FloatMinMax) &&
341*9880d681SAndroid Build Coastguard Worker       NumCmpSelectPatternInst != 2)
342*9880d681SAndroid Build Coastguard Worker     return false;
343*9880d681SAndroid Build Coastguard Worker 
344*9880d681SAndroid Build Coastguard Worker   if (!FoundStartPHI || !FoundReduxOp || !ExitInstruction)
345*9880d681SAndroid Build Coastguard Worker     return false;
346*9880d681SAndroid Build Coastguard Worker 
347*9880d681SAndroid Build Coastguard Worker   // If we think Phi may have been type-promoted, we also need to ensure that
348*9880d681SAndroid Build Coastguard Worker   // all source operands of the reduction are either SExtInsts or ZEstInsts. If
349*9880d681SAndroid Build Coastguard Worker   // so, we will be able to evaluate the reduction in the narrower bit width.
350*9880d681SAndroid Build Coastguard Worker   if (Start != Phi)
351*9880d681SAndroid Build Coastguard Worker     if (!getSourceExtensionKind(Start, ExitInstruction, RecurrenceType,
352*9880d681SAndroid Build Coastguard Worker                                 IsSigned, VisitedInsts, CastInsts))
353*9880d681SAndroid Build Coastguard Worker       return false;
354*9880d681SAndroid Build Coastguard Worker 
355*9880d681SAndroid Build Coastguard Worker   // We found a reduction var if we have reached the original phi node and we
356*9880d681SAndroid Build Coastguard Worker   // only have a single instruction with out-of-loop users.
357*9880d681SAndroid Build Coastguard Worker 
358*9880d681SAndroid Build Coastguard Worker   // The ExitInstruction(Instruction which is allowed to have out-of-loop users)
359*9880d681SAndroid Build Coastguard Worker   // is saved as part of the RecurrenceDescriptor.
360*9880d681SAndroid Build Coastguard Worker 
361*9880d681SAndroid Build Coastguard Worker   // Save the description of this reduction variable.
362*9880d681SAndroid Build Coastguard Worker   RecurrenceDescriptor RD(
363*9880d681SAndroid Build Coastguard Worker       RdxStart, ExitInstruction, Kind, ReduxDesc.getMinMaxKind(),
364*9880d681SAndroid Build Coastguard Worker       ReduxDesc.getUnsafeAlgebraInst(), RecurrenceType, IsSigned, CastInsts);
365*9880d681SAndroid Build Coastguard Worker   RedDes = RD;
366*9880d681SAndroid Build Coastguard Worker 
367*9880d681SAndroid Build Coastguard Worker   return true;
368*9880d681SAndroid Build Coastguard Worker }
369*9880d681SAndroid Build Coastguard Worker 
370*9880d681SAndroid Build Coastguard Worker /// Returns true if the instruction is a Select(ICmp(X, Y), X, Y) instruction
371*9880d681SAndroid Build Coastguard Worker /// pattern corresponding to a min(X, Y) or max(X, Y).
372*9880d681SAndroid Build Coastguard Worker RecurrenceDescriptor::InstDesc
isMinMaxSelectCmpPattern(Instruction * I,InstDesc & Prev)373*9880d681SAndroid Build Coastguard Worker RecurrenceDescriptor::isMinMaxSelectCmpPattern(Instruction *I, InstDesc &Prev) {
374*9880d681SAndroid Build Coastguard Worker 
375*9880d681SAndroid Build Coastguard Worker   assert((isa<ICmpInst>(I) || isa<FCmpInst>(I) || isa<SelectInst>(I)) &&
376*9880d681SAndroid Build Coastguard Worker          "Expect a select instruction");
377*9880d681SAndroid Build Coastguard Worker   Instruction *Cmp = nullptr;
378*9880d681SAndroid Build Coastguard Worker   SelectInst *Select = nullptr;
379*9880d681SAndroid Build Coastguard Worker 
380*9880d681SAndroid Build Coastguard Worker   // We must handle the select(cmp()) as a single instruction. Advance to the
381*9880d681SAndroid Build Coastguard Worker   // select.
382*9880d681SAndroid Build Coastguard Worker   if ((Cmp = dyn_cast<ICmpInst>(I)) || (Cmp = dyn_cast<FCmpInst>(I))) {
383*9880d681SAndroid Build Coastguard Worker     if (!Cmp->hasOneUse() || !(Select = dyn_cast<SelectInst>(*I->user_begin())))
384*9880d681SAndroid Build Coastguard Worker       return InstDesc(false, I);
385*9880d681SAndroid Build Coastguard Worker     return InstDesc(Select, Prev.getMinMaxKind());
386*9880d681SAndroid Build Coastguard Worker   }
387*9880d681SAndroid Build Coastguard Worker 
388*9880d681SAndroid Build Coastguard Worker   // Only handle single use cases for now.
389*9880d681SAndroid Build Coastguard Worker   if (!(Select = dyn_cast<SelectInst>(I)))
390*9880d681SAndroid Build Coastguard Worker     return InstDesc(false, I);
391*9880d681SAndroid Build Coastguard Worker   if (!(Cmp = dyn_cast<ICmpInst>(I->getOperand(0))) &&
392*9880d681SAndroid Build Coastguard Worker       !(Cmp = dyn_cast<FCmpInst>(I->getOperand(0))))
393*9880d681SAndroid Build Coastguard Worker     return InstDesc(false, I);
394*9880d681SAndroid Build Coastguard Worker   if (!Cmp->hasOneUse())
395*9880d681SAndroid Build Coastguard Worker     return InstDesc(false, I);
396*9880d681SAndroid Build Coastguard Worker 
397*9880d681SAndroid Build Coastguard Worker   Value *CmpLeft;
398*9880d681SAndroid Build Coastguard Worker   Value *CmpRight;
399*9880d681SAndroid Build Coastguard Worker 
400*9880d681SAndroid Build Coastguard Worker   // Look for a min/max pattern.
401*9880d681SAndroid Build Coastguard Worker   if (m_UMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select))
402*9880d681SAndroid Build Coastguard Worker     return InstDesc(Select, MRK_UIntMin);
403*9880d681SAndroid Build Coastguard Worker   else if (m_UMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select))
404*9880d681SAndroid Build Coastguard Worker     return InstDesc(Select, MRK_UIntMax);
405*9880d681SAndroid Build Coastguard Worker   else if (m_SMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select))
406*9880d681SAndroid Build Coastguard Worker     return InstDesc(Select, MRK_SIntMax);
407*9880d681SAndroid Build Coastguard Worker   else if (m_SMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select))
408*9880d681SAndroid Build Coastguard Worker     return InstDesc(Select, MRK_SIntMin);
409*9880d681SAndroid Build Coastguard Worker   else if (m_OrdFMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select))
410*9880d681SAndroid Build Coastguard Worker     return InstDesc(Select, MRK_FloatMin);
411*9880d681SAndroid Build Coastguard Worker   else if (m_OrdFMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select))
412*9880d681SAndroid Build Coastguard Worker     return InstDesc(Select, MRK_FloatMax);
413*9880d681SAndroid Build Coastguard Worker   else if (m_UnordFMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select))
414*9880d681SAndroid Build Coastguard Worker     return InstDesc(Select, MRK_FloatMin);
415*9880d681SAndroid Build Coastguard Worker   else if (m_UnordFMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select))
416*9880d681SAndroid Build Coastguard Worker     return InstDesc(Select, MRK_FloatMax);
417*9880d681SAndroid Build Coastguard Worker 
418*9880d681SAndroid Build Coastguard Worker   return InstDesc(false, I);
419*9880d681SAndroid Build Coastguard Worker }
420*9880d681SAndroid Build Coastguard Worker 
421*9880d681SAndroid Build Coastguard Worker RecurrenceDescriptor::InstDesc
isRecurrenceInstr(Instruction * I,RecurrenceKind Kind,InstDesc & Prev,bool HasFunNoNaNAttr)422*9880d681SAndroid Build Coastguard Worker RecurrenceDescriptor::isRecurrenceInstr(Instruction *I, RecurrenceKind Kind,
423*9880d681SAndroid Build Coastguard Worker                                         InstDesc &Prev, bool HasFunNoNaNAttr) {
424*9880d681SAndroid Build Coastguard Worker   bool FP = I->getType()->isFloatingPointTy();
425*9880d681SAndroid Build Coastguard Worker   Instruction *UAI = Prev.getUnsafeAlgebraInst();
426*9880d681SAndroid Build Coastguard Worker   if (!UAI && FP && !I->hasUnsafeAlgebra())
427*9880d681SAndroid Build Coastguard Worker     UAI = I; // Found an unsafe (unvectorizable) algebra instruction.
428*9880d681SAndroid Build Coastguard Worker 
429*9880d681SAndroid Build Coastguard Worker   switch (I->getOpcode()) {
430*9880d681SAndroid Build Coastguard Worker   default:
431*9880d681SAndroid Build Coastguard Worker     return InstDesc(false, I);
432*9880d681SAndroid Build Coastguard Worker   case Instruction::PHI:
433*9880d681SAndroid Build Coastguard Worker     return InstDesc(I, Prev.getMinMaxKind(), Prev.getUnsafeAlgebraInst());
434*9880d681SAndroid Build Coastguard Worker   case Instruction::Sub:
435*9880d681SAndroid Build Coastguard Worker   case Instruction::Add:
436*9880d681SAndroid Build Coastguard Worker     return InstDesc(Kind == RK_IntegerAdd, I);
437*9880d681SAndroid Build Coastguard Worker   case Instruction::Mul:
438*9880d681SAndroid Build Coastguard Worker     return InstDesc(Kind == RK_IntegerMult, I);
439*9880d681SAndroid Build Coastguard Worker   case Instruction::And:
440*9880d681SAndroid Build Coastguard Worker     return InstDesc(Kind == RK_IntegerAnd, I);
441*9880d681SAndroid Build Coastguard Worker   case Instruction::Or:
442*9880d681SAndroid Build Coastguard Worker     return InstDesc(Kind == RK_IntegerOr, I);
443*9880d681SAndroid Build Coastguard Worker   case Instruction::Xor:
444*9880d681SAndroid Build Coastguard Worker     return InstDesc(Kind == RK_IntegerXor, I);
445*9880d681SAndroid Build Coastguard Worker   case Instruction::FMul:
446*9880d681SAndroid Build Coastguard Worker     return InstDesc(Kind == RK_FloatMult, I, UAI);
447*9880d681SAndroid Build Coastguard Worker   case Instruction::FSub:
448*9880d681SAndroid Build Coastguard Worker   case Instruction::FAdd:
449*9880d681SAndroid Build Coastguard Worker     return InstDesc(Kind == RK_FloatAdd, I, UAI);
450*9880d681SAndroid Build Coastguard Worker   case Instruction::FCmp:
451*9880d681SAndroid Build Coastguard Worker   case Instruction::ICmp:
452*9880d681SAndroid Build Coastguard Worker   case Instruction::Select:
453*9880d681SAndroid Build Coastguard Worker     if (Kind != RK_IntegerMinMax &&
454*9880d681SAndroid Build Coastguard Worker         (!HasFunNoNaNAttr || Kind != RK_FloatMinMax))
455*9880d681SAndroid Build Coastguard Worker       return InstDesc(false, I);
456*9880d681SAndroid Build Coastguard Worker     return isMinMaxSelectCmpPattern(I, Prev);
457*9880d681SAndroid Build Coastguard Worker   }
458*9880d681SAndroid Build Coastguard Worker }
459*9880d681SAndroid Build Coastguard Worker 
hasMultipleUsesOf(Instruction * I,SmallPtrSetImpl<Instruction * > & Insts)460*9880d681SAndroid Build Coastguard Worker bool RecurrenceDescriptor::hasMultipleUsesOf(
461*9880d681SAndroid Build Coastguard Worker     Instruction *I, SmallPtrSetImpl<Instruction *> &Insts) {
462*9880d681SAndroid Build Coastguard Worker   unsigned NumUses = 0;
463*9880d681SAndroid Build Coastguard Worker   for (User::op_iterator Use = I->op_begin(), E = I->op_end(); Use != E;
464*9880d681SAndroid Build Coastguard Worker        ++Use) {
465*9880d681SAndroid Build Coastguard Worker     if (Insts.count(dyn_cast<Instruction>(*Use)))
466*9880d681SAndroid Build Coastguard Worker       ++NumUses;
467*9880d681SAndroid Build Coastguard Worker     if (NumUses > 1)
468*9880d681SAndroid Build Coastguard Worker       return true;
469*9880d681SAndroid Build Coastguard Worker   }
470*9880d681SAndroid Build Coastguard Worker 
471*9880d681SAndroid Build Coastguard Worker   return false;
472*9880d681SAndroid Build Coastguard Worker }
isReductionPHI(PHINode * Phi,Loop * TheLoop,RecurrenceDescriptor & RedDes)473*9880d681SAndroid Build Coastguard Worker bool RecurrenceDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop,
474*9880d681SAndroid Build Coastguard Worker                                           RecurrenceDescriptor &RedDes) {
475*9880d681SAndroid Build Coastguard Worker 
476*9880d681SAndroid Build Coastguard Worker   BasicBlock *Header = TheLoop->getHeader();
477*9880d681SAndroid Build Coastguard Worker   Function &F = *Header->getParent();
478*9880d681SAndroid Build Coastguard Worker   bool HasFunNoNaNAttr =
479*9880d681SAndroid Build Coastguard Worker       F.getFnAttribute("no-nans-fp-math").getValueAsString() == "true";
480*9880d681SAndroid Build Coastguard Worker 
481*9880d681SAndroid Build Coastguard Worker   if (AddReductionVar(Phi, RK_IntegerAdd, TheLoop, HasFunNoNaNAttr, RedDes)) {
482*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Found an ADD reduction PHI." << *Phi << "\n");
483*9880d681SAndroid Build Coastguard Worker     return true;
484*9880d681SAndroid Build Coastguard Worker   }
485*9880d681SAndroid Build Coastguard Worker   if (AddReductionVar(Phi, RK_IntegerMult, TheLoop, HasFunNoNaNAttr, RedDes)) {
486*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Found a MUL reduction PHI." << *Phi << "\n");
487*9880d681SAndroid Build Coastguard Worker     return true;
488*9880d681SAndroid Build Coastguard Worker   }
489*9880d681SAndroid Build Coastguard Worker   if (AddReductionVar(Phi, RK_IntegerOr, TheLoop, HasFunNoNaNAttr, RedDes)) {
490*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Found an OR reduction PHI." << *Phi << "\n");
491*9880d681SAndroid Build Coastguard Worker     return true;
492*9880d681SAndroid Build Coastguard Worker   }
493*9880d681SAndroid Build Coastguard Worker   if (AddReductionVar(Phi, RK_IntegerAnd, TheLoop, HasFunNoNaNAttr, RedDes)) {
494*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Found an AND reduction PHI." << *Phi << "\n");
495*9880d681SAndroid Build Coastguard Worker     return true;
496*9880d681SAndroid Build Coastguard Worker   }
497*9880d681SAndroid Build Coastguard Worker   if (AddReductionVar(Phi, RK_IntegerXor, TheLoop, HasFunNoNaNAttr, RedDes)) {
498*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Found a XOR reduction PHI." << *Phi << "\n");
499*9880d681SAndroid Build Coastguard Worker     return true;
500*9880d681SAndroid Build Coastguard Worker   }
501*9880d681SAndroid Build Coastguard Worker   if (AddReductionVar(Phi, RK_IntegerMinMax, TheLoop, HasFunNoNaNAttr,
502*9880d681SAndroid Build Coastguard Worker                       RedDes)) {
503*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Found a MINMAX reduction PHI." << *Phi << "\n");
504*9880d681SAndroid Build Coastguard Worker     return true;
505*9880d681SAndroid Build Coastguard Worker   }
506*9880d681SAndroid Build Coastguard Worker   if (AddReductionVar(Phi, RK_FloatMult, TheLoop, HasFunNoNaNAttr, RedDes)) {
507*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Found an FMult reduction PHI." << *Phi << "\n");
508*9880d681SAndroid Build Coastguard Worker     return true;
509*9880d681SAndroid Build Coastguard Worker   }
510*9880d681SAndroid Build Coastguard Worker   if (AddReductionVar(Phi, RK_FloatAdd, TheLoop, HasFunNoNaNAttr, RedDes)) {
511*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Found an FAdd reduction PHI." << *Phi << "\n");
512*9880d681SAndroid Build Coastguard Worker     return true;
513*9880d681SAndroid Build Coastguard Worker   }
514*9880d681SAndroid Build Coastguard Worker   if (AddReductionVar(Phi, RK_FloatMinMax, TheLoop, HasFunNoNaNAttr, RedDes)) {
515*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Found an float MINMAX reduction PHI." << *Phi << "\n");
516*9880d681SAndroid Build Coastguard Worker     return true;
517*9880d681SAndroid Build Coastguard Worker   }
518*9880d681SAndroid Build Coastguard Worker   // Not a reduction of known type.
519*9880d681SAndroid Build Coastguard Worker   return false;
520*9880d681SAndroid Build Coastguard Worker }
521*9880d681SAndroid Build Coastguard Worker 
isFirstOrderRecurrence(PHINode * Phi,Loop * TheLoop,DominatorTree * DT)522*9880d681SAndroid Build Coastguard Worker bool RecurrenceDescriptor::isFirstOrderRecurrence(PHINode *Phi, Loop *TheLoop,
523*9880d681SAndroid Build Coastguard Worker                                                   DominatorTree *DT) {
524*9880d681SAndroid Build Coastguard Worker 
525*9880d681SAndroid Build Coastguard Worker   // Ensure the phi node is in the loop header and has two incoming values.
526*9880d681SAndroid Build Coastguard Worker   if (Phi->getParent() != TheLoop->getHeader() ||
527*9880d681SAndroid Build Coastguard Worker       Phi->getNumIncomingValues() != 2)
528*9880d681SAndroid Build Coastguard Worker     return false;
529*9880d681SAndroid Build Coastguard Worker 
530*9880d681SAndroid Build Coastguard Worker   // Ensure the loop has a preheader and a single latch block. The loop
531*9880d681SAndroid Build Coastguard Worker   // vectorizer will need the latch to set up the next iteration of the loop.
532*9880d681SAndroid Build Coastguard Worker   auto *Preheader = TheLoop->getLoopPreheader();
533*9880d681SAndroid Build Coastguard Worker   auto *Latch = TheLoop->getLoopLatch();
534*9880d681SAndroid Build Coastguard Worker   if (!Preheader || !Latch)
535*9880d681SAndroid Build Coastguard Worker     return false;
536*9880d681SAndroid Build Coastguard Worker 
537*9880d681SAndroid Build Coastguard Worker   // Ensure the phi node's incoming blocks are the loop preheader and latch.
538*9880d681SAndroid Build Coastguard Worker   if (Phi->getBasicBlockIndex(Preheader) < 0 ||
539*9880d681SAndroid Build Coastguard Worker       Phi->getBasicBlockIndex(Latch) < 0)
540*9880d681SAndroid Build Coastguard Worker     return false;
541*9880d681SAndroid Build Coastguard Worker 
542*9880d681SAndroid Build Coastguard Worker   // Get the previous value. The previous value comes from the latch edge while
543*9880d681SAndroid Build Coastguard Worker   // the initial value comes form the preheader edge.
544*9880d681SAndroid Build Coastguard Worker   auto *Previous = dyn_cast<Instruction>(Phi->getIncomingValueForBlock(Latch));
545*9880d681SAndroid Build Coastguard Worker   if (!Previous || !TheLoop->contains(Previous) || isa<PHINode>(Previous))
546*9880d681SAndroid Build Coastguard Worker     return false;
547*9880d681SAndroid Build Coastguard Worker 
548*9880d681SAndroid Build Coastguard Worker   // Ensure every user of the phi node is dominated by the previous value. The
549*9880d681SAndroid Build Coastguard Worker   // dominance requirement ensures the loop vectorizer will not need to
550*9880d681SAndroid Build Coastguard Worker   // vectorize the initial value prior to the first iteration of the loop.
551*9880d681SAndroid Build Coastguard Worker   for (User *U : Phi->users())
552*9880d681SAndroid Build Coastguard Worker     if (auto *I = dyn_cast<Instruction>(U))
553*9880d681SAndroid Build Coastguard Worker       if (!DT->dominates(Previous, I))
554*9880d681SAndroid Build Coastguard Worker         return false;
555*9880d681SAndroid Build Coastguard Worker 
556*9880d681SAndroid Build Coastguard Worker   return true;
557*9880d681SAndroid Build Coastguard Worker }
558*9880d681SAndroid Build Coastguard Worker 
559*9880d681SAndroid Build Coastguard Worker /// This function returns the identity element (or neutral element) for
560*9880d681SAndroid Build Coastguard Worker /// the operation K.
getRecurrenceIdentity(RecurrenceKind K,Type * Tp)561*9880d681SAndroid Build Coastguard Worker Constant *RecurrenceDescriptor::getRecurrenceIdentity(RecurrenceKind K,
562*9880d681SAndroid Build Coastguard Worker                                                       Type *Tp) {
563*9880d681SAndroid Build Coastguard Worker   switch (K) {
564*9880d681SAndroid Build Coastguard Worker   case RK_IntegerXor:
565*9880d681SAndroid Build Coastguard Worker   case RK_IntegerAdd:
566*9880d681SAndroid Build Coastguard Worker   case RK_IntegerOr:
567*9880d681SAndroid Build Coastguard Worker     // Adding, Xoring, Oring zero to a number does not change it.
568*9880d681SAndroid Build Coastguard Worker     return ConstantInt::get(Tp, 0);
569*9880d681SAndroid Build Coastguard Worker   case RK_IntegerMult:
570*9880d681SAndroid Build Coastguard Worker     // Multiplying a number by 1 does not change it.
571*9880d681SAndroid Build Coastguard Worker     return ConstantInt::get(Tp, 1);
572*9880d681SAndroid Build Coastguard Worker   case RK_IntegerAnd:
573*9880d681SAndroid Build Coastguard Worker     // AND-ing a number with an all-1 value does not change it.
574*9880d681SAndroid Build Coastguard Worker     return ConstantInt::get(Tp, -1, true);
575*9880d681SAndroid Build Coastguard Worker   case RK_FloatMult:
576*9880d681SAndroid Build Coastguard Worker     // Multiplying a number by 1 does not change it.
577*9880d681SAndroid Build Coastguard Worker     return ConstantFP::get(Tp, 1.0L);
578*9880d681SAndroid Build Coastguard Worker   case RK_FloatAdd:
579*9880d681SAndroid Build Coastguard Worker     // Adding zero to a number does not change it.
580*9880d681SAndroid Build Coastguard Worker     return ConstantFP::get(Tp, 0.0L);
581*9880d681SAndroid Build Coastguard Worker   default:
582*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unknown recurrence kind");
583*9880d681SAndroid Build Coastguard Worker   }
584*9880d681SAndroid Build Coastguard Worker }
585*9880d681SAndroid Build Coastguard Worker 
586*9880d681SAndroid Build Coastguard Worker /// This function translates the recurrence kind to an LLVM binary operator.
getRecurrenceBinOp(RecurrenceKind Kind)587*9880d681SAndroid Build Coastguard Worker unsigned RecurrenceDescriptor::getRecurrenceBinOp(RecurrenceKind Kind) {
588*9880d681SAndroid Build Coastguard Worker   switch (Kind) {
589*9880d681SAndroid Build Coastguard Worker   case RK_IntegerAdd:
590*9880d681SAndroid Build Coastguard Worker     return Instruction::Add;
591*9880d681SAndroid Build Coastguard Worker   case RK_IntegerMult:
592*9880d681SAndroid Build Coastguard Worker     return Instruction::Mul;
593*9880d681SAndroid Build Coastguard Worker   case RK_IntegerOr:
594*9880d681SAndroid Build Coastguard Worker     return Instruction::Or;
595*9880d681SAndroid Build Coastguard Worker   case RK_IntegerAnd:
596*9880d681SAndroid Build Coastguard Worker     return Instruction::And;
597*9880d681SAndroid Build Coastguard Worker   case RK_IntegerXor:
598*9880d681SAndroid Build Coastguard Worker     return Instruction::Xor;
599*9880d681SAndroid Build Coastguard Worker   case RK_FloatMult:
600*9880d681SAndroid Build Coastguard Worker     return Instruction::FMul;
601*9880d681SAndroid Build Coastguard Worker   case RK_FloatAdd:
602*9880d681SAndroid Build Coastguard Worker     return Instruction::FAdd;
603*9880d681SAndroid Build Coastguard Worker   case RK_IntegerMinMax:
604*9880d681SAndroid Build Coastguard Worker     return Instruction::ICmp;
605*9880d681SAndroid Build Coastguard Worker   case RK_FloatMinMax:
606*9880d681SAndroid Build Coastguard Worker     return Instruction::FCmp;
607*9880d681SAndroid Build Coastguard Worker   default:
608*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unknown recurrence operation");
609*9880d681SAndroid Build Coastguard Worker   }
610*9880d681SAndroid Build Coastguard Worker }
611*9880d681SAndroid Build Coastguard Worker 
createMinMaxOp(IRBuilder<> & Builder,MinMaxRecurrenceKind RK,Value * Left,Value * Right)612*9880d681SAndroid Build Coastguard Worker Value *RecurrenceDescriptor::createMinMaxOp(IRBuilder<> &Builder,
613*9880d681SAndroid Build Coastguard Worker                                             MinMaxRecurrenceKind RK,
614*9880d681SAndroid Build Coastguard Worker                                             Value *Left, Value *Right) {
615*9880d681SAndroid Build Coastguard Worker   CmpInst::Predicate P = CmpInst::ICMP_NE;
616*9880d681SAndroid Build Coastguard Worker   switch (RK) {
617*9880d681SAndroid Build Coastguard Worker   default:
618*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unknown min/max recurrence kind");
619*9880d681SAndroid Build Coastguard Worker   case MRK_UIntMin:
620*9880d681SAndroid Build Coastguard Worker     P = CmpInst::ICMP_ULT;
621*9880d681SAndroid Build Coastguard Worker     break;
622*9880d681SAndroid Build Coastguard Worker   case MRK_UIntMax:
623*9880d681SAndroid Build Coastguard Worker     P = CmpInst::ICMP_UGT;
624*9880d681SAndroid Build Coastguard Worker     break;
625*9880d681SAndroid Build Coastguard Worker   case MRK_SIntMin:
626*9880d681SAndroid Build Coastguard Worker     P = CmpInst::ICMP_SLT;
627*9880d681SAndroid Build Coastguard Worker     break;
628*9880d681SAndroid Build Coastguard Worker   case MRK_SIntMax:
629*9880d681SAndroid Build Coastguard Worker     P = CmpInst::ICMP_SGT;
630*9880d681SAndroid Build Coastguard Worker     break;
631*9880d681SAndroid Build Coastguard Worker   case MRK_FloatMin:
632*9880d681SAndroid Build Coastguard Worker     P = CmpInst::FCMP_OLT;
633*9880d681SAndroid Build Coastguard Worker     break;
634*9880d681SAndroid Build Coastguard Worker   case MRK_FloatMax:
635*9880d681SAndroid Build Coastguard Worker     P = CmpInst::FCMP_OGT;
636*9880d681SAndroid Build Coastguard Worker     break;
637*9880d681SAndroid Build Coastguard Worker   }
638*9880d681SAndroid Build Coastguard Worker 
639*9880d681SAndroid Build Coastguard Worker   // We only match FP sequences with unsafe algebra, so we can unconditionally
640*9880d681SAndroid Build Coastguard Worker   // set it on any generated instructions.
641*9880d681SAndroid Build Coastguard Worker   IRBuilder<>::FastMathFlagGuard FMFG(Builder);
642*9880d681SAndroid Build Coastguard Worker   FastMathFlags FMF;
643*9880d681SAndroid Build Coastguard Worker   FMF.setUnsafeAlgebra();
644*9880d681SAndroid Build Coastguard Worker   Builder.setFastMathFlags(FMF);
645*9880d681SAndroid Build Coastguard Worker 
646*9880d681SAndroid Build Coastguard Worker   Value *Cmp;
647*9880d681SAndroid Build Coastguard Worker   if (RK == MRK_FloatMin || RK == MRK_FloatMax)
648*9880d681SAndroid Build Coastguard Worker     Cmp = Builder.CreateFCmp(P, Left, Right, "rdx.minmax.cmp");
649*9880d681SAndroid Build Coastguard Worker   else
650*9880d681SAndroid Build Coastguard Worker     Cmp = Builder.CreateICmp(P, Left, Right, "rdx.minmax.cmp");
651*9880d681SAndroid Build Coastguard Worker 
652*9880d681SAndroid Build Coastguard Worker   Value *Select = Builder.CreateSelect(Cmp, Left, Right, "rdx.minmax.select");
653*9880d681SAndroid Build Coastguard Worker   return Select;
654*9880d681SAndroid Build Coastguard Worker }
655*9880d681SAndroid Build Coastguard Worker 
InductionDescriptor(Value * Start,InductionKind K,const SCEV * Step)656*9880d681SAndroid Build Coastguard Worker InductionDescriptor::InductionDescriptor(Value *Start, InductionKind K,
657*9880d681SAndroid Build Coastguard Worker                                          const SCEV *Step)
658*9880d681SAndroid Build Coastguard Worker   : StartValue(Start), IK(K), Step(Step) {
659*9880d681SAndroid Build Coastguard Worker   assert(IK != IK_NoInduction && "Not an induction");
660*9880d681SAndroid Build Coastguard Worker 
661*9880d681SAndroid Build Coastguard Worker   // Start value type should match the induction kind and the value
662*9880d681SAndroid Build Coastguard Worker   // itself should not be null.
663*9880d681SAndroid Build Coastguard Worker   assert(StartValue && "StartValue is null");
664*9880d681SAndroid Build Coastguard Worker   assert((IK != IK_PtrInduction || StartValue->getType()->isPointerTy()) &&
665*9880d681SAndroid Build Coastguard Worker          "StartValue is not a pointer for pointer induction");
666*9880d681SAndroid Build Coastguard Worker   assert((IK != IK_IntInduction || StartValue->getType()->isIntegerTy()) &&
667*9880d681SAndroid Build Coastguard Worker          "StartValue is not an integer for integer induction");
668*9880d681SAndroid Build Coastguard Worker 
669*9880d681SAndroid Build Coastguard Worker   // Check the Step Value. It should be non-zero integer value.
670*9880d681SAndroid Build Coastguard Worker   assert((!getConstIntStepValue() || !getConstIntStepValue()->isZero()) &&
671*9880d681SAndroid Build Coastguard Worker          "Step value is zero");
672*9880d681SAndroid Build Coastguard Worker 
673*9880d681SAndroid Build Coastguard Worker   assert((IK != IK_PtrInduction || getConstIntStepValue()) &&
674*9880d681SAndroid Build Coastguard Worker          "Step value should be constant for pointer induction");
675*9880d681SAndroid Build Coastguard Worker   assert(Step->getType()->isIntegerTy() && "StepValue is not an integer");
676*9880d681SAndroid Build Coastguard Worker }
677*9880d681SAndroid Build Coastguard Worker 
getConsecutiveDirection() const678*9880d681SAndroid Build Coastguard Worker int InductionDescriptor::getConsecutiveDirection() const {
679*9880d681SAndroid Build Coastguard Worker   ConstantInt *ConstStep = getConstIntStepValue();
680*9880d681SAndroid Build Coastguard Worker   if (ConstStep && (ConstStep->isOne() || ConstStep->isMinusOne()))
681*9880d681SAndroid Build Coastguard Worker     return ConstStep->getSExtValue();
682*9880d681SAndroid Build Coastguard Worker   return 0;
683*9880d681SAndroid Build Coastguard Worker }
684*9880d681SAndroid Build Coastguard Worker 
getConstIntStepValue() const685*9880d681SAndroid Build Coastguard Worker ConstantInt *InductionDescriptor::getConstIntStepValue() const {
686*9880d681SAndroid Build Coastguard Worker   if (isa<SCEVConstant>(Step))
687*9880d681SAndroid Build Coastguard Worker     return dyn_cast<ConstantInt>(cast<SCEVConstant>(Step)->getValue());
688*9880d681SAndroid Build Coastguard Worker   return nullptr;
689*9880d681SAndroid Build Coastguard Worker }
690*9880d681SAndroid Build Coastguard Worker 
transform(IRBuilder<> & B,Value * Index,ScalarEvolution * SE,const DataLayout & DL) const691*9880d681SAndroid Build Coastguard Worker Value *InductionDescriptor::transform(IRBuilder<> &B, Value *Index,
692*9880d681SAndroid Build Coastguard Worker                                       ScalarEvolution *SE,
693*9880d681SAndroid Build Coastguard Worker                                       const DataLayout& DL) const {
694*9880d681SAndroid Build Coastguard Worker 
695*9880d681SAndroid Build Coastguard Worker   SCEVExpander Exp(*SE, DL, "induction");
696*9880d681SAndroid Build Coastguard Worker   switch (IK) {
697*9880d681SAndroid Build Coastguard Worker   case IK_IntInduction: {
698*9880d681SAndroid Build Coastguard Worker     assert(Index->getType() == StartValue->getType() &&
699*9880d681SAndroid Build Coastguard Worker            "Index type does not match StartValue type");
700*9880d681SAndroid Build Coastguard Worker 
701*9880d681SAndroid Build Coastguard Worker     // FIXME: Theoretically, we can call getAddExpr() of ScalarEvolution
702*9880d681SAndroid Build Coastguard Worker     // and calculate (Start + Index * Step) for all cases, without
703*9880d681SAndroid Build Coastguard Worker     // special handling for "isOne" and "isMinusOne".
704*9880d681SAndroid Build Coastguard Worker     // But in the real life the result code getting worse. We mix SCEV
705*9880d681SAndroid Build Coastguard Worker     // expressions and ADD/SUB operations and receive redundant
706*9880d681SAndroid Build Coastguard Worker     // intermediate values being calculated in different ways and
707*9880d681SAndroid Build Coastguard Worker     // Instcombine is unable to reduce them all.
708*9880d681SAndroid Build Coastguard Worker 
709*9880d681SAndroid Build Coastguard Worker     if (getConstIntStepValue() &&
710*9880d681SAndroid Build Coastguard Worker         getConstIntStepValue()->isMinusOne())
711*9880d681SAndroid Build Coastguard Worker       return B.CreateSub(StartValue, Index);
712*9880d681SAndroid Build Coastguard Worker     if (getConstIntStepValue() &&
713*9880d681SAndroid Build Coastguard Worker         getConstIntStepValue()->isOne())
714*9880d681SAndroid Build Coastguard Worker       return B.CreateAdd(StartValue, Index);
715*9880d681SAndroid Build Coastguard Worker     const SCEV *S = SE->getAddExpr(SE->getSCEV(StartValue),
716*9880d681SAndroid Build Coastguard Worker                                    SE->getMulExpr(Step, SE->getSCEV(Index)));
717*9880d681SAndroid Build Coastguard Worker     return Exp.expandCodeFor(S, StartValue->getType(), &*B.GetInsertPoint());
718*9880d681SAndroid Build Coastguard Worker   }
719*9880d681SAndroid Build Coastguard Worker   case IK_PtrInduction: {
720*9880d681SAndroid Build Coastguard Worker     assert(Index->getType() == Step->getType() &&
721*9880d681SAndroid Build Coastguard Worker            "Index type does not match StepValue type");
722*9880d681SAndroid Build Coastguard Worker     assert(isa<SCEVConstant>(Step) &&
723*9880d681SAndroid Build Coastguard Worker            "Expected constant step for pointer induction");
724*9880d681SAndroid Build Coastguard Worker     const SCEV *S = SE->getMulExpr(SE->getSCEV(Index), Step);
725*9880d681SAndroid Build Coastguard Worker     Index = Exp.expandCodeFor(S, Index->getType(), &*B.GetInsertPoint());
726*9880d681SAndroid Build Coastguard Worker     return B.CreateGEP(nullptr, StartValue, Index);
727*9880d681SAndroid Build Coastguard Worker   }
728*9880d681SAndroid Build Coastguard Worker   case IK_NoInduction:
729*9880d681SAndroid Build Coastguard Worker     return nullptr;
730*9880d681SAndroid Build Coastguard Worker   }
731*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("invalid enum");
732*9880d681SAndroid Build Coastguard Worker }
733*9880d681SAndroid Build Coastguard Worker 
isInductionPHI(PHINode * Phi,PredicatedScalarEvolution & PSE,InductionDescriptor & D,bool Assume)734*9880d681SAndroid Build Coastguard Worker bool InductionDescriptor::isInductionPHI(PHINode *Phi,
735*9880d681SAndroid Build Coastguard Worker                                          PredicatedScalarEvolution &PSE,
736*9880d681SAndroid Build Coastguard Worker                                          InductionDescriptor &D,
737*9880d681SAndroid Build Coastguard Worker                                          bool Assume) {
738*9880d681SAndroid Build Coastguard Worker   Type *PhiTy = Phi->getType();
739*9880d681SAndroid Build Coastguard Worker   // We only handle integer and pointer inductions variables.
740*9880d681SAndroid Build Coastguard Worker   if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy())
741*9880d681SAndroid Build Coastguard Worker     return false;
742*9880d681SAndroid Build Coastguard Worker 
743*9880d681SAndroid Build Coastguard Worker   const SCEV *PhiScev = PSE.getSCEV(Phi);
744*9880d681SAndroid Build Coastguard Worker   const auto *AR = dyn_cast<SCEVAddRecExpr>(PhiScev);
745*9880d681SAndroid Build Coastguard Worker 
746*9880d681SAndroid Build Coastguard Worker   // We need this expression to be an AddRecExpr.
747*9880d681SAndroid Build Coastguard Worker   if (Assume && !AR)
748*9880d681SAndroid Build Coastguard Worker     AR = PSE.getAsAddRec(Phi);
749*9880d681SAndroid Build Coastguard Worker 
750*9880d681SAndroid Build Coastguard Worker   if (!AR) {
751*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n");
752*9880d681SAndroid Build Coastguard Worker     return false;
753*9880d681SAndroid Build Coastguard Worker   }
754*9880d681SAndroid Build Coastguard Worker 
755*9880d681SAndroid Build Coastguard Worker   return isInductionPHI(Phi, PSE.getSE(), D, AR);
756*9880d681SAndroid Build Coastguard Worker }
757*9880d681SAndroid Build Coastguard Worker 
isInductionPHI(PHINode * Phi,ScalarEvolution * SE,InductionDescriptor & D,const SCEV * Expr)758*9880d681SAndroid Build Coastguard Worker bool InductionDescriptor::isInductionPHI(PHINode *Phi,
759*9880d681SAndroid Build Coastguard Worker                                          ScalarEvolution *SE,
760*9880d681SAndroid Build Coastguard Worker                                          InductionDescriptor &D,
761*9880d681SAndroid Build Coastguard Worker                                          const SCEV *Expr) {
762*9880d681SAndroid Build Coastguard Worker   Type *PhiTy = Phi->getType();
763*9880d681SAndroid Build Coastguard Worker   // We only handle integer and pointer inductions variables.
764*9880d681SAndroid Build Coastguard Worker   if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy())
765*9880d681SAndroid Build Coastguard Worker     return false;
766*9880d681SAndroid Build Coastguard Worker 
767*9880d681SAndroid Build Coastguard Worker   // Check that the PHI is consecutive.
768*9880d681SAndroid Build Coastguard Worker   const SCEV *PhiScev = Expr ? Expr : SE->getSCEV(Phi);
769*9880d681SAndroid Build Coastguard Worker   const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PhiScev);
770*9880d681SAndroid Build Coastguard Worker 
771*9880d681SAndroid Build Coastguard Worker   if (!AR) {
772*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n");
773*9880d681SAndroid Build Coastguard Worker     return false;
774*9880d681SAndroid Build Coastguard Worker   }
775*9880d681SAndroid Build Coastguard Worker 
776*9880d681SAndroid Build Coastguard Worker   assert(AR->getLoop()->getHeader() == Phi->getParent() &&
777*9880d681SAndroid Build Coastguard Worker          "PHI is an AddRec for a different loop?!");
778*9880d681SAndroid Build Coastguard Worker   Value *StartValue =
779*9880d681SAndroid Build Coastguard Worker     Phi->getIncomingValueForBlock(AR->getLoop()->getLoopPreheader());
780*9880d681SAndroid Build Coastguard Worker   const SCEV *Step = AR->getStepRecurrence(*SE);
781*9880d681SAndroid Build Coastguard Worker   // Calculate the pointer stride and check if it is consecutive.
782*9880d681SAndroid Build Coastguard Worker   // The stride may be a constant or a loop invariant integer value.
783*9880d681SAndroid Build Coastguard Worker   const SCEVConstant *ConstStep = dyn_cast<SCEVConstant>(Step);
784*9880d681SAndroid Build Coastguard Worker   if (!ConstStep && !SE->isLoopInvariant(Step, AR->getLoop()))
785*9880d681SAndroid Build Coastguard Worker     return false;
786*9880d681SAndroid Build Coastguard Worker 
787*9880d681SAndroid Build Coastguard Worker   if (PhiTy->isIntegerTy()) {
788*9880d681SAndroid Build Coastguard Worker     D = InductionDescriptor(StartValue, IK_IntInduction, Step);
789*9880d681SAndroid Build Coastguard Worker     return true;
790*9880d681SAndroid Build Coastguard Worker   }
791*9880d681SAndroid Build Coastguard Worker 
792*9880d681SAndroid Build Coastguard Worker   assert(PhiTy->isPointerTy() && "The PHI must be a pointer");
793*9880d681SAndroid Build Coastguard Worker   // Pointer induction should be a constant.
794*9880d681SAndroid Build Coastguard Worker   if (!ConstStep)
795*9880d681SAndroid Build Coastguard Worker     return false;
796*9880d681SAndroid Build Coastguard Worker 
797*9880d681SAndroid Build Coastguard Worker   ConstantInt *CV = ConstStep->getValue();
798*9880d681SAndroid Build Coastguard Worker   Type *PointerElementType = PhiTy->getPointerElementType();
799*9880d681SAndroid Build Coastguard Worker   // The pointer stride cannot be determined if the pointer element type is not
800*9880d681SAndroid Build Coastguard Worker   // sized.
801*9880d681SAndroid Build Coastguard Worker   if (!PointerElementType->isSized())
802*9880d681SAndroid Build Coastguard Worker     return false;
803*9880d681SAndroid Build Coastguard Worker 
804*9880d681SAndroid Build Coastguard Worker   const DataLayout &DL = Phi->getModule()->getDataLayout();
805*9880d681SAndroid Build Coastguard Worker   int64_t Size = static_cast<int64_t>(DL.getTypeAllocSize(PointerElementType));
806*9880d681SAndroid Build Coastguard Worker   if (!Size)
807*9880d681SAndroid Build Coastguard Worker     return false;
808*9880d681SAndroid Build Coastguard Worker 
809*9880d681SAndroid Build Coastguard Worker   int64_t CVSize = CV->getSExtValue();
810*9880d681SAndroid Build Coastguard Worker   if (CVSize % Size)
811*9880d681SAndroid Build Coastguard Worker     return false;
812*9880d681SAndroid Build Coastguard Worker   auto *StepValue = SE->getConstant(CV->getType(), CVSize / Size,
813*9880d681SAndroid Build Coastguard Worker                                     true /* signed */);
814*9880d681SAndroid Build Coastguard Worker   D = InductionDescriptor(StartValue, IK_PtrInduction, StepValue);
815*9880d681SAndroid Build Coastguard Worker   return true;
816*9880d681SAndroid Build Coastguard Worker }
817*9880d681SAndroid Build Coastguard Worker 
818*9880d681SAndroid Build Coastguard Worker /// \brief Returns the instructions that use values defined in the loop.
findDefsUsedOutsideOfLoop(Loop * L)819*9880d681SAndroid Build Coastguard Worker SmallVector<Instruction *, 8> llvm::findDefsUsedOutsideOfLoop(Loop *L) {
820*9880d681SAndroid Build Coastguard Worker   SmallVector<Instruction *, 8> UsedOutside;
821*9880d681SAndroid Build Coastguard Worker 
822*9880d681SAndroid Build Coastguard Worker   for (auto *Block : L->getBlocks())
823*9880d681SAndroid Build Coastguard Worker     // FIXME: I believe that this could use copy_if if the Inst reference could
824*9880d681SAndroid Build Coastguard Worker     // be adapted into a pointer.
825*9880d681SAndroid Build Coastguard Worker     for (auto &Inst : *Block) {
826*9880d681SAndroid Build Coastguard Worker       auto Users = Inst.users();
827*9880d681SAndroid Build Coastguard Worker       if (std::any_of(Users.begin(), Users.end(), [&](User *U) {
828*9880d681SAndroid Build Coastguard Worker             auto *Use = cast<Instruction>(U);
829*9880d681SAndroid Build Coastguard Worker             return !L->contains(Use->getParent());
830*9880d681SAndroid Build Coastguard Worker           }))
831*9880d681SAndroid Build Coastguard Worker         UsedOutside.push_back(&Inst);
832*9880d681SAndroid Build Coastguard Worker     }
833*9880d681SAndroid Build Coastguard Worker 
834*9880d681SAndroid Build Coastguard Worker   return UsedOutside;
835*9880d681SAndroid Build Coastguard Worker }
836*9880d681SAndroid Build Coastguard Worker 
getLoopAnalysisUsage(AnalysisUsage & AU)837*9880d681SAndroid Build Coastguard Worker void llvm::getLoopAnalysisUsage(AnalysisUsage &AU) {
838*9880d681SAndroid Build Coastguard Worker   // By definition, all loop passes need the LoopInfo analysis and the
839*9880d681SAndroid Build Coastguard Worker   // Dominator tree it depends on. Because they all participate in the loop
840*9880d681SAndroid Build Coastguard Worker   // pass manager, they must also preserve these.
841*9880d681SAndroid Build Coastguard Worker   AU.addRequired<DominatorTreeWrapperPass>();
842*9880d681SAndroid Build Coastguard Worker   AU.addPreserved<DominatorTreeWrapperPass>();
843*9880d681SAndroid Build Coastguard Worker   AU.addRequired<LoopInfoWrapperPass>();
844*9880d681SAndroid Build Coastguard Worker   AU.addPreserved<LoopInfoWrapperPass>();
845*9880d681SAndroid Build Coastguard Worker 
846*9880d681SAndroid Build Coastguard Worker   // We must also preserve LoopSimplify and LCSSA. We locally access their IDs
847*9880d681SAndroid Build Coastguard Worker   // here because users shouldn't directly get them from this header.
848*9880d681SAndroid Build Coastguard Worker   extern char &LoopSimplifyID;
849*9880d681SAndroid Build Coastguard Worker   extern char &LCSSAID;
850*9880d681SAndroid Build Coastguard Worker   AU.addRequiredID(LoopSimplifyID);
851*9880d681SAndroid Build Coastguard Worker   AU.addPreservedID(LoopSimplifyID);
852*9880d681SAndroid Build Coastguard Worker   AU.addRequiredID(LCSSAID);
853*9880d681SAndroid Build Coastguard Worker   AU.addPreservedID(LCSSAID);
854*9880d681SAndroid Build Coastguard Worker 
855*9880d681SAndroid Build Coastguard Worker   // Loop passes are designed to run inside of a loop pass manager which means
856*9880d681SAndroid Build Coastguard Worker   // that any function analyses they require must be required by the first loop
857*9880d681SAndroid Build Coastguard Worker   // pass in the manager (so that it is computed before the loop pass manager
858*9880d681SAndroid Build Coastguard Worker   // runs) and preserved by all loop pasess in the manager. To make this
859*9880d681SAndroid Build Coastguard Worker   // reasonably robust, the set needed for most loop passes is maintained here.
860*9880d681SAndroid Build Coastguard Worker   // If your loop pass requires an analysis not listed here, you will need to
861*9880d681SAndroid Build Coastguard Worker   // carefully audit the loop pass manager nesting structure that results.
862*9880d681SAndroid Build Coastguard Worker   AU.addRequired<AAResultsWrapperPass>();
863*9880d681SAndroid Build Coastguard Worker   AU.addPreserved<AAResultsWrapperPass>();
864*9880d681SAndroid Build Coastguard Worker   AU.addPreserved<BasicAAWrapperPass>();
865*9880d681SAndroid Build Coastguard Worker   AU.addPreserved<GlobalsAAWrapperPass>();
866*9880d681SAndroid Build Coastguard Worker   AU.addPreserved<SCEVAAWrapperPass>();
867*9880d681SAndroid Build Coastguard Worker   AU.addRequired<ScalarEvolutionWrapperPass>();
868*9880d681SAndroid Build Coastguard Worker   AU.addPreserved<ScalarEvolutionWrapperPass>();
869*9880d681SAndroid Build Coastguard Worker }
870*9880d681SAndroid Build Coastguard Worker 
871*9880d681SAndroid Build Coastguard Worker /// Manually defined generic "LoopPass" dependency initialization. This is used
872*9880d681SAndroid Build Coastguard Worker /// to initialize the exact set of passes from above in \c
873*9880d681SAndroid Build Coastguard Worker /// getLoopAnalysisUsage. It can be used within a loop pass's initialization
874*9880d681SAndroid Build Coastguard Worker /// with:
875*9880d681SAndroid Build Coastguard Worker ///
876*9880d681SAndroid Build Coastguard Worker ///   INITIALIZE_PASS_DEPENDENCY(LoopPass)
877*9880d681SAndroid Build Coastguard Worker ///
878*9880d681SAndroid Build Coastguard Worker /// As-if "LoopPass" were a pass.
initializeLoopPassPass(PassRegistry & Registry)879*9880d681SAndroid Build Coastguard Worker void llvm::initializeLoopPassPass(PassRegistry &Registry) {
880*9880d681SAndroid Build Coastguard Worker   INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
881*9880d681SAndroid Build Coastguard Worker   INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
882*9880d681SAndroid Build Coastguard Worker   INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
883*9880d681SAndroid Build Coastguard Worker   INITIALIZE_PASS_DEPENDENCY(LCSSAWrapperPass)
884*9880d681SAndroid Build Coastguard Worker   INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
885*9880d681SAndroid Build Coastguard Worker   INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass)
886*9880d681SAndroid Build Coastguard Worker   INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
887*9880d681SAndroid Build Coastguard Worker   INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass)
888*9880d681SAndroid Build Coastguard Worker   INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
889*9880d681SAndroid Build Coastguard Worker }
890*9880d681SAndroid Build Coastguard Worker 
891*9880d681SAndroid Build Coastguard Worker /// \brief Find string metadata for loop
892*9880d681SAndroid Build Coastguard Worker ///
893*9880d681SAndroid Build Coastguard Worker /// If it has a value (e.g. {"llvm.distribute", 1} return the value as an
894*9880d681SAndroid Build Coastguard Worker /// operand or null otherwise.  If the string metadata is not found return
895*9880d681SAndroid Build Coastguard Worker /// Optional's not-a-value.
findStringMetadataForLoop(Loop * TheLoop,StringRef Name)896*9880d681SAndroid Build Coastguard Worker Optional<const MDOperand *> llvm::findStringMetadataForLoop(Loop *TheLoop,
897*9880d681SAndroid Build Coastguard Worker                                                             StringRef Name) {
898*9880d681SAndroid Build Coastguard Worker   MDNode *LoopID = TheLoop->getLoopID();
899*9880d681SAndroid Build Coastguard Worker   // Return none if LoopID is false.
900*9880d681SAndroid Build Coastguard Worker   if (!LoopID)
901*9880d681SAndroid Build Coastguard Worker     return None;
902*9880d681SAndroid Build Coastguard Worker 
903*9880d681SAndroid Build Coastguard Worker   // First operand should refer to the loop id itself.
904*9880d681SAndroid Build Coastguard Worker   assert(LoopID->getNumOperands() > 0 && "requires at least one operand");
905*9880d681SAndroid Build Coastguard Worker   assert(LoopID->getOperand(0) == LoopID && "invalid loop id");
906*9880d681SAndroid Build Coastguard Worker 
907*9880d681SAndroid Build Coastguard Worker   // Iterate over LoopID operands and look for MDString Metadata
908*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 1, e = LoopID->getNumOperands(); i < e; ++i) {
909*9880d681SAndroid Build Coastguard Worker     MDNode *MD = dyn_cast<MDNode>(LoopID->getOperand(i));
910*9880d681SAndroid Build Coastguard Worker     if (!MD)
911*9880d681SAndroid Build Coastguard Worker       continue;
912*9880d681SAndroid Build Coastguard Worker     MDString *S = dyn_cast<MDString>(MD->getOperand(0));
913*9880d681SAndroid Build Coastguard Worker     if (!S)
914*9880d681SAndroid Build Coastguard Worker       continue;
915*9880d681SAndroid Build Coastguard Worker     // Return true if MDString holds expected MetaData.
916*9880d681SAndroid Build Coastguard Worker     if (Name.equals(S->getString()))
917*9880d681SAndroid Build Coastguard Worker       switch (MD->getNumOperands()) {
918*9880d681SAndroid Build Coastguard Worker       case 1:
919*9880d681SAndroid Build Coastguard Worker         return nullptr;
920*9880d681SAndroid Build Coastguard Worker       case 2:
921*9880d681SAndroid Build Coastguard Worker         return &MD->getOperand(1);
922*9880d681SAndroid Build Coastguard Worker       default:
923*9880d681SAndroid Build Coastguard Worker         llvm_unreachable("loop metadata has 0 or 1 operand");
924*9880d681SAndroid Build Coastguard Worker       }
925*9880d681SAndroid Build Coastguard Worker   }
926*9880d681SAndroid Build Coastguard Worker   return None;
927*9880d681SAndroid Build Coastguard Worker }
928*9880d681SAndroid Build Coastguard Worker 
929*9880d681SAndroid Build Coastguard Worker /// Returns true if the instruction in a loop is guaranteed to execute at least
930*9880d681SAndroid Build Coastguard Worker /// once.
isGuaranteedToExecute(const Instruction & Inst,const DominatorTree * DT,const Loop * CurLoop,const LoopSafetyInfo * SafetyInfo)931*9880d681SAndroid Build Coastguard Worker bool llvm::isGuaranteedToExecute(const Instruction &Inst,
932*9880d681SAndroid Build Coastguard Worker                                  const DominatorTree *DT, const Loop *CurLoop,
933*9880d681SAndroid Build Coastguard Worker                                  const LoopSafetyInfo *SafetyInfo) {
934*9880d681SAndroid Build Coastguard Worker   // We have to check to make sure that the instruction dominates all
935*9880d681SAndroid Build Coastguard Worker   // of the exit blocks.  If it doesn't, then there is a path out of the loop
936*9880d681SAndroid Build Coastguard Worker   // which does not execute this instruction, so we can't hoist it.
937*9880d681SAndroid Build Coastguard Worker 
938*9880d681SAndroid Build Coastguard Worker   // If the instruction is in the header block for the loop (which is very
939*9880d681SAndroid Build Coastguard Worker   // common), it is always guaranteed to dominate the exit blocks.  Since this
940*9880d681SAndroid Build Coastguard Worker   // is a common case, and can save some work, check it now.
941*9880d681SAndroid Build Coastguard Worker   if (Inst.getParent() == CurLoop->getHeader())
942*9880d681SAndroid Build Coastguard Worker     // If there's a throw in the header block, we can't guarantee we'll reach
943*9880d681SAndroid Build Coastguard Worker     // Inst.
944*9880d681SAndroid Build Coastguard Worker     return !SafetyInfo->HeaderMayThrow;
945*9880d681SAndroid Build Coastguard Worker 
946*9880d681SAndroid Build Coastguard Worker   // Somewhere in this loop there is an instruction which may throw and make us
947*9880d681SAndroid Build Coastguard Worker   // exit the loop.
948*9880d681SAndroid Build Coastguard Worker   if (SafetyInfo->MayThrow)
949*9880d681SAndroid Build Coastguard Worker     return false;
950*9880d681SAndroid Build Coastguard Worker 
951*9880d681SAndroid Build Coastguard Worker   // Get the exit blocks for the current loop.
952*9880d681SAndroid Build Coastguard Worker   SmallVector<BasicBlock *, 8> ExitBlocks;
953*9880d681SAndroid Build Coastguard Worker   CurLoop->getExitBlocks(ExitBlocks);
954*9880d681SAndroid Build Coastguard Worker 
955*9880d681SAndroid Build Coastguard Worker   // Verify that the block dominates each of the exit blocks of the loop.
956*9880d681SAndroid Build Coastguard Worker   for (BasicBlock *ExitBlock : ExitBlocks)
957*9880d681SAndroid Build Coastguard Worker     if (!DT->dominates(Inst.getParent(), ExitBlock))
958*9880d681SAndroid Build Coastguard Worker       return false;
959*9880d681SAndroid Build Coastguard Worker 
960*9880d681SAndroid Build Coastguard Worker   // As a degenerate case, if the loop is statically infinite then we haven't
961*9880d681SAndroid Build Coastguard Worker   // proven anything since there are no exit blocks.
962*9880d681SAndroid Build Coastguard Worker   if (ExitBlocks.empty())
963*9880d681SAndroid Build Coastguard Worker     return false;
964*9880d681SAndroid Build Coastguard Worker 
965*9880d681SAndroid Build Coastguard Worker   // FIXME: In general, we have to prove that the loop isn't an infinite loop.
966*9880d681SAndroid Build Coastguard Worker   // See http::llvm.org/PR24078 .  (The "ExitBlocks.empty()" check above is
967*9880d681SAndroid Build Coastguard Worker   // just a special case of this.)
968*9880d681SAndroid Build Coastguard Worker   return true;
969*9880d681SAndroid Build Coastguard Worker }
970