Skip to content

Commit 7e98d69

Browse files
committed
Break LoopUtils into an Analysis file.
Summary: The InductionDescriptor and RecurrenceDescriptor classes basically analyze the IR to identify the respective IVs. So, it is better to have them in the "Analysis" directory instead of the "Transforms" directory. The rationale for this is to make the Induction and Recurrence descriptor classes available for analysis passes. Currently including them in an analysis pass produces link error (http://lists.llvm.org/pipermail/llvm-dev/2018-July/124456.html). Induction and Recurrence descriptors are moved from Transforms/Utils/LoopUtils.h|cpp to Analysis/IVDescriptors.h|cpp. Reviewers: dmgreen, llvm-commits, hfinkel Reviewed By: dmgreen Subscribers: mgorny Differential Revision: https://reviews.llvm.org/D51153 llvm-svn: 342016
1 parent dc32e91 commit 7e98d69

File tree

5 files changed

+1394
-1296
lines changed

5 files changed

+1394
-1296
lines changed
Lines changed: 352 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
//===- llvm/Analysis/IVDescriptors.h - IndVar Descriptors -------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This file "describes" induction and recurrence variables.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_ANALYSIS_IVDESCRIPTORS_H
15+
#define LLVM_ANALYSIS_IVDESCRIPTORS_H
16+
17+
#include "llvm/ADT/DenseMap.h"
18+
#include "llvm/ADT/Optional.h"
19+
#include "llvm/ADT/SetVector.h"
20+
#include "llvm/ADT/SmallPtrSet.h"
21+
#include "llvm/ADT/SmallVector.h"
22+
#include "llvm/ADT/StringRef.h"
23+
#include "llvm/Analysis/AliasAnalysis.h"
24+
#include "llvm/Analysis/DemandedBits.h"
25+
#include "llvm/Analysis/EHPersonalities.h"
26+
#include "llvm/Analysis/MustExecute.h"
27+
#include "llvm/Analysis/TargetTransformInfo.h"
28+
#include "llvm/IR/Dominators.h"
29+
#include "llvm/IR/IRBuilder.h"
30+
#include "llvm/IR/InstrTypes.h"
31+
#include "llvm/IR/Operator.h"
32+
#include "llvm/IR/ValueHandle.h"
33+
#include "llvm/Support/Casting.h"
34+
35+
namespace llvm {
36+
37+
class AliasSet;
38+
class AliasSetTracker;
39+
class BasicBlock;
40+
class DataLayout;
41+
class Loop;
42+
class LoopInfo;
43+
class OptimizationRemarkEmitter;
44+
class PredicatedScalarEvolution;
45+
class PredIteratorCache;
46+
class ScalarEvolution;
47+
class SCEV;
48+
class TargetLibraryInfo;
49+
class TargetTransformInfo;
50+
51+
/// The RecurrenceDescriptor is used to identify recurrences variables in a
52+
/// loop. Reduction is a special case of recurrence that has uses of the
53+
/// recurrence variable outside the loop. The method isReductionPHI identifies
54+
/// reductions that are basic recurrences.
55+
///
56+
/// Basic recurrences are defined as the summation, product, OR, AND, XOR, min,
57+
/// or max of a set of terms. For example: for(i=0; i<n; i++) { total +=
58+
/// array[i]; } is a summation of array elements. Basic recurrences are a
59+
/// special case of chains of recurrences (CR). See ScalarEvolution for CR
60+
/// references.
61+
62+
/// This struct holds information about recurrence variables.
63+
class RecurrenceDescriptor {
64+
public:
65+
/// This enum represents the kinds of recurrences that we support.
66+
enum RecurrenceKind {
67+
RK_NoRecurrence, ///< Not a recurrence.
68+
RK_IntegerAdd, ///< Sum of integers.
69+
RK_IntegerMult, ///< Product of integers.
70+
RK_IntegerOr, ///< Bitwise or logical OR of numbers.
71+
RK_IntegerAnd, ///< Bitwise or logical AND of numbers.
72+
RK_IntegerXor, ///< Bitwise or logical XOR of numbers.
73+
RK_IntegerMinMax, ///< Min/max implemented in terms of select(cmp()).
74+
RK_FloatAdd, ///< Sum of floats.
75+
RK_FloatMult, ///< Product of floats.
76+
RK_FloatMinMax ///< Min/max implemented in terms of select(cmp()).
77+
};
78+
79+
// This enum represents the kind of minmax recurrence.
80+
enum MinMaxRecurrenceKind {
81+
MRK_Invalid,
82+
MRK_UIntMin,
83+
MRK_UIntMax,
84+
MRK_SIntMin,
85+
MRK_SIntMax,
86+
MRK_FloatMin,
87+
MRK_FloatMax
88+
};
89+
90+
RecurrenceDescriptor() = default;
91+
92+
RecurrenceDescriptor(Value *Start, Instruction *Exit, RecurrenceKind K,
93+
MinMaxRecurrenceKind MK, Instruction *UAI, Type *RT,
94+
bool Signed, SmallPtrSetImpl<Instruction *> &CI)
95+
: StartValue(Start), LoopExitInstr(Exit), Kind(K), MinMaxKind(MK),
96+
UnsafeAlgebraInst(UAI), RecurrenceType(RT), IsSigned(Signed) {
97+
CastInsts.insert(CI.begin(), CI.end());
98+
}
99+
100+
/// This POD struct holds information about a potential recurrence operation.
101+
class InstDesc {
102+
public:
103+
InstDesc(bool IsRecur, Instruction *I, Instruction *UAI = nullptr)
104+
: IsRecurrence(IsRecur), PatternLastInst(I), MinMaxKind(MRK_Invalid),
105+
UnsafeAlgebraInst(UAI) {}
106+
107+
InstDesc(Instruction *I, MinMaxRecurrenceKind K, Instruction *UAI = nullptr)
108+
: IsRecurrence(true), PatternLastInst(I), MinMaxKind(K),
109+
UnsafeAlgebraInst(UAI) {}
110+
111+
bool isRecurrence() { return IsRecurrence; }
112+
113+
bool hasUnsafeAlgebra() { return UnsafeAlgebraInst != nullptr; }
114+
115+
Instruction *getUnsafeAlgebraInst() { return UnsafeAlgebraInst; }
116+
117+
MinMaxRecurrenceKind getMinMaxKind() { return MinMaxKind; }
118+
119+
Instruction *getPatternInst() { return PatternLastInst; }
120+
121+
private:
122+
// Is this instruction a recurrence candidate.
123+
bool IsRecurrence;
124+
// The last instruction in a min/max pattern (select of the select(icmp())
125+
// pattern), or the current recurrence instruction otherwise.
126+
Instruction *PatternLastInst;
127+
// If this is a min/max pattern the comparison predicate.
128+
MinMaxRecurrenceKind MinMaxKind;
129+
// Recurrence has unsafe algebra.
130+
Instruction *UnsafeAlgebraInst;
131+
};
132+
133+
/// Returns a struct describing if the instruction 'I' can be a recurrence
134+
/// variable of type 'Kind'. If the recurrence is a min/max pattern of
135+
/// select(icmp()) this function advances the instruction pointer 'I' from the
136+
/// compare instruction to the select instruction and stores this pointer in
137+
/// 'PatternLastInst' member of the returned struct.
138+
static InstDesc isRecurrenceInstr(Instruction *I, RecurrenceKind Kind,
139+
InstDesc &Prev, bool HasFunNoNaNAttr);
140+
141+
/// Returns true if instruction I has multiple uses in Insts
142+
static bool hasMultipleUsesOf(Instruction *I,
143+
SmallPtrSetImpl<Instruction *> &Insts);
144+
145+
/// Returns true if all uses of the instruction I is within the Set.
146+
static bool areAllUsesIn(Instruction *I, SmallPtrSetImpl<Instruction *> &Set);
147+
148+
/// Returns a struct describing if the instruction if the instruction is a
149+
/// Select(ICmp(X, Y), X, Y) instruction pattern corresponding to a min(X, Y)
150+
/// or max(X, Y).
151+
static InstDesc isMinMaxSelectCmpPattern(Instruction *I, InstDesc &Prev);
152+
153+
/// Returns identity corresponding to the RecurrenceKind.
154+
static Constant *getRecurrenceIdentity(RecurrenceKind K, Type *Tp);
155+
156+
/// Returns the opcode of binary operation corresponding to the
157+
/// RecurrenceKind.
158+
static unsigned getRecurrenceBinOp(RecurrenceKind Kind);
159+
160+
/// Returns true if Phi is a reduction of type Kind and adds it to the
161+
/// RecurrenceDescriptor. If either \p DB is non-null or \p AC and \p DT are
162+
/// non-null, the minimal bit width needed to compute the reduction will be
163+
/// computed.
164+
static bool AddReductionVar(PHINode *Phi, RecurrenceKind Kind, Loop *TheLoop,
165+
bool HasFunNoNaNAttr,
166+
RecurrenceDescriptor &RedDes,
167+
DemandedBits *DB = nullptr,
168+
AssumptionCache *AC = nullptr,
169+
DominatorTree *DT = nullptr);
170+
171+
/// Returns true if Phi is a reduction in TheLoop. The RecurrenceDescriptor
172+
/// is returned in RedDes. If either \p DB is non-null or \p AC and \p DT are
173+
/// non-null, the minimal bit width needed to compute the reduction will be
174+
/// computed.
175+
static bool isReductionPHI(PHINode *Phi, Loop *TheLoop,
176+
RecurrenceDescriptor &RedDes,
177+
DemandedBits *DB = nullptr,
178+
AssumptionCache *AC = nullptr,
179+
DominatorTree *DT = nullptr);
180+
181+
/// Returns true if Phi is a first-order recurrence. A first-order recurrence
182+
/// is a non-reduction recurrence relation in which the value of the
183+
/// recurrence in the current loop iteration equals a value defined in the
184+
/// previous iteration. \p SinkAfter includes pairs of instructions where the
185+
/// first will be rescheduled to appear after the second if/when the loop is
186+
/// vectorized. It may be augmented with additional pairs if needed in order
187+
/// to handle Phi as a first-order recurrence.
188+
static bool
189+
isFirstOrderRecurrence(PHINode *Phi, Loop *TheLoop,
190+
DenseMap<Instruction *, Instruction *> &SinkAfter,
191+
DominatorTree *DT);
192+
193+
RecurrenceKind getRecurrenceKind() { return Kind; }
194+
195+
MinMaxRecurrenceKind getMinMaxRecurrenceKind() { return MinMaxKind; }
196+
197+
TrackingVH<Value> getRecurrenceStartValue() { return StartValue; }
198+
199+
Instruction *getLoopExitInstr() { return LoopExitInstr; }
200+
201+
/// Returns true if the recurrence has unsafe algebra which requires a relaxed
202+
/// floating-point model.
203+
bool hasUnsafeAlgebra() { return UnsafeAlgebraInst != nullptr; }
204+
205+
/// Returns first unsafe algebra instruction in the PHI node's use-chain.
206+
Instruction *getUnsafeAlgebraInst() { return UnsafeAlgebraInst; }
207+
208+
/// Returns true if the recurrence kind is an integer kind.
209+
static bool isIntegerRecurrenceKind(RecurrenceKind Kind);
210+
211+
/// Returns true if the recurrence kind is a floating point kind.
212+
static bool isFloatingPointRecurrenceKind(RecurrenceKind Kind);
213+
214+
/// Returns true if the recurrence kind is an arithmetic kind.
215+
static bool isArithmeticRecurrenceKind(RecurrenceKind Kind);
216+
217+
/// Returns the type of the recurrence. This type can be narrower than the
218+
/// actual type of the Phi if the recurrence has been type-promoted.
219+
Type *getRecurrenceType() { return RecurrenceType; }
220+
221+
/// Returns a reference to the instructions used for type-promoting the
222+
/// recurrence.
223+
SmallPtrSet<Instruction *, 8> &getCastInsts() { return CastInsts; }
224+
225+
/// Returns true if all source operands of the recurrence are SExtInsts.
226+
bool isSigned() { return IsSigned; }
227+
228+
private:
229+
// The starting value of the recurrence.
230+
// It does not have to be zero!
231+
TrackingVH<Value> StartValue;
232+
// The instruction who's value is used outside the loop.
233+
Instruction *LoopExitInstr = nullptr;
234+
// The kind of the recurrence.
235+
RecurrenceKind Kind = RK_NoRecurrence;
236+
// If this a min/max recurrence the kind of recurrence.
237+
MinMaxRecurrenceKind MinMaxKind = MRK_Invalid;
238+
// First occurrence of unasfe algebra in the PHI's use-chain.
239+
Instruction *UnsafeAlgebraInst = nullptr;
240+
// The type of the recurrence.
241+
Type *RecurrenceType = nullptr;
242+
// True if all source operands of the recurrence are SExtInsts.
243+
bool IsSigned = false;
244+
// Instructions used for type-promoting the recurrence.
245+
SmallPtrSet<Instruction *, 8> CastInsts;
246+
};
247+
248+
/// A struct for saving information about induction variables.
249+
class InductionDescriptor {
250+
public:
251+
/// This enum represents the kinds of inductions that we support.
252+
enum InductionKind {
253+
IK_NoInduction, ///< Not an induction variable.
254+
IK_IntInduction, ///< Integer induction variable. Step = C.
255+
IK_PtrInduction, ///< Pointer induction var. Step = C / sizeof(elem).
256+
IK_FpInduction ///< Floating point induction variable.
257+
};
258+
259+
public:
260+
/// Default constructor - creates an invalid induction.
261+
InductionDescriptor() = default;
262+
263+
/// Get the consecutive direction. Returns:
264+
/// 0 - unknown or non-consecutive.
265+
/// 1 - consecutive and increasing.
266+
/// -1 - consecutive and decreasing.
267+
int getConsecutiveDirection() const;
268+
269+
Value *getStartValue() const { return StartValue; }
270+
InductionKind getKind() const { return IK; }
271+
const SCEV *getStep() const { return Step; }
272+
BinaryOperator *getInductionBinOp() const { return InductionBinOp; }
273+
ConstantInt *getConstIntStepValue() const;
274+
275+
/// Returns true if \p Phi is an induction in the loop \p L. If \p Phi is an
276+
/// induction, the induction descriptor \p D will contain the data describing
277+
/// this induction. If by some other means the caller has a better SCEV
278+
/// expression for \p Phi than the one returned by the ScalarEvolution
279+
/// analysis, it can be passed through \p Expr. If the def-use chain
280+
/// associated with the phi includes casts (that we know we can ignore
281+
/// under proper runtime checks), they are passed through \p CastsToIgnore.
282+
static bool
283+
isInductionPHI(PHINode *Phi, const Loop *L, ScalarEvolution *SE,
284+
InductionDescriptor &D, const SCEV *Expr = nullptr,
285+
SmallVectorImpl<Instruction *> *CastsToIgnore = nullptr);
286+
287+
/// Returns true if \p Phi is a floating point induction in the loop \p L.
288+
/// If \p Phi is an induction, the induction descriptor \p D will contain
289+
/// the data describing this induction.
290+
static bool isFPInductionPHI(PHINode *Phi, const Loop *L, ScalarEvolution *SE,
291+
InductionDescriptor &D);
292+
293+
/// Returns true if \p Phi is a loop \p L induction, in the context associated
294+
/// with the run-time predicate of PSE. If \p Assume is true, this can add
295+
/// further SCEV predicates to \p PSE in order to prove that \p Phi is an
296+
/// induction.
297+
/// If \p Phi is an induction, \p D will contain the data describing this
298+
/// induction.
299+
static bool isInductionPHI(PHINode *Phi, const Loop *L,
300+
PredicatedScalarEvolution &PSE,
301+
InductionDescriptor &D, bool Assume = false);
302+
303+
/// Returns true if the induction type is FP and the binary operator does
304+
/// not have the "fast-math" property. Such operation requires a relaxed FP
305+
/// mode.
306+
bool hasUnsafeAlgebra() {
307+
return InductionBinOp && !cast<FPMathOperator>(InductionBinOp)->isFast();
308+
}
309+
310+
/// Returns induction operator that does not have "fast-math" property
311+
/// and requires FP unsafe mode.
312+
Instruction *getUnsafeAlgebraInst() {
313+
if (!InductionBinOp || cast<FPMathOperator>(InductionBinOp)->isFast())
314+
return nullptr;
315+
return InductionBinOp;
316+
}
317+
318+
/// Returns binary opcode of the induction operator.
319+
Instruction::BinaryOps getInductionOpcode() const {
320+
return InductionBinOp ? InductionBinOp->getOpcode()
321+
: Instruction::BinaryOpsEnd;
322+
}
323+
324+
/// Returns a reference to the type cast instructions in the induction
325+
/// update chain, that are redundant when guarded with a runtime
326+
/// SCEV overflow check.
327+
const SmallVectorImpl<Instruction *> &getCastInsts() const {
328+
return RedundantCasts;
329+
}
330+
331+
private:
332+
/// Private constructor - used by \c isInductionPHI.
333+
InductionDescriptor(Value *Start, InductionKind K, const SCEV *Step,
334+
BinaryOperator *InductionBinOp = nullptr,
335+
SmallVectorImpl<Instruction *> *Casts = nullptr);
336+
337+
/// Start value.
338+
TrackingVH<Value> StartValue;
339+
/// Induction kind.
340+
InductionKind IK = IK_NoInduction;
341+
/// Step value.
342+
const SCEV *Step = nullptr;
343+
// Instruction that advances induction variable.
344+
BinaryOperator *InductionBinOp = nullptr;
345+
// Instructions used for type-casts of the induction variable,
346+
// that are redundant when guarded with a runtime SCEV overflow check.
347+
SmallVector<Instruction *, 2> RedundantCasts;
348+
};
349+
350+
} // end namespace llvm
351+
352+
#endif // LLVM_ANALYSIS_IVDESCRIPTORS_H

0 commit comments

Comments
 (0)