parent
482495695e
commit
65b6056e37
|
@ -34,7 +34,7 @@ class IVUsersOfOneStride;
|
||||||
class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
|
class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
|
||||||
public:
|
public:
|
||||||
IVStrideUse(IVUsersOfOneStride *parent,
|
IVStrideUse(IVUsersOfOneStride *parent,
|
||||||
const SCEVHandle &offset,
|
const SCEV* offset,
|
||||||
Instruction* U, Value *O)
|
Instruction* U, Value *O)
|
||||||
: CallbackVH(U), Parent(parent), Offset(offset),
|
: CallbackVH(U), Parent(parent), Offset(offset),
|
||||||
OperandValToReplace(O),
|
OperandValToReplace(O),
|
||||||
|
@ -58,10 +58,10 @@ public:
|
||||||
/// getOffset - Return the offset to add to a theoeretical induction
|
/// getOffset - Return the offset to add to a theoeretical induction
|
||||||
/// variable that starts at zero and counts up by the stride to compute
|
/// variable that starts at zero and counts up by the stride to compute
|
||||||
/// the value for the use. This always has the same type as the stride.
|
/// the value for the use. This always has the same type as the stride.
|
||||||
SCEVHandle getOffset() const { return Offset; }
|
const SCEV* getOffset() const { return Offset; }
|
||||||
|
|
||||||
/// setOffset - Assign a new offset to this use.
|
/// setOffset - Assign a new offset to this use.
|
||||||
void setOffset(SCEVHandle Val) {
|
void setOffset(const SCEV* Val) {
|
||||||
Offset = Val;
|
Offset = Val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ private:
|
||||||
IVUsersOfOneStride *Parent;
|
IVUsersOfOneStride *Parent;
|
||||||
|
|
||||||
/// Offset - The offset to add to the base induction expression.
|
/// Offset - The offset to add to the base induction expression.
|
||||||
SCEVHandle Offset;
|
const SCEV* Offset;
|
||||||
|
|
||||||
/// OperandValToReplace - The Value of the operand in the user instruction
|
/// OperandValToReplace - The Value of the operand in the user instruction
|
||||||
/// that this IVStrideUse is representing.
|
/// that this IVStrideUse is representing.
|
||||||
|
@ -158,7 +158,7 @@ public:
|
||||||
/// initial value and the operand that uses the IV.
|
/// initial value and the operand that uses the IV.
|
||||||
ilist<IVStrideUse> Users;
|
ilist<IVStrideUse> Users;
|
||||||
|
|
||||||
void addUser(const SCEVHandle &Offset, Instruction *User, Value *Operand) {
|
void addUser(const SCEV* Offset, Instruction *User, Value *Operand) {
|
||||||
Users.push_back(new IVStrideUse(this, Offset, User, Operand));
|
Users.push_back(new IVStrideUse(this, Offset, User, Operand));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -178,12 +178,12 @@ public:
|
||||||
|
|
||||||
/// IVUsesByStride - A mapping from the strides in StrideOrder to the
|
/// IVUsesByStride - A mapping from the strides in StrideOrder to the
|
||||||
/// uses in IVUses.
|
/// uses in IVUses.
|
||||||
std::map<SCEVHandle, IVUsersOfOneStride*> IVUsesByStride;
|
std::map<const SCEV*, IVUsersOfOneStride*> IVUsesByStride;
|
||||||
|
|
||||||
/// StrideOrder - An ordering of the keys in IVUsesByStride that is stable:
|
/// StrideOrder - An ordering of the keys in IVUsesByStride that is stable:
|
||||||
/// We use this to iterate over the IVUsesByStride collection without being
|
/// We use this to iterate over the IVUsesByStride collection without being
|
||||||
/// dependent on random ordering of pointers in the process.
|
/// dependent on random ordering of pointers in the process.
|
||||||
SmallVector<SCEVHandle, 16> StrideOrder;
|
SmallVector<const SCEV*, 16> StrideOrder;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||||
|
@ -203,7 +203,7 @@ public:
|
||||||
|
|
||||||
/// getReplacementExpr - Return a SCEV expression which computes the
|
/// getReplacementExpr - Return a SCEV expression which computes the
|
||||||
/// value of the OperandValToReplace of the given IVStrideUse.
|
/// value of the OperandValToReplace of the given IVStrideUse.
|
||||||
SCEVHandle getReplacementExpr(const IVStrideUse &U) const;
|
const SCEV* getReplacementExpr(const IVStrideUse &U) const;
|
||||||
|
|
||||||
void print(raw_ostream &OS, const Module* = 0) const;
|
void print(raw_ostream &OS, const Module* = 0) const;
|
||||||
virtual void print(std::ostream &OS, const Module* = 0) const;
|
virtual void print(std::ostream &OS, const Module* = 0) const;
|
||||||
|
|
|
@ -78,9 +78,9 @@ public:
|
||||||
private:
|
private:
|
||||||
ConstantRange compute(Value *V);
|
ConstantRange compute(Value *V);
|
||||||
|
|
||||||
ConstantRange getRange(SCEVHandle S, Loop *L, ScalarEvolution &SE);
|
ConstantRange getRange(const SCEV* S, Loop *L, ScalarEvolution &SE);
|
||||||
|
|
||||||
ConstantRange getRange(SCEVHandle S, SCEVHandle T, ScalarEvolution &SE);
|
ConstantRange getRange(const SCEV* S, const SCEV* T, ScalarEvolution &SE);
|
||||||
|
|
||||||
std::map<Value *, ConstantRange *> Map;
|
std::map<Value *, ConstantRange *> Map;
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,7 +32,6 @@ namespace llvm {
|
||||||
class APInt;
|
class APInt;
|
||||||
class ConstantInt;
|
class ConstantInt;
|
||||||
class Type;
|
class Type;
|
||||||
class SCEVHandle;
|
|
||||||
class ScalarEvolution;
|
class ScalarEvolution;
|
||||||
class TargetData;
|
class TargetData;
|
||||||
class SCEVConstant;
|
class SCEVConstant;
|
||||||
|
@ -43,7 +42,6 @@ namespace llvm {
|
||||||
class SCEVSignExtendExpr;
|
class SCEVSignExtendExpr;
|
||||||
class SCEVAddRecExpr;
|
class SCEVAddRecExpr;
|
||||||
class SCEVUnknown;
|
class SCEVUnknown;
|
||||||
template<> struct DenseMapInfo<SCEVHandle>;
|
|
||||||
|
|
||||||
/// SCEV - This class represents an analyzed expression in the program. These
|
/// SCEV - This class represents an analyzed expression in the program. These
|
||||||
/// are reference-counted opaque objects that the client is not allowed to
|
/// are reference-counted opaque objects that the client is not allowed to
|
||||||
|
@ -52,9 +50,6 @@ namespace llvm {
|
||||||
class SCEV {
|
class SCEV {
|
||||||
const unsigned SCEVType; // The SCEV baseclass this node corresponds to
|
const unsigned SCEVType; // The SCEV baseclass this node corresponds to
|
||||||
|
|
||||||
friend class SCEVHandle;
|
|
||||||
friend class DenseMapInfo<SCEVHandle>;
|
|
||||||
|
|
||||||
const ScalarEvolution* parent;
|
const ScalarEvolution* parent;
|
||||||
|
|
||||||
SCEV(const SCEV &); // DO NOT IMPLEMENT
|
SCEV(const SCEV &); // DO NOT IMPLEMENT
|
||||||
|
@ -94,9 +89,9 @@ namespace llvm {
|
||||||
/// the same value, but which uses the concrete value Conc instead of the
|
/// the same value, but which uses the concrete value Conc instead of the
|
||||||
/// symbolic value. If this SCEV does not use the symbolic value, it
|
/// symbolic value. If this SCEV does not use the symbolic value, it
|
||||||
/// returns itself.
|
/// returns itself.
|
||||||
virtual SCEVHandle
|
virtual const SCEV*
|
||||||
replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
|
replaceSymbolicValuesWithConcrete(const SCEV* Sym,
|
||||||
const SCEVHandle &Conc,
|
const SCEV* Conc,
|
||||||
ScalarEvolution &SE) const = 0;
|
ScalarEvolution &SE) const = 0;
|
||||||
|
|
||||||
/// dominates - Return true if elements that makes up this SCEV dominates
|
/// dominates - Return true if elements that makes up this SCEV dominates
|
||||||
|
@ -139,9 +134,9 @@ namespace llvm {
|
||||||
virtual const Type *getType() const;
|
virtual const Type *getType() const;
|
||||||
virtual bool hasComputableLoopEvolution(const Loop *L) const;
|
virtual bool hasComputableLoopEvolution(const Loop *L) const;
|
||||||
virtual void print(raw_ostream &OS) const;
|
virtual void print(raw_ostream &OS) const;
|
||||||
virtual SCEVHandle
|
virtual const SCEV*
|
||||||
replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
|
replaceSymbolicValuesWithConcrete(const SCEV* Sym,
|
||||||
const SCEVHandle &Conc,
|
const SCEV* Conc,
|
||||||
ScalarEvolution &SE) const;
|
ScalarEvolution &SE) const;
|
||||||
|
|
||||||
virtual bool dominates(BasicBlock *BB, DominatorTree *DT) const {
|
virtual bool dominates(BasicBlock *BB, DominatorTree *DT) const {
|
||||||
|
@ -153,72 +148,6 @@ namespace llvm {
|
||||||
static bool classof(const SCEV *S);
|
static bool classof(const SCEV *S);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// SCEVHandle - This class is used to maintain the SCEV object's refcounts,
|
|
||||||
/// freeing the objects when the last reference is dropped.
|
|
||||||
class SCEVHandle {
|
|
||||||
const SCEV *S;
|
|
||||||
SCEVHandle(); // DO NOT IMPLEMENT
|
|
||||||
public:
|
|
||||||
SCEVHandle(const SCEV *s) : S(s) {
|
|
||||||
assert(S && "Cannot create a handle to a null SCEV!");
|
|
||||||
}
|
|
||||||
SCEVHandle(const SCEVHandle &RHS) : S(RHS.S) { }
|
|
||||||
~SCEVHandle() { }
|
|
||||||
|
|
||||||
operator const SCEV*() const { return S; }
|
|
||||||
|
|
||||||
const SCEV &operator*() const { return *S; }
|
|
||||||
const SCEV *operator->() const { return S; }
|
|
||||||
|
|
||||||
bool operator==(const SCEV *RHS) const { return S == RHS; }
|
|
||||||
bool operator!=(const SCEV *RHS) const { return S != RHS; }
|
|
||||||
|
|
||||||
const SCEVHandle &operator=(SCEV *RHS) {
|
|
||||||
if (S != RHS) {
|
|
||||||
S = RHS;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SCEVHandle &operator=(const SCEVHandle &RHS) {
|
|
||||||
if (S != RHS.S) {
|
|
||||||
S = RHS.S;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename From> struct simplify_type;
|
|
||||||
template<> struct simplify_type<const SCEVHandle> {
|
|
||||||
typedef const SCEV* SimpleType;
|
|
||||||
static SimpleType getSimplifiedValue(const SCEVHandle &Node) {
|
|
||||||
return Node;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<> struct simplify_type<SCEVHandle>
|
|
||||||
: public simplify_type<const SCEVHandle> {};
|
|
||||||
|
|
||||||
// Specialize DenseMapInfo for SCEVHandle so that SCEVHandle may be used
|
|
||||||
// as a key in DenseMaps.
|
|
||||||
template<>
|
|
||||||
struct DenseMapInfo<SCEVHandle> {
|
|
||||||
static inline SCEVHandle getEmptyKey() {
|
|
||||||
static SCEVCouldNotCompute Empty(0);
|
|
||||||
return &Empty;
|
|
||||||
}
|
|
||||||
static inline SCEVHandle getTombstoneKey() {
|
|
||||||
static SCEVCouldNotCompute Tombstone(0);
|
|
||||||
return &Tombstone;
|
|
||||||
}
|
|
||||||
static unsigned getHashValue(const SCEVHandle &Val) {
|
|
||||||
return DenseMapInfo<const SCEV *>::getHashValue(Val);
|
|
||||||
}
|
|
||||||
static bool isEqual(const SCEVHandle &LHS, const SCEVHandle &RHS) {
|
|
||||||
return LHS == RHS;
|
|
||||||
}
|
|
||||||
static bool isPod() { return false; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/// ScalarEvolution - This class is the main scalar evolution driver. Because
|
/// ScalarEvolution - This class is the main scalar evolution driver. Because
|
||||||
/// client code (intentionally) can't do much with the SCEV objects directly,
|
/// client code (intentionally) can't do much with the SCEV objects directly,
|
||||||
/// they must ask this class for services.
|
/// they must ask this class for services.
|
||||||
|
@ -251,11 +180,11 @@ namespace llvm {
|
||||||
|
|
||||||
/// CouldNotCompute - This SCEV is used to represent unknown trip
|
/// CouldNotCompute - This SCEV is used to represent unknown trip
|
||||||
/// counts and things.
|
/// counts and things.
|
||||||
SCEVHandle CouldNotCompute;
|
const SCEV* CouldNotCompute;
|
||||||
|
|
||||||
/// Scalars - This is a cache of the scalars we have analyzed so far.
|
/// Scalars - This is a cache of the scalars we have analyzed so far.
|
||||||
///
|
///
|
||||||
std::map<SCEVCallbackVH, SCEVHandle> Scalars;
|
std::map<SCEVCallbackVH, const SCEV*> Scalars;
|
||||||
|
|
||||||
/// BackedgeTakenInfo - Information about the backedge-taken count
|
/// BackedgeTakenInfo - Information about the backedge-taken count
|
||||||
/// of a loop. This currently inclues an exact count and a maximum count.
|
/// of a loop. This currently inclues an exact count and a maximum count.
|
||||||
|
@ -263,19 +192,16 @@ namespace llvm {
|
||||||
struct BackedgeTakenInfo {
|
struct BackedgeTakenInfo {
|
||||||
/// Exact - An expression indicating the exact backedge-taken count of
|
/// Exact - An expression indicating the exact backedge-taken count of
|
||||||
/// the loop if it is known, or a SCEVCouldNotCompute otherwise.
|
/// the loop if it is known, or a SCEVCouldNotCompute otherwise.
|
||||||
SCEVHandle Exact;
|
const SCEV* Exact;
|
||||||
|
|
||||||
/// Exact - An expression indicating the least maximum backedge-taken
|
/// Exact - An expression indicating the least maximum backedge-taken
|
||||||
/// count of the loop that is known, or a SCEVCouldNotCompute.
|
/// count of the loop that is known, or a SCEVCouldNotCompute.
|
||||||
SCEVHandle Max;
|
const SCEV* Max;
|
||||||
|
|
||||||
/*implicit*/ BackedgeTakenInfo(SCEVHandle exact) :
|
/*implicit*/ BackedgeTakenInfo(const SCEV* exact) :
|
||||||
Exact(exact), Max(exact) {}
|
Exact(exact), Max(exact) {}
|
||||||
|
|
||||||
/*implicit*/ BackedgeTakenInfo(const SCEV *exact) :
|
BackedgeTakenInfo(const SCEV* exact, const SCEV* max) :
|
||||||
Exact(exact), Max(exact) {}
|
|
||||||
|
|
||||||
BackedgeTakenInfo(SCEVHandle exact, SCEVHandle max) :
|
|
||||||
Exact(exact), Max(max) {}
|
Exact(exact), Max(max) {}
|
||||||
|
|
||||||
/// hasAnyInfo - Test whether this BackedgeTakenInfo contains any
|
/// hasAnyInfo - Test whether this BackedgeTakenInfo contains any
|
||||||
|
@ -305,30 +231,30 @@ namespace llvm {
|
||||||
|
|
||||||
/// createSCEV - We know that there is no SCEV for the specified value.
|
/// createSCEV - We know that there is no SCEV for the specified value.
|
||||||
/// Analyze the expression.
|
/// Analyze the expression.
|
||||||
SCEVHandle createSCEV(Value *V);
|
const SCEV* createSCEV(Value *V);
|
||||||
|
|
||||||
/// createNodeForPHI - Provide the special handling we need to analyze PHI
|
/// createNodeForPHI - Provide the special handling we need to analyze PHI
|
||||||
/// SCEVs.
|
/// SCEVs.
|
||||||
SCEVHandle createNodeForPHI(PHINode *PN);
|
const SCEV* createNodeForPHI(PHINode *PN);
|
||||||
|
|
||||||
/// createNodeForGEP - Provide the special handling we need to analyze GEP
|
/// createNodeForGEP - Provide the special handling we need to analyze GEP
|
||||||
/// SCEVs.
|
/// SCEVs.
|
||||||
SCEVHandle createNodeForGEP(User *GEP);
|
const SCEV* createNodeForGEP(User *GEP);
|
||||||
|
|
||||||
/// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value
|
/// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value
|
||||||
/// for the specified instruction and replaces any references to the
|
/// for the specified instruction and replaces any references to the
|
||||||
/// symbolic value SymName with the specified value. This is used during
|
/// symbolic value SymName with the specified value. This is used during
|
||||||
/// PHI resolution.
|
/// PHI resolution.
|
||||||
void ReplaceSymbolicValueWithConcrete(Instruction *I,
|
void ReplaceSymbolicValueWithConcrete(Instruction *I,
|
||||||
const SCEVHandle &SymName,
|
const SCEV* SymName,
|
||||||
const SCEVHandle &NewVal);
|
const SCEV* NewVal);
|
||||||
|
|
||||||
/// getBECount - Subtract the end and start values and divide by the step,
|
/// getBECount - Subtract the end and start values and divide by the step,
|
||||||
/// rounding up, to get the number of times the backedge is executed. Return
|
/// rounding up, to get the number of times the backedge is executed. Return
|
||||||
/// CouldNotCompute if an intermediate computation overflows.
|
/// CouldNotCompute if an intermediate computation overflows.
|
||||||
SCEVHandle getBECount(const SCEVHandle &Start,
|
const SCEV* getBECount(const SCEV* Start,
|
||||||
const SCEVHandle &End,
|
const SCEV* End,
|
||||||
const SCEVHandle &Step);
|
const SCEV* Step);
|
||||||
|
|
||||||
/// getBackedgeTakenInfo - Return the BackedgeTakenInfo for the given
|
/// getBackedgeTakenInfo - Return the BackedgeTakenInfo for the given
|
||||||
/// loop, lazily computing new values if the loop hasn't been analyzed
|
/// loop, lazily computing new values if the loop hasn't been analyzed
|
||||||
|
@ -366,7 +292,7 @@ namespace llvm {
|
||||||
|
|
||||||
/// ComputeLoadConstantCompareBackedgeTakenCount - Given an exit condition
|
/// ComputeLoadConstantCompareBackedgeTakenCount - Given an exit condition
|
||||||
/// of 'icmp op load X, cst', try to see if we can compute the trip count.
|
/// of 'icmp op load X, cst', try to see if we can compute the trip count.
|
||||||
SCEVHandle
|
const SCEV*
|
||||||
ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI,
|
ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI,
|
||||||
Constant *RHS,
|
Constant *RHS,
|
||||||
const Loop *L,
|
const Loop *L,
|
||||||
|
@ -377,18 +303,18 @@ namespace llvm {
|
||||||
/// try to evaluate a few iterations of the loop until we get the exit
|
/// try to evaluate a few iterations of the loop until we get the exit
|
||||||
/// condition gets a value of ExitWhen (true or false). If we cannot
|
/// condition gets a value of ExitWhen (true or false). If we cannot
|
||||||
/// evaluate the trip count of the loop, return CouldNotCompute.
|
/// evaluate the trip count of the loop, return CouldNotCompute.
|
||||||
SCEVHandle ComputeBackedgeTakenCountExhaustively(const Loop *L, Value *Cond,
|
const SCEV* ComputeBackedgeTakenCountExhaustively(const Loop *L, Value *Cond,
|
||||||
bool ExitWhen);
|
bool ExitWhen);
|
||||||
|
|
||||||
/// HowFarToZero - Return the number of times a backedge comparing the
|
/// HowFarToZero - Return the number of times a backedge comparing the
|
||||||
/// specified value to zero will execute. If not computable, return
|
/// specified value to zero will execute. If not computable, return
|
||||||
/// CouldNotCompute.
|
/// CouldNotCompute.
|
||||||
SCEVHandle HowFarToZero(const SCEV *V, const Loop *L);
|
const SCEV* HowFarToZero(const SCEV *V, const Loop *L);
|
||||||
|
|
||||||
/// HowFarToNonZero - Return the number of times a backedge checking the
|
/// HowFarToNonZero - Return the number of times a backedge checking the
|
||||||
/// specified value for nonzero will execute. If not computable, return
|
/// specified value for nonzero will execute. If not computable, return
|
||||||
/// CouldNotCompute.
|
/// CouldNotCompute.
|
||||||
SCEVHandle HowFarToNonZero(const SCEV *V, const Loop *L);
|
const SCEV* HowFarToNonZero(const SCEV *V, const Loop *L);
|
||||||
|
|
||||||
/// HowManyLessThans - Return the number of times a backedge containing the
|
/// HowManyLessThans - Return the number of times a backedge containing the
|
||||||
/// specified less-than comparison will execute. If not computable, return
|
/// specified less-than comparison will execute. If not computable, return
|
||||||
|
@ -440,115 +366,115 @@ namespace llvm {
|
||||||
|
|
||||||
/// getSCEV - Return a SCEV expression handle for the full generality of the
|
/// getSCEV - Return a SCEV expression handle for the full generality of the
|
||||||
/// specified expression.
|
/// specified expression.
|
||||||
SCEVHandle getSCEV(Value *V);
|
const SCEV* getSCEV(Value *V);
|
||||||
|
|
||||||
SCEVHandle getConstant(ConstantInt *V);
|
const SCEV* getConstant(ConstantInt *V);
|
||||||
SCEVHandle getConstant(const APInt& Val);
|
const SCEV* getConstant(const APInt& Val);
|
||||||
SCEVHandle getConstant(const Type *Ty, uint64_t V, bool isSigned = false);
|
const SCEV* getConstant(const Type *Ty, uint64_t V, bool isSigned = false);
|
||||||
SCEVHandle getTruncateExpr(const SCEVHandle &Op, const Type *Ty);
|
const SCEV* getTruncateExpr(const SCEV* Op, const Type *Ty);
|
||||||
SCEVHandle getZeroExtendExpr(const SCEVHandle &Op, const Type *Ty);
|
const SCEV* getZeroExtendExpr(const SCEV* Op, const Type *Ty);
|
||||||
SCEVHandle getSignExtendExpr(const SCEVHandle &Op, const Type *Ty);
|
const SCEV* getSignExtendExpr(const SCEV* Op, const Type *Ty);
|
||||||
SCEVHandle getAnyExtendExpr(const SCEVHandle &Op, const Type *Ty);
|
const SCEV* getAnyExtendExpr(const SCEV* Op, const Type *Ty);
|
||||||
SCEVHandle getAddExpr(SmallVectorImpl<SCEVHandle> &Ops);
|
const SCEV* getAddExpr(SmallVectorImpl<const SCEV*> &Ops);
|
||||||
SCEVHandle getAddExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) {
|
const SCEV* getAddExpr(const SCEV* LHS, const SCEV* RHS) {
|
||||||
SmallVector<SCEVHandle, 2> Ops;
|
SmallVector<const SCEV*, 2> Ops;
|
||||||
Ops.push_back(LHS);
|
Ops.push_back(LHS);
|
||||||
Ops.push_back(RHS);
|
Ops.push_back(RHS);
|
||||||
return getAddExpr(Ops);
|
return getAddExpr(Ops);
|
||||||
}
|
}
|
||||||
SCEVHandle getAddExpr(const SCEVHandle &Op0, const SCEVHandle &Op1,
|
const SCEV* getAddExpr(const SCEV* Op0, const SCEV* Op1,
|
||||||
const SCEVHandle &Op2) {
|
const SCEV* Op2) {
|
||||||
SmallVector<SCEVHandle, 3> Ops;
|
SmallVector<const SCEV*, 3> Ops;
|
||||||
Ops.push_back(Op0);
|
Ops.push_back(Op0);
|
||||||
Ops.push_back(Op1);
|
Ops.push_back(Op1);
|
||||||
Ops.push_back(Op2);
|
Ops.push_back(Op2);
|
||||||
return getAddExpr(Ops);
|
return getAddExpr(Ops);
|
||||||
}
|
}
|
||||||
SCEVHandle getMulExpr(SmallVectorImpl<SCEVHandle> &Ops);
|
const SCEV* getMulExpr(SmallVectorImpl<const SCEV*> &Ops);
|
||||||
SCEVHandle getMulExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) {
|
const SCEV* getMulExpr(const SCEV* LHS, const SCEV* RHS) {
|
||||||
SmallVector<SCEVHandle, 2> Ops;
|
SmallVector<const SCEV*, 2> Ops;
|
||||||
Ops.push_back(LHS);
|
Ops.push_back(LHS);
|
||||||
Ops.push_back(RHS);
|
Ops.push_back(RHS);
|
||||||
return getMulExpr(Ops);
|
return getMulExpr(Ops);
|
||||||
}
|
}
|
||||||
SCEVHandle getUDivExpr(const SCEVHandle &LHS, const SCEVHandle &RHS);
|
const SCEV* getUDivExpr(const SCEV* LHS, const SCEV* RHS);
|
||||||
SCEVHandle getAddRecExpr(const SCEVHandle &Start, const SCEVHandle &Step,
|
const SCEV* getAddRecExpr(const SCEV* Start, const SCEV* Step,
|
||||||
const Loop *L);
|
const Loop *L);
|
||||||
SCEVHandle getAddRecExpr(SmallVectorImpl<SCEVHandle> &Operands,
|
const SCEV* getAddRecExpr(SmallVectorImpl<const SCEV*> &Operands,
|
||||||
const Loop *L);
|
const Loop *L);
|
||||||
SCEVHandle getAddRecExpr(const SmallVectorImpl<SCEVHandle> &Operands,
|
const SCEV* getAddRecExpr(const SmallVectorImpl<const SCEV*> &Operands,
|
||||||
const Loop *L) {
|
const Loop *L) {
|
||||||
SmallVector<SCEVHandle, 4> NewOp(Operands.begin(), Operands.end());
|
SmallVector<const SCEV*, 4> NewOp(Operands.begin(), Operands.end());
|
||||||
return getAddRecExpr(NewOp, L);
|
return getAddRecExpr(NewOp, L);
|
||||||
}
|
}
|
||||||
SCEVHandle getSMaxExpr(const SCEVHandle &LHS, const SCEVHandle &RHS);
|
const SCEV* getSMaxExpr(const SCEV* LHS, const SCEV* RHS);
|
||||||
SCEVHandle getSMaxExpr(SmallVectorImpl<SCEVHandle> &Operands);
|
const SCEV* getSMaxExpr(SmallVectorImpl<const SCEV*> &Operands);
|
||||||
SCEVHandle getUMaxExpr(const SCEVHandle &LHS, const SCEVHandle &RHS);
|
const SCEV* getUMaxExpr(const SCEV* LHS, const SCEV* RHS);
|
||||||
SCEVHandle getUMaxExpr(SmallVectorImpl<SCEVHandle> &Operands);
|
const SCEV* getUMaxExpr(SmallVectorImpl<const SCEV*> &Operands);
|
||||||
SCEVHandle getSMinExpr(const SCEVHandle &LHS, const SCEVHandle &RHS);
|
const SCEV* getSMinExpr(const SCEV* LHS, const SCEV* RHS);
|
||||||
SCEVHandle getUMinExpr(const SCEVHandle &LHS, const SCEVHandle &RHS);
|
const SCEV* getUMinExpr(const SCEV* LHS, const SCEV* RHS);
|
||||||
SCEVHandle getUnknown(Value *V);
|
const SCEV* getUnknown(Value *V);
|
||||||
SCEVHandle getCouldNotCompute();
|
const SCEV* getCouldNotCompute();
|
||||||
|
|
||||||
/// getNegativeSCEV - Return the SCEV object corresponding to -V.
|
/// getNegativeSCEV - Return the SCEV object corresponding to -V.
|
||||||
///
|
///
|
||||||
SCEVHandle getNegativeSCEV(const SCEVHandle &V);
|
const SCEV* getNegativeSCEV(const SCEV* V);
|
||||||
|
|
||||||
/// getNotSCEV - Return the SCEV object corresponding to ~V.
|
/// getNotSCEV - Return the SCEV object corresponding to ~V.
|
||||||
///
|
///
|
||||||
SCEVHandle getNotSCEV(const SCEVHandle &V);
|
const SCEV* getNotSCEV(const SCEV* V);
|
||||||
|
|
||||||
/// getMinusSCEV - Return LHS-RHS.
|
/// getMinusSCEV - Return LHS-RHS.
|
||||||
///
|
///
|
||||||
SCEVHandle getMinusSCEV(const SCEVHandle &LHS,
|
const SCEV* getMinusSCEV(const SCEV* LHS,
|
||||||
const SCEVHandle &RHS);
|
const SCEV* RHS);
|
||||||
|
|
||||||
/// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion
|
/// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion
|
||||||
/// of the input value to the specified type. If the type must be
|
/// of the input value to the specified type. If the type must be
|
||||||
/// extended, it is zero extended.
|
/// extended, it is zero extended.
|
||||||
SCEVHandle getTruncateOrZeroExtend(const SCEVHandle &V, const Type *Ty);
|
const SCEV* getTruncateOrZeroExtend(const SCEV* V, const Type *Ty);
|
||||||
|
|
||||||
/// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion
|
/// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion
|
||||||
/// of the input value to the specified type. If the type must be
|
/// of the input value to the specified type. If the type must be
|
||||||
/// extended, it is sign extended.
|
/// extended, it is sign extended.
|
||||||
SCEVHandle getTruncateOrSignExtend(const SCEVHandle &V, const Type *Ty);
|
const SCEV* getTruncateOrSignExtend(const SCEV* V, const Type *Ty);
|
||||||
|
|
||||||
/// getNoopOrZeroExtend - Return a SCEV corresponding to a conversion of
|
/// getNoopOrZeroExtend - Return a SCEV corresponding to a conversion of
|
||||||
/// the input value to the specified type. If the type must be extended,
|
/// the input value to the specified type. If the type must be extended,
|
||||||
/// it is zero extended. The conversion must not be narrowing.
|
/// it is zero extended. The conversion must not be narrowing.
|
||||||
SCEVHandle getNoopOrZeroExtend(const SCEVHandle &V, const Type *Ty);
|
const SCEV* getNoopOrZeroExtend(const SCEV* V, const Type *Ty);
|
||||||
|
|
||||||
/// getNoopOrSignExtend - Return a SCEV corresponding to a conversion of
|
/// getNoopOrSignExtend - Return a SCEV corresponding to a conversion of
|
||||||
/// the input value to the specified type. If the type must be extended,
|
/// the input value to the specified type. If the type must be extended,
|
||||||
/// it is sign extended. The conversion must not be narrowing.
|
/// it is sign extended. The conversion must not be narrowing.
|
||||||
SCEVHandle getNoopOrSignExtend(const SCEVHandle &V, const Type *Ty);
|
const SCEV* getNoopOrSignExtend(const SCEV* V, const Type *Ty);
|
||||||
|
|
||||||
/// getNoopOrAnyExtend - Return a SCEV corresponding to a conversion of
|
/// getNoopOrAnyExtend - Return a SCEV corresponding to a conversion of
|
||||||
/// the input value to the specified type. If the type must be extended,
|
/// the input value to the specified type. If the type must be extended,
|
||||||
/// it is extended with unspecified bits. The conversion must not be
|
/// it is extended with unspecified bits. The conversion must not be
|
||||||
/// narrowing.
|
/// narrowing.
|
||||||
SCEVHandle getNoopOrAnyExtend(const SCEVHandle &V, const Type *Ty);
|
const SCEV* getNoopOrAnyExtend(const SCEV* V, const Type *Ty);
|
||||||
|
|
||||||
/// getTruncateOrNoop - Return a SCEV corresponding to a conversion of the
|
/// getTruncateOrNoop - Return a SCEV corresponding to a conversion of the
|
||||||
/// input value to the specified type. The conversion must not be
|
/// input value to the specified type. The conversion must not be
|
||||||
/// widening.
|
/// widening.
|
||||||
SCEVHandle getTruncateOrNoop(const SCEVHandle &V, const Type *Ty);
|
const SCEV* getTruncateOrNoop(const SCEV* V, const Type *Ty);
|
||||||
|
|
||||||
/// getIntegerSCEV - Given an integer or FP type, create a constant for the
|
/// getIntegerSCEV - Given an integer or FP type, create a constant for the
|
||||||
/// specified signed integer value and return a SCEV for the constant.
|
/// specified signed integer value and return a SCEV for the constant.
|
||||||
SCEVHandle getIntegerSCEV(int Val, const Type *Ty);
|
const SCEV* getIntegerSCEV(int Val, const Type *Ty);
|
||||||
|
|
||||||
/// getUMaxFromMismatchedTypes - Promote the operands to the wider of
|
/// getUMaxFromMismatchedTypes - Promote the operands to the wider of
|
||||||
/// the types using zero-extension, and then perform a umax operation
|
/// the types using zero-extension, and then perform a umax operation
|
||||||
/// with them.
|
/// with them.
|
||||||
SCEVHandle getUMaxFromMismatchedTypes(const SCEVHandle &LHS,
|
const SCEV* getUMaxFromMismatchedTypes(const SCEV* LHS,
|
||||||
const SCEVHandle &RHS);
|
const SCEV* RHS);
|
||||||
|
|
||||||
/// getUMinFromMismatchedTypes - Promote the operands to the wider of
|
/// getUMinFromMismatchedTypes - Promote the operands to the wider of
|
||||||
/// the types using zero-extension, and then perform a umin operation
|
/// the types using zero-extension, and then perform a umin operation
|
||||||
/// with them.
|
/// with them.
|
||||||
SCEVHandle getUMinFromMismatchedTypes(const SCEVHandle &LHS,
|
const SCEV* getUMinFromMismatchedTypes(const SCEV* LHS,
|
||||||
const SCEVHandle &RHS);
|
const SCEV* RHS);
|
||||||
|
|
||||||
/// hasSCEV - Return true if the SCEV for this value has already been
|
/// hasSCEV - Return true if the SCEV for this value has already been
|
||||||
/// computed.
|
/// computed.
|
||||||
|
@ -556,7 +482,7 @@ namespace llvm {
|
||||||
|
|
||||||
/// setSCEV - Insert the specified SCEV into the map of current SCEVs for
|
/// setSCEV - Insert the specified SCEV into the map of current SCEVs for
|
||||||
/// the specified value.
|
/// the specified value.
|
||||||
void setSCEV(Value *V, const SCEVHandle &H);
|
void setSCEV(Value *V, const SCEV* H);
|
||||||
|
|
||||||
/// getSCEVAtScope - Return a SCEV expression handle for the specified value
|
/// getSCEVAtScope - Return a SCEV expression handle for the specified value
|
||||||
/// at the specified scope in the program. The L value specifies a loop
|
/// at the specified scope in the program. The L value specifies a loop
|
||||||
|
@ -568,11 +494,11 @@ namespace llvm {
|
||||||
///
|
///
|
||||||
/// In the case that a relevant loop exit value cannot be computed, the
|
/// In the case that a relevant loop exit value cannot be computed, the
|
||||||
/// original value V is returned.
|
/// original value V is returned.
|
||||||
SCEVHandle getSCEVAtScope(const SCEV *S, const Loop *L);
|
const SCEV* getSCEVAtScope(const SCEV *S, const Loop *L);
|
||||||
|
|
||||||
/// getSCEVAtScope - This is a convenience function which does
|
/// getSCEVAtScope - This is a convenience function which does
|
||||||
/// getSCEVAtScope(getSCEV(V), L).
|
/// getSCEVAtScope(getSCEV(V), L).
|
||||||
SCEVHandle getSCEVAtScope(Value *V, const Loop *L);
|
const SCEV* getSCEVAtScope(Value *V, const Loop *L);
|
||||||
|
|
||||||
/// isLoopGuardedByCond - Test whether entry to the loop is protected by
|
/// isLoopGuardedByCond - Test whether entry to the loop is protected by
|
||||||
/// a conditional between LHS and RHS. This is used to help avoid max
|
/// a conditional between LHS and RHS. This is used to help avoid max
|
||||||
|
@ -591,12 +517,12 @@ namespace llvm {
|
||||||
/// loop-invariant backedge-taken count (see
|
/// loop-invariant backedge-taken count (see
|
||||||
/// hasLoopInvariantBackedgeTakenCount).
|
/// hasLoopInvariantBackedgeTakenCount).
|
||||||
///
|
///
|
||||||
SCEVHandle getBackedgeTakenCount(const Loop *L);
|
const SCEV* getBackedgeTakenCount(const Loop *L);
|
||||||
|
|
||||||
/// getMaxBackedgeTakenCount - Similar to getBackedgeTakenCount, except
|
/// getMaxBackedgeTakenCount - Similar to getBackedgeTakenCount, except
|
||||||
/// return the least SCEV value that is known never to be less than the
|
/// return the least SCEV value that is known never to be less than the
|
||||||
/// actual backedge taken count.
|
/// actual backedge taken count.
|
||||||
SCEVHandle getMaxBackedgeTakenCount(const Loop *L);
|
const SCEV* getMaxBackedgeTakenCount(const Loop *L);
|
||||||
|
|
||||||
/// hasLoopInvariantBackedgeTakenCount - Return true if the specified loop
|
/// hasLoopInvariantBackedgeTakenCount - Return true if the specified loop
|
||||||
/// has an analyzable loop-invariant backedge-taken count.
|
/// has an analyzable loop-invariant backedge-taken count.
|
||||||
|
@ -612,15 +538,15 @@ namespace llvm {
|
||||||
/// guaranteed to end in (at every loop iteration). It is, at the same time,
|
/// guaranteed to end in (at every loop iteration). It is, at the same time,
|
||||||
/// the minimum number of times S is divisible by 2. For example, given {4,+,8}
|
/// the minimum number of times S is divisible by 2. For example, given {4,+,8}
|
||||||
/// it returns 2. If S is guaranteed to be 0, it returns the bitwidth of S.
|
/// it returns 2. If S is guaranteed to be 0, it returns the bitwidth of S.
|
||||||
uint32_t GetMinTrailingZeros(const SCEVHandle &S);
|
uint32_t GetMinTrailingZeros(const SCEV* S);
|
||||||
|
|
||||||
/// GetMinLeadingZeros - Determine the minimum number of zero bits that S is
|
/// GetMinLeadingZeros - Determine the minimum number of zero bits that S is
|
||||||
/// guaranteed to begin with (at every loop iteration).
|
/// guaranteed to begin with (at every loop iteration).
|
||||||
uint32_t GetMinLeadingZeros(const SCEVHandle &S);
|
uint32_t GetMinLeadingZeros(const SCEV* S);
|
||||||
|
|
||||||
/// GetMinSignBits - Determine the minimum number of sign bits that S is
|
/// GetMinSignBits - Determine the minimum number of sign bits that S is
|
||||||
/// guaranteed to begin with.
|
/// guaranteed to begin with.
|
||||||
uint32_t GetMinSignBits(const SCEVHandle &S);
|
uint32_t GetMinSignBits(const SCEV* S);
|
||||||
|
|
||||||
virtual bool runOnFunction(Function &F);
|
virtual bool runOnFunction(Function &F);
|
||||||
virtual void releaseMemory();
|
virtual void releaseMemory();
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace llvm {
|
||||||
/// memory.
|
/// memory.
|
||||||
struct SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
|
struct SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
|
||||||
ScalarEvolution &SE;
|
ScalarEvolution &SE;
|
||||||
std::map<SCEVHandle, AssertingVH<Value> > InsertedExpressions;
|
std::map<const SCEV*, AssertingVH<Value> > InsertedExpressions;
|
||||||
std::set<Value*> InsertedValues;
|
std::set<Value*> InsertedValues;
|
||||||
|
|
||||||
BasicBlock::iterator InsertPt;
|
BasicBlock::iterator InsertPt;
|
||||||
|
@ -77,12 +77,12 @@ namespace llvm {
|
||||||
/// expression into the program. The inserted code is inserted into the
|
/// expression into the program. The inserted code is inserted into the
|
||||||
/// SCEVExpander's current insertion point. If a type is specified, the
|
/// SCEVExpander's current insertion point. If a type is specified, the
|
||||||
/// result will be expanded to have that type, with a cast if necessary.
|
/// result will be expanded to have that type, with a cast if necessary.
|
||||||
Value *expandCodeFor(SCEVHandle SH, const Type *Ty = 0);
|
Value *expandCodeFor(const SCEV* SH, const Type *Ty = 0);
|
||||||
|
|
||||||
/// expandCodeFor - Insert code to directly compute the specified SCEV
|
/// expandCodeFor - Insert code to directly compute the specified SCEV
|
||||||
/// expression into the program. The inserted code is inserted into the
|
/// expression into the program. The inserted code is inserted into the
|
||||||
/// specified block.
|
/// specified block.
|
||||||
Value *expandCodeFor(SCEVHandle SH, const Type *Ty,
|
Value *expandCodeFor(const SCEV* SH, const Type *Ty,
|
||||||
BasicBlock::iterator IP) {
|
BasicBlock::iterator IP) {
|
||||||
setInsertionPoint(IP);
|
setInsertionPoint(IP);
|
||||||
return expandCodeFor(SH, Ty);
|
return expandCodeFor(SH, Ty);
|
||||||
|
@ -105,7 +105,8 @@ namespace llvm {
|
||||||
private:
|
private:
|
||||||
/// expandAddToGEP - Expand a SCEVAddExpr with a pointer type into a GEP
|
/// expandAddToGEP - Expand a SCEVAddExpr with a pointer type into a GEP
|
||||||
/// instead of using ptrtoint+arithmetic+inttoptr.
|
/// instead of using ptrtoint+arithmetic+inttoptr.
|
||||||
Value *expandAddToGEP(const SCEVHandle *op_begin, const SCEVHandle *op_end,
|
Value *expandAddToGEP(const SCEV* const *op_begin,
|
||||||
|
const SCEV* const *op_end,
|
||||||
const PointerType *PTy, const Type *Ty, Value *V);
|
const PointerType *PTy, const Type *Ty, Value *V);
|
||||||
|
|
||||||
Value *expand(const SCEV *S);
|
Value *expand(const SCEV *S);
|
||||||
|
|
|
@ -51,8 +51,8 @@ namespace llvm {
|
||||||
|
|
||||||
virtual const Type *getType() const;
|
virtual const Type *getType() const;
|
||||||
|
|
||||||
SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
|
const SCEV* replaceSymbolicValuesWithConcrete(const SCEV* Sym,
|
||||||
const SCEVHandle &Conc,
|
const SCEV* Conc,
|
||||||
ScalarEvolution &SE) const {
|
ScalarEvolution &SE) const {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -75,15 +75,15 @@ namespace llvm {
|
||||||
///
|
///
|
||||||
class SCEVCastExpr : public SCEV {
|
class SCEVCastExpr : public SCEV {
|
||||||
protected:
|
protected:
|
||||||
SCEVHandle Op;
|
const SCEV* Op;
|
||||||
const Type *Ty;
|
const Type *Ty;
|
||||||
|
|
||||||
SCEVCastExpr(unsigned SCEVTy, const SCEVHandle &op, const Type *ty,
|
SCEVCastExpr(unsigned SCEVTy, const SCEV* op, const Type *ty,
|
||||||
const ScalarEvolution* p);
|
const ScalarEvolution* p);
|
||||||
virtual ~SCEVCastExpr();
|
virtual ~SCEVCastExpr();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const SCEVHandle &getOperand() const { return Op; }
|
const SCEV* getOperand() const { return Op; }
|
||||||
virtual const Type *getType() const { return Ty; }
|
virtual const Type *getType() const { return Ty; }
|
||||||
|
|
||||||
virtual bool isLoopInvariant(const Loop *L) const {
|
virtual bool isLoopInvariant(const Loop *L) const {
|
||||||
|
@ -112,14 +112,14 @@ namespace llvm {
|
||||||
class SCEVTruncateExpr : public SCEVCastExpr {
|
class SCEVTruncateExpr : public SCEVCastExpr {
|
||||||
friend class ScalarEvolution;
|
friend class ScalarEvolution;
|
||||||
|
|
||||||
SCEVTruncateExpr(const SCEVHandle &op, const Type *ty,
|
SCEVTruncateExpr(const SCEV* op, const Type *ty,
|
||||||
const ScalarEvolution* p);
|
const ScalarEvolution* p);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
|
const SCEV* replaceSymbolicValuesWithConcrete(const SCEV* Sym,
|
||||||
const SCEVHandle &Conc,
|
const SCEV* Conc,
|
||||||
ScalarEvolution &SE) const {
|
ScalarEvolution &SE) const {
|
||||||
SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
|
const SCEV* H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
|
||||||
if (H == Op)
|
if (H == Op)
|
||||||
return this;
|
return this;
|
||||||
return SE.getTruncateExpr(H, Ty);
|
return SE.getTruncateExpr(H, Ty);
|
||||||
|
@ -141,14 +141,14 @@ namespace llvm {
|
||||||
class SCEVZeroExtendExpr : public SCEVCastExpr {
|
class SCEVZeroExtendExpr : public SCEVCastExpr {
|
||||||
friend class ScalarEvolution;
|
friend class ScalarEvolution;
|
||||||
|
|
||||||
SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty,
|
SCEVZeroExtendExpr(const SCEV* op, const Type *ty,
|
||||||
const ScalarEvolution* p);
|
const ScalarEvolution* p);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
|
const SCEV* replaceSymbolicValuesWithConcrete(const SCEV* Sym,
|
||||||
const SCEVHandle &Conc,
|
const SCEV* Conc,
|
||||||
ScalarEvolution &SE) const {
|
ScalarEvolution &SE) const {
|
||||||
SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
|
const SCEV* H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
|
||||||
if (H == Op)
|
if (H == Op)
|
||||||
return this;
|
return this;
|
||||||
return SE.getZeroExtendExpr(H, Ty);
|
return SE.getZeroExtendExpr(H, Ty);
|
||||||
|
@ -170,14 +170,14 @@ namespace llvm {
|
||||||
class SCEVSignExtendExpr : public SCEVCastExpr {
|
class SCEVSignExtendExpr : public SCEVCastExpr {
|
||||||
friend class ScalarEvolution;
|
friend class ScalarEvolution;
|
||||||
|
|
||||||
SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty,
|
SCEVSignExtendExpr(const SCEV* op, const Type *ty,
|
||||||
const ScalarEvolution* p);
|
const ScalarEvolution* p);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
|
const SCEV* replaceSymbolicValuesWithConcrete(const SCEV* Sym,
|
||||||
const SCEVHandle &Conc,
|
const SCEV* Conc,
|
||||||
ScalarEvolution &SE) const {
|
ScalarEvolution &SE) const {
|
||||||
SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
|
const SCEV* H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
|
||||||
if (H == Op)
|
if (H == Op)
|
||||||
return this;
|
return this;
|
||||||
return SE.getSignExtendExpr(H, Ty);
|
return SE.getSignExtendExpr(H, Ty);
|
||||||
|
@ -199,22 +199,22 @@ namespace llvm {
|
||||||
///
|
///
|
||||||
class SCEVNAryExpr : public SCEV {
|
class SCEVNAryExpr : public SCEV {
|
||||||
protected:
|
protected:
|
||||||
SmallVector<SCEVHandle, 8> Operands;
|
SmallVector<const SCEV*, 8> Operands;
|
||||||
|
|
||||||
SCEVNAryExpr(enum SCEVTypes T, const SmallVectorImpl<SCEVHandle> &ops,
|
SCEVNAryExpr(enum SCEVTypes T, const SmallVectorImpl<const SCEV*> &ops,
|
||||||
const ScalarEvolution* p)
|
const ScalarEvolution* p)
|
||||||
: SCEV(T, p), Operands(ops.begin(), ops.end()) {}
|
: SCEV(T, p), Operands(ops.begin(), ops.end()) {}
|
||||||
virtual ~SCEVNAryExpr() {}
|
virtual ~SCEVNAryExpr() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned getNumOperands() const { return (unsigned)Operands.size(); }
|
unsigned getNumOperands() const { return (unsigned)Operands.size(); }
|
||||||
const SCEVHandle &getOperand(unsigned i) const {
|
const SCEV* getOperand(unsigned i) const {
|
||||||
assert(i < Operands.size() && "Operand index out of range!");
|
assert(i < Operands.size() && "Operand index out of range!");
|
||||||
return Operands[i];
|
return Operands[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
const SmallVectorImpl<SCEVHandle> &getOperands() const { return Operands; }
|
const SmallVectorImpl<const SCEV*> &getOperands() const { return Operands; }
|
||||||
typedef SmallVectorImpl<SCEVHandle>::const_iterator op_iterator;
|
typedef SmallVectorImpl<const SCEV*>::const_iterator op_iterator;
|
||||||
op_iterator op_begin() const { return Operands.begin(); }
|
op_iterator op_begin() const { return Operands.begin(); }
|
||||||
op_iterator op_end() const { return Operands.end(); }
|
op_iterator op_end() const { return Operands.end(); }
|
||||||
|
|
||||||
|
@ -261,13 +261,13 @@ namespace llvm {
|
||||||
class SCEVCommutativeExpr : public SCEVNAryExpr {
|
class SCEVCommutativeExpr : public SCEVNAryExpr {
|
||||||
protected:
|
protected:
|
||||||
SCEVCommutativeExpr(enum SCEVTypes T,
|
SCEVCommutativeExpr(enum SCEVTypes T,
|
||||||
const SmallVectorImpl<SCEVHandle> &ops,
|
const SmallVectorImpl<const SCEV*> &ops,
|
||||||
const ScalarEvolution* p)
|
const ScalarEvolution* p)
|
||||||
: SCEVNAryExpr(T, ops, p) {}
|
: SCEVNAryExpr(T, ops, p) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
|
const SCEV* replaceSymbolicValuesWithConcrete(const SCEV* Sym,
|
||||||
const SCEVHandle &Conc,
|
const SCEV* Conc,
|
||||||
ScalarEvolution &SE) const;
|
ScalarEvolution &SE) const;
|
||||||
|
|
||||||
virtual const char *getOperationStr() const = 0;
|
virtual const char *getOperationStr() const = 0;
|
||||||
|
@ -291,7 +291,7 @@ namespace llvm {
|
||||||
class SCEVAddExpr : public SCEVCommutativeExpr {
|
class SCEVAddExpr : public SCEVCommutativeExpr {
|
||||||
friend class ScalarEvolution;
|
friend class ScalarEvolution;
|
||||||
|
|
||||||
explicit SCEVAddExpr(const SmallVectorImpl<SCEVHandle> &ops,
|
explicit SCEVAddExpr(const SmallVectorImpl<const SCEV*> &ops,
|
||||||
const ScalarEvolution* p)
|
const ScalarEvolution* p)
|
||||||
: SCEVCommutativeExpr(scAddExpr, ops, p) {
|
: SCEVCommutativeExpr(scAddExpr, ops, p) {
|
||||||
}
|
}
|
||||||
|
@ -312,7 +312,7 @@ namespace llvm {
|
||||||
class SCEVMulExpr : public SCEVCommutativeExpr {
|
class SCEVMulExpr : public SCEVCommutativeExpr {
|
||||||
friend class ScalarEvolution;
|
friend class ScalarEvolution;
|
||||||
|
|
||||||
explicit SCEVMulExpr(const SmallVectorImpl<SCEVHandle> &ops,
|
explicit SCEVMulExpr(const SmallVectorImpl<const SCEV*> &ops,
|
||||||
const ScalarEvolution* p)
|
const ScalarEvolution* p)
|
||||||
: SCEVCommutativeExpr(scMulExpr, ops, p) {
|
: SCEVCommutativeExpr(scMulExpr, ops, p) {
|
||||||
}
|
}
|
||||||
|
@ -334,14 +334,15 @@ namespace llvm {
|
||||||
class SCEVUDivExpr : public SCEV {
|
class SCEVUDivExpr : public SCEV {
|
||||||
friend class ScalarEvolution;
|
friend class ScalarEvolution;
|
||||||
|
|
||||||
SCEVHandle LHS, RHS;
|
const SCEV* LHS;
|
||||||
SCEVUDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs,
|
const SCEV* RHS;
|
||||||
|
SCEVUDivExpr(const SCEV* lhs, const SCEV* rhs,
|
||||||
const ScalarEvolution* p)
|
const ScalarEvolution* p)
|
||||||
: SCEV(scUDivExpr, p), LHS(lhs), RHS(rhs) {}
|
: SCEV(scUDivExpr, p), LHS(lhs), RHS(rhs) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const SCEVHandle &getLHS() const { return LHS; }
|
const SCEV* getLHS() const { return LHS; }
|
||||||
const SCEVHandle &getRHS() const { return RHS; }
|
const SCEV* getRHS() const { return RHS; }
|
||||||
|
|
||||||
virtual bool isLoopInvariant(const Loop *L) const {
|
virtual bool isLoopInvariant(const Loop *L) const {
|
||||||
return LHS->isLoopInvariant(L) && RHS->isLoopInvariant(L);
|
return LHS->isLoopInvariant(L) && RHS->isLoopInvariant(L);
|
||||||
|
@ -352,11 +353,11 @@ namespace llvm {
|
||||||
RHS->hasComputableLoopEvolution(L);
|
RHS->hasComputableLoopEvolution(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
|
const SCEV* replaceSymbolicValuesWithConcrete(const SCEV* Sym,
|
||||||
const SCEVHandle &Conc,
|
const SCEV* Conc,
|
||||||
ScalarEvolution &SE) const {
|
ScalarEvolution &SE) const {
|
||||||
SCEVHandle L = LHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
|
const SCEV* L = LHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
|
||||||
SCEVHandle R = RHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
|
const SCEV* R = RHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE);
|
||||||
if (L == LHS && R == RHS)
|
if (L == LHS && R == RHS)
|
||||||
return this;
|
return this;
|
||||||
else
|
else
|
||||||
|
@ -391,7 +392,7 @@ namespace llvm {
|
||||||
|
|
||||||
const Loop *L;
|
const Loop *L;
|
||||||
|
|
||||||
SCEVAddRecExpr(const SmallVectorImpl<SCEVHandle> &ops, const Loop *l,
|
SCEVAddRecExpr(const SmallVectorImpl<const SCEV*> &ops, const Loop *l,
|
||||||
const ScalarEvolution* p)
|
const ScalarEvolution* p)
|
||||||
: SCEVNAryExpr(scAddRecExpr, ops, p), L(l) {
|
: SCEVNAryExpr(scAddRecExpr, ops, p), L(l) {
|
||||||
for (size_t i = 0, e = Operands.size(); i != e; ++i)
|
for (size_t i = 0, e = Operands.size(); i != e; ++i)
|
||||||
|
@ -400,15 +401,15 @@ namespace llvm {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const SCEVHandle &getStart() const { return Operands[0]; }
|
const SCEV* getStart() const { return Operands[0]; }
|
||||||
const Loop *getLoop() const { return L; }
|
const Loop *getLoop() const { return L; }
|
||||||
|
|
||||||
/// getStepRecurrence - This method constructs and returns the recurrence
|
/// getStepRecurrence - This method constructs and returns the recurrence
|
||||||
/// indicating how much this expression steps by. If this is a polynomial
|
/// indicating how much this expression steps by. If this is a polynomial
|
||||||
/// of degree N, it returns a chrec of degree N-1.
|
/// of degree N, it returns a chrec of degree N-1.
|
||||||
SCEVHandle getStepRecurrence(ScalarEvolution &SE) const {
|
const SCEV* getStepRecurrence(ScalarEvolution &SE) const {
|
||||||
if (isAffine()) return getOperand(1);
|
if (isAffine()) return getOperand(1);
|
||||||
return SE.getAddRecExpr(SmallVector<SCEVHandle, 3>(op_begin()+1,op_end()),
|
return SE.getAddRecExpr(SmallVector<const SCEV*, 3>(op_begin()+1,op_end()),
|
||||||
getLoop());
|
getLoop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,7 +437,7 @@ namespace llvm {
|
||||||
|
|
||||||
/// evaluateAtIteration - Return the value of this chain of recurrences at
|
/// evaluateAtIteration - Return the value of this chain of recurrences at
|
||||||
/// the specified iteration number.
|
/// the specified iteration number.
|
||||||
SCEVHandle evaluateAtIteration(SCEVHandle It, ScalarEvolution &SE) const;
|
const SCEV* evaluateAtIteration(const SCEV* It, ScalarEvolution &SE) const;
|
||||||
|
|
||||||
/// getNumIterationsInRange - Return the number of iterations of this loop
|
/// getNumIterationsInRange - Return the number of iterations of this loop
|
||||||
/// that produce values in the specified constant range. Another way of
|
/// that produce values in the specified constant range. Another way of
|
||||||
|
@ -444,11 +445,11 @@ namespace llvm {
|
||||||
/// value is not in the condition, thus computing the exit count. If the
|
/// value is not in the condition, thus computing the exit count. If the
|
||||||
/// iteration count can't be computed, an instance of SCEVCouldNotCompute is
|
/// iteration count can't be computed, an instance of SCEVCouldNotCompute is
|
||||||
/// returned.
|
/// returned.
|
||||||
SCEVHandle getNumIterationsInRange(ConstantRange Range,
|
const SCEV* getNumIterationsInRange(ConstantRange Range,
|
||||||
ScalarEvolution &SE) const;
|
ScalarEvolution &SE) const;
|
||||||
|
|
||||||
SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
|
const SCEV* replaceSymbolicValuesWithConcrete(const SCEV* Sym,
|
||||||
const SCEVHandle &Conc,
|
const SCEV* Conc,
|
||||||
ScalarEvolution &SE) const;
|
ScalarEvolution &SE) const;
|
||||||
|
|
||||||
virtual void print(raw_ostream &OS) const;
|
virtual void print(raw_ostream &OS) const;
|
||||||
|
@ -467,7 +468,7 @@ namespace llvm {
|
||||||
class SCEVSMaxExpr : public SCEVCommutativeExpr {
|
class SCEVSMaxExpr : public SCEVCommutativeExpr {
|
||||||
friend class ScalarEvolution;
|
friend class ScalarEvolution;
|
||||||
|
|
||||||
explicit SCEVSMaxExpr(const SmallVectorImpl<SCEVHandle> &ops,
|
explicit SCEVSMaxExpr(const SmallVectorImpl<const SCEV*> &ops,
|
||||||
const ScalarEvolution* p)
|
const ScalarEvolution* p)
|
||||||
: SCEVCommutativeExpr(scSMaxExpr, ops, p) {
|
: SCEVCommutativeExpr(scSMaxExpr, ops, p) {
|
||||||
}
|
}
|
||||||
|
@ -489,7 +490,7 @@ namespace llvm {
|
||||||
class SCEVUMaxExpr : public SCEVCommutativeExpr {
|
class SCEVUMaxExpr : public SCEVCommutativeExpr {
|
||||||
friend class ScalarEvolution;
|
friend class ScalarEvolution;
|
||||||
|
|
||||||
explicit SCEVUMaxExpr(const SmallVectorImpl<SCEVHandle> &ops,
|
explicit SCEVUMaxExpr(const SmallVectorImpl<const SCEV*> &ops,
|
||||||
const ScalarEvolution* p)
|
const ScalarEvolution* p)
|
||||||
: SCEVCommutativeExpr(scUMaxExpr, ops, p) {
|
: SCEVCommutativeExpr(scUMaxExpr, ops, p) {
|
||||||
}
|
}
|
||||||
|
@ -525,8 +526,8 @@ namespace llvm {
|
||||||
return false; // not computable
|
return false; // not computable
|
||||||
}
|
}
|
||||||
|
|
||||||
SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
|
const SCEV* replaceSymbolicValuesWithConcrete(const SCEV* Sym,
|
||||||
const SCEVHandle &Conc,
|
const SCEV* Conc,
|
||||||
ScalarEvolution &SE) const {
|
ScalarEvolution &SE) const {
|
||||||
if (&*Sym == this) return Conc;
|
if (&*Sym == this) return Conc;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -39,7 +39,7 @@ Pass *llvm::createIVUsersPass() {
|
||||||
/// containsAddRecFromDifferentLoop - Determine whether expression S involves a
|
/// containsAddRecFromDifferentLoop - Determine whether expression S involves a
|
||||||
/// subexpression that is an AddRec from a loop other than L. An outer loop
|
/// subexpression that is an AddRec from a loop other than L. An outer loop
|
||||||
/// of L is OK, but not an inner loop nor a disjoint loop.
|
/// of L is OK, but not an inner loop nor a disjoint loop.
|
||||||
static bool containsAddRecFromDifferentLoop(SCEVHandle S, Loop *L) {
|
static bool containsAddRecFromDifferentLoop(const SCEV* S, Loop *L) {
|
||||||
// This is very common, put it first.
|
// This is very common, put it first.
|
||||||
if (isa<SCEVConstant>(S))
|
if (isa<SCEVConstant>(S))
|
||||||
return false;
|
return false;
|
||||||
|
@ -80,10 +80,10 @@ static bool containsAddRecFromDifferentLoop(SCEVHandle S, Loop *L) {
|
||||||
/// a mix of loop invariant and loop variant expressions. The start cannot,
|
/// a mix of loop invariant and loop variant expressions. The start cannot,
|
||||||
/// however, contain an AddRec from a different loop, unless that loop is an
|
/// however, contain an AddRec from a different loop, unless that loop is an
|
||||||
/// outer loop of the current loop.
|
/// outer loop of the current loop.
|
||||||
static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, Loop *UseLoop,
|
static bool getSCEVStartAndStride(const SCEV* &SH, Loop *L, Loop *UseLoop,
|
||||||
SCEVHandle &Start, SCEVHandle &Stride,
|
const SCEV* &Start, const SCEV* &Stride,
|
||||||
ScalarEvolution *SE, DominatorTree *DT) {
|
ScalarEvolution *SE, DominatorTree *DT) {
|
||||||
SCEVHandle TheAddRec = Start; // Initialize to zero.
|
const SCEV* TheAddRec = Start; // Initialize to zero.
|
||||||
|
|
||||||
// If the outer level is an AddExpr, the operands are all start values except
|
// If the outer level is an AddExpr, the operands are all start values except
|
||||||
// for a nested AddRecExpr.
|
// for a nested AddRecExpr.
|
||||||
|
@ -109,9 +109,9 @@ static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, Loop *UseLoop,
|
||||||
|
|
||||||
// Use getSCEVAtScope to attempt to simplify other loops out of
|
// Use getSCEVAtScope to attempt to simplify other loops out of
|
||||||
// the picture.
|
// the picture.
|
||||||
SCEVHandle AddRecStart = AddRec->getStart();
|
const SCEV* AddRecStart = AddRec->getStart();
|
||||||
AddRecStart = SE->getSCEVAtScope(AddRecStart, UseLoop);
|
AddRecStart = SE->getSCEVAtScope(AddRecStart, UseLoop);
|
||||||
SCEVHandle AddRecStride = AddRec->getStepRecurrence(*SE);
|
const SCEV* AddRecStride = AddRec->getStepRecurrence(*SE);
|
||||||
|
|
||||||
// FIXME: If Start contains an SCEVAddRecExpr from a different loop, other
|
// FIXME: If Start contains an SCEVAddRecExpr from a different loop, other
|
||||||
// than an outer loop of the current loop, reject it. LSR has no concept of
|
// than an outer loop of the current loop, reject it. LSR has no concept of
|
||||||
|
@ -196,13 +196,13 @@ bool IVUsers::AddUsersIfInteresting(Instruction *I) {
|
||||||
return true; // Instruction already handled.
|
return true; // Instruction already handled.
|
||||||
|
|
||||||
// Get the symbolic expression for this instruction.
|
// Get the symbolic expression for this instruction.
|
||||||
SCEVHandle ISE = SE->getSCEV(I);
|
const SCEV* ISE = SE->getSCEV(I);
|
||||||
if (isa<SCEVCouldNotCompute>(ISE)) return false;
|
if (isa<SCEVCouldNotCompute>(ISE)) return false;
|
||||||
|
|
||||||
// Get the start and stride for this expression.
|
// Get the start and stride for this expression.
|
||||||
Loop *UseLoop = LI->getLoopFor(I->getParent());
|
Loop *UseLoop = LI->getLoopFor(I->getParent());
|
||||||
SCEVHandle Start = SE->getIntegerSCEV(0, ISE->getType());
|
const SCEV* Start = SE->getIntegerSCEV(0, ISE->getType());
|
||||||
SCEVHandle Stride = Start;
|
const SCEV* Stride = Start;
|
||||||
|
|
||||||
if (!getSCEVStartAndStride(ISE, L, UseLoop, Start, Stride, SE, DT))
|
if (!getSCEVStartAndStride(ISE, L, UseLoop, Start, Stride, SE, DT))
|
||||||
return false; // Non-reducible symbolic expression, bail out.
|
return false; // Non-reducible symbolic expression, bail out.
|
||||||
|
@ -254,7 +254,7 @@ bool IVUsers::AddUsersIfInteresting(Instruction *I) {
|
||||||
if (IVUseShouldUsePostIncValue(User, I, L, LI, DT, this)) {
|
if (IVUseShouldUsePostIncValue(User, I, L, LI, DT, this)) {
|
||||||
// The value used will be incremented by the stride more than we are
|
// The value used will be incremented by the stride more than we are
|
||||||
// expecting, so subtract this off.
|
// expecting, so subtract this off.
|
||||||
SCEVHandle NewStart = SE->getMinusSCEV(Start, Stride);
|
const SCEV* NewStart = SE->getMinusSCEV(Start, Stride);
|
||||||
StrideUses->addUser(NewStart, User, I);
|
StrideUses->addUser(NewStart, User, I);
|
||||||
StrideUses->Users.back().setIsUseOfPostIncrementedValue(true);
|
StrideUses->Users.back().setIsUseOfPostIncrementedValue(true);
|
||||||
DOUT << " USING POSTINC SCEV, START=" << *NewStart<< "\n";
|
DOUT << " USING POSTINC SCEV, START=" << *NewStart<< "\n";
|
||||||
|
@ -295,9 +295,9 @@ bool IVUsers::runOnLoop(Loop *l, LPPassManager &LPM) {
|
||||||
|
|
||||||
/// getReplacementExpr - Return a SCEV expression which computes the
|
/// getReplacementExpr - Return a SCEV expression which computes the
|
||||||
/// value of the OperandValToReplace of the given IVStrideUse.
|
/// value of the OperandValToReplace of the given IVStrideUse.
|
||||||
SCEVHandle IVUsers::getReplacementExpr(const IVStrideUse &U) const {
|
const SCEV* IVUsers::getReplacementExpr(const IVStrideUse &U) const {
|
||||||
// Start with zero.
|
// Start with zero.
|
||||||
SCEVHandle RetVal = SE->getIntegerSCEV(0, U.getParent()->Stride->getType());
|
const SCEV* RetVal = SE->getIntegerSCEV(0, U.getParent()->Stride->getType());
|
||||||
// Create the basic add recurrence.
|
// Create the basic add recurrence.
|
||||||
RetVal = SE->getAddRecExpr(RetVal, U.getParent()->Stride, L);
|
RetVal = SE->getAddRecExpr(RetVal, U.getParent()->Stride, L);
|
||||||
// Add the offset in a separate step, because it may be loop-variant.
|
// Add the offset in a separate step, because it may be loop-variant.
|
||||||
|
@ -308,7 +308,7 @@ SCEVHandle IVUsers::getReplacementExpr(const IVStrideUse &U) const {
|
||||||
RetVal = SE->getAddExpr(RetVal, U.getParent()->Stride);
|
RetVal = SE->getAddExpr(RetVal, U.getParent()->Stride);
|
||||||
// Evaluate the expression out of the loop, if possible.
|
// Evaluate the expression out of the loop, if possible.
|
||||||
if (!L->contains(U.getUser()->getParent())) {
|
if (!L->contains(U.getUser()->getParent())) {
|
||||||
SCEVHandle ExitVal = SE->getSCEVAtScope(RetVal, L->getParentLoop());
|
const SCEV* ExitVal = SE->getSCEVAtScope(RetVal, L->getParentLoop());
|
||||||
if (ExitVal->isLoopInvariant(L))
|
if (ExitVal->isLoopInvariant(L))
|
||||||
RetVal = ExitVal;
|
RetVal = ExitVal;
|
||||||
}
|
}
|
||||||
|
@ -325,7 +325,7 @@ void IVUsers::print(raw_ostream &OS, const Module *M) const {
|
||||||
OS << ":\n";
|
OS << ":\n";
|
||||||
|
|
||||||
for (unsigned Stride = 0, e = StrideOrder.size(); Stride != e; ++Stride) {
|
for (unsigned Stride = 0, e = StrideOrder.size(); Stride != e; ++Stride) {
|
||||||
std::map<SCEVHandle, IVUsersOfOneStride*>::const_iterator SI =
|
std::map<const SCEV*, IVUsersOfOneStride*>::const_iterator SI =
|
||||||
IVUsesByStride.find(StrideOrder[Stride]);
|
IVUsesByStride.find(StrideOrder[Stride]);
|
||||||
assert(SI != IVUsesByStride.end() && "Stride doesn't exist!");
|
assert(SI != IVUsesByStride.end() && "Stride doesn't exist!");
|
||||||
OS << " Stride " << *SI->first->getType() << " " << *SI->first << ":\n";
|
OS << " Stride " << *SI->first->getType() << " " << *SI->first << ":\n";
|
||||||
|
|
|
@ -26,8 +26,8 @@ char LoopVR::ID = 0;
|
||||||
static RegisterPass<LoopVR> X("loopvr", "Loop Value Ranges", false, true);
|
static RegisterPass<LoopVR> X("loopvr", "Loop Value Ranges", false, true);
|
||||||
|
|
||||||
/// getRange - determine the range for a particular SCEV within a given Loop
|
/// getRange - determine the range for a particular SCEV within a given Loop
|
||||||
ConstantRange LoopVR::getRange(SCEVHandle S, Loop *L, ScalarEvolution &SE) {
|
ConstantRange LoopVR::getRange(const SCEV* S, Loop *L, ScalarEvolution &SE) {
|
||||||
SCEVHandle T = SE.getBackedgeTakenCount(L);
|
const SCEV* T = SE.getBackedgeTakenCount(L);
|
||||||
if (isa<SCEVCouldNotCompute>(T))
|
if (isa<SCEVCouldNotCompute>(T))
|
||||||
return ConstantRange(cast<IntegerType>(S->getType())->getBitWidth(), true);
|
return ConstantRange(cast<IntegerType>(S->getType())->getBitWidth(), true);
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ ConstantRange LoopVR::getRange(SCEVHandle S, Loop *L, ScalarEvolution &SE) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getRange - determine the range for a particular SCEV with a given trip count
|
/// getRange - determine the range for a particular SCEV with a given trip count
|
||||||
ConstantRange LoopVR::getRange(SCEVHandle S, SCEVHandle T, ScalarEvolution &SE){
|
ConstantRange LoopVR::getRange(const SCEV* S, const SCEV* T, ScalarEvolution &SE){
|
||||||
|
|
||||||
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(S))
|
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(S))
|
||||||
return ConstantRange(C->getValue()->getValue());
|
return ConstantRange(C->getValue()->getValue());
|
||||||
|
@ -182,8 +182,8 @@ ConstantRange LoopVR::getRange(SCEVHandle S, SCEVHandle T, ScalarEvolution &SE){
|
||||||
if (!Trip) return FullSet;
|
if (!Trip) return FullSet;
|
||||||
|
|
||||||
if (AddRec->isAffine()) {
|
if (AddRec->isAffine()) {
|
||||||
SCEVHandle StartHandle = AddRec->getStart();
|
const SCEV* StartHandle = AddRec->getStart();
|
||||||
SCEVHandle StepHandle = AddRec->getOperand(1);
|
const SCEV* StepHandle = AddRec->getOperand(1);
|
||||||
|
|
||||||
const SCEVConstant *Step = dyn_cast<SCEVConstant>(StepHandle);
|
const SCEVConstant *Step = dyn_cast<SCEVConstant>(StepHandle);
|
||||||
if (!Step) return FullSet;
|
if (!Step) return FullSet;
|
||||||
|
@ -194,7 +194,7 @@ ConstantRange LoopVR::getRange(SCEVHandle S, SCEVHandle T, ScalarEvolution &SE){
|
||||||
if ((TripExt * StepExt).ugt(APInt::getLowBitsSet(ExWidth, ExWidth >> 1)))
|
if ((TripExt * StepExt).ugt(APInt::getLowBitsSet(ExWidth, ExWidth >> 1)))
|
||||||
return FullSet;
|
return FullSet;
|
||||||
|
|
||||||
SCEVHandle EndHandle = SE.getAddExpr(StartHandle,
|
const SCEV* EndHandle = SE.getAddExpr(StartHandle,
|
||||||
SE.getMulExpr(T, StepHandle));
|
SE.getMulExpr(T, StepHandle));
|
||||||
const SCEVConstant *Start = dyn_cast<SCEVConstant>(StartHandle);
|
const SCEVConstant *Start = dyn_cast<SCEVConstant>(StartHandle);
|
||||||
const SCEVConstant *End = dyn_cast<SCEVConstant>(EndHandle);
|
const SCEVConstant *End = dyn_cast<SCEVConstant>(EndHandle);
|
||||||
|
@ -254,7 +254,7 @@ ConstantRange LoopVR::compute(Value *V) {
|
||||||
|
|
||||||
ScalarEvolution &SE = getAnalysis<ScalarEvolution>();
|
ScalarEvolution &SE = getAnalysis<ScalarEvolution>();
|
||||||
|
|
||||||
SCEVHandle S = SE.getSCEV(I);
|
const SCEV* S = SE.getSCEV(I);
|
||||||
if (isa<SCEVUnknown>(S) || isa<SCEVCouldNotCompute>(S))
|
if (isa<SCEVUnknown>(S) || isa<SCEVCouldNotCompute>(S))
|
||||||
return ConstantRange(cast<IntegerType>(V->getType())->getBitWidth(), false);
|
return ConstantRange(cast<IntegerType>(V->getType())->getBitWidth(), false);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -152,8 +152,8 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, Value *LHS,
|
||||||
/// TODO: When ScalarEvolution gets a SCEVSDivExpr, this can be made
|
/// TODO: When ScalarEvolution gets a SCEVSDivExpr, this can be made
|
||||||
/// unnecessary; in its place, just signed-divide Ops[i] by the scale and
|
/// unnecessary; in its place, just signed-divide Ops[i] by the scale and
|
||||||
/// check to see if the divide was folded.
|
/// check to see if the divide was folded.
|
||||||
static bool FactorOutConstant(SCEVHandle &S,
|
static bool FactorOutConstant(const SCEV* &S,
|
||||||
SCEVHandle &Remainder,
|
const SCEV* &Remainder,
|
||||||
const APInt &Factor,
|
const APInt &Factor,
|
||||||
ScalarEvolution &SE) {
|
ScalarEvolution &SE) {
|
||||||
// Everything is divisible by one.
|
// Everything is divisible by one.
|
||||||
|
@ -168,7 +168,7 @@ static bool FactorOutConstant(SCEVHandle &S,
|
||||||
// the value at this scale. It will be considered for subsequent
|
// the value at this scale. It will be considered for subsequent
|
||||||
// smaller scales.
|
// smaller scales.
|
||||||
if (C->isZero() || !CI->isZero()) {
|
if (C->isZero() || !CI->isZero()) {
|
||||||
SCEVHandle Div = SE.getConstant(CI);
|
const SCEV* Div = SE.getConstant(CI);
|
||||||
S = Div;
|
S = Div;
|
||||||
Remainder =
|
Remainder =
|
||||||
SE.getAddExpr(Remainder,
|
SE.getAddExpr(Remainder,
|
||||||
|
@ -182,8 +182,8 @@ static bool FactorOutConstant(SCEVHandle &S,
|
||||||
if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(S))
|
if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(S))
|
||||||
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(M->getOperand(0)))
|
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(M->getOperand(0)))
|
||||||
if (!C->getValue()->getValue().srem(Factor)) {
|
if (!C->getValue()->getValue().srem(Factor)) {
|
||||||
const SmallVectorImpl<SCEVHandle> &MOperands = M->getOperands();
|
const SmallVectorImpl<const SCEV*> &MOperands = M->getOperands();
|
||||||
SmallVector<SCEVHandle, 4> NewMulOps(MOperands.begin(), MOperands.end());
|
SmallVector<const SCEV*, 4> NewMulOps(MOperands.begin(), MOperands.end());
|
||||||
NewMulOps[0] =
|
NewMulOps[0] =
|
||||||
SE.getConstant(C->getValue()->getValue().sdiv(Factor));
|
SE.getConstant(C->getValue()->getValue().sdiv(Factor));
|
||||||
S = SE.getMulExpr(NewMulOps);
|
S = SE.getMulExpr(NewMulOps);
|
||||||
|
@ -192,13 +192,13 @@ static bool FactorOutConstant(SCEVHandle &S,
|
||||||
|
|
||||||
// In an AddRec, check if both start and step are divisible.
|
// In an AddRec, check if both start and step are divisible.
|
||||||
if (const SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(S)) {
|
if (const SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(S)) {
|
||||||
SCEVHandle Step = A->getStepRecurrence(SE);
|
const SCEV* Step = A->getStepRecurrence(SE);
|
||||||
SCEVHandle StepRem = SE.getIntegerSCEV(0, Step->getType());
|
const SCEV* StepRem = SE.getIntegerSCEV(0, Step->getType());
|
||||||
if (!FactorOutConstant(Step, StepRem, Factor, SE))
|
if (!FactorOutConstant(Step, StepRem, Factor, SE))
|
||||||
return false;
|
return false;
|
||||||
if (!StepRem->isZero())
|
if (!StepRem->isZero())
|
||||||
return false;
|
return false;
|
||||||
SCEVHandle Start = A->getStart();
|
const SCEV* Start = A->getStart();
|
||||||
if (!FactorOutConstant(Start, Remainder, Factor, SE))
|
if (!FactorOutConstant(Start, Remainder, Factor, SE))
|
||||||
return false;
|
return false;
|
||||||
S = SE.getAddRecExpr(Start, Step, A->getLoop());
|
S = SE.getAddRecExpr(Start, Step, A->getLoop());
|
||||||
|
@ -233,14 +233,14 @@ static bool FactorOutConstant(SCEVHandle &S,
|
||||||
/// loop-invariant portions of expressions, after considering what
|
/// loop-invariant portions of expressions, after considering what
|
||||||
/// can be folded using target addressing modes.
|
/// can be folded using target addressing modes.
|
||||||
///
|
///
|
||||||
Value *SCEVExpander::expandAddToGEP(const SCEVHandle *op_begin,
|
Value *SCEVExpander::expandAddToGEP(const SCEV* const *op_begin,
|
||||||
const SCEVHandle *op_end,
|
const SCEV* const *op_end,
|
||||||
const PointerType *PTy,
|
const PointerType *PTy,
|
||||||
const Type *Ty,
|
const Type *Ty,
|
||||||
Value *V) {
|
Value *V) {
|
||||||
const Type *ElTy = PTy->getElementType();
|
const Type *ElTy = PTy->getElementType();
|
||||||
SmallVector<Value *, 4> GepIndices;
|
SmallVector<Value *, 4> GepIndices;
|
||||||
SmallVector<SCEVHandle, 8> Ops(op_begin, op_end);
|
SmallVector<const SCEV*, 8> Ops(op_begin, op_end);
|
||||||
bool AnyNonZeroIndices = false;
|
bool AnyNonZeroIndices = false;
|
||||||
|
|
||||||
// Decend down the pointer's type and attempt to convert the other
|
// Decend down the pointer's type and attempt to convert the other
|
||||||
|
@ -251,14 +251,14 @@ Value *SCEVExpander::expandAddToGEP(const SCEVHandle *op_begin,
|
||||||
for (;;) {
|
for (;;) {
|
||||||
APInt ElSize = APInt(SE.getTypeSizeInBits(Ty),
|
APInt ElSize = APInt(SE.getTypeSizeInBits(Ty),
|
||||||
ElTy->isSized() ? SE.TD->getTypeAllocSize(ElTy) : 0);
|
ElTy->isSized() ? SE.TD->getTypeAllocSize(ElTy) : 0);
|
||||||
SmallVector<SCEVHandle, 8> NewOps;
|
SmallVector<const SCEV*, 8> NewOps;
|
||||||
SmallVector<SCEVHandle, 8> ScaledOps;
|
SmallVector<const SCEV*, 8> ScaledOps;
|
||||||
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
|
||||||
// Split AddRecs up into parts as either of the parts may be usable
|
// Split AddRecs up into parts as either of the parts may be usable
|
||||||
// without the other.
|
// without the other.
|
||||||
if (const SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(Ops[i]))
|
if (const SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(Ops[i]))
|
||||||
if (!A->getStart()->isZero()) {
|
if (!A->getStart()->isZero()) {
|
||||||
SCEVHandle Start = A->getStart();
|
const SCEV* Start = A->getStart();
|
||||||
Ops.push_back(SE.getAddRecExpr(SE.getIntegerSCEV(0, A->getType()),
|
Ops.push_back(SE.getAddRecExpr(SE.getIntegerSCEV(0, A->getType()),
|
||||||
A->getStepRecurrence(SE),
|
A->getStepRecurrence(SE),
|
||||||
A->getLoop()));
|
A->getLoop()));
|
||||||
|
@ -267,8 +267,8 @@ Value *SCEVExpander::expandAddToGEP(const SCEVHandle *op_begin,
|
||||||
}
|
}
|
||||||
// If the scale size is not 0, attempt to factor out a scale.
|
// If the scale size is not 0, attempt to factor out a scale.
|
||||||
if (ElSize != 0) {
|
if (ElSize != 0) {
|
||||||
SCEVHandle Op = Ops[i];
|
const SCEV* Op = Ops[i];
|
||||||
SCEVHandle Remainder = SE.getIntegerSCEV(0, Op->getType());
|
const SCEV* Remainder = SE.getIntegerSCEV(0, Op->getType());
|
||||||
if (FactorOutConstant(Op, Remainder, ElSize, SE)) {
|
if (FactorOutConstant(Op, Remainder, ElSize, SE)) {
|
||||||
ScaledOps.push_back(Op); // Op now has ElSize factored out.
|
ScaledOps.push_back(Op); // Op now has ElSize factored out.
|
||||||
NewOps.push_back(Remainder);
|
NewOps.push_back(Remainder);
|
||||||
|
@ -364,7 +364,7 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
|
||||||
// comments on expandAddToGEP for details.
|
// comments on expandAddToGEP for details.
|
||||||
if (SE.TD)
|
if (SE.TD)
|
||||||
if (const PointerType *PTy = dyn_cast<PointerType>(V->getType())) {
|
if (const PointerType *PTy = dyn_cast<PointerType>(V->getType())) {
|
||||||
const SmallVectorImpl<SCEVHandle> &Ops = S->getOperands();
|
const SmallVectorImpl<const SCEV*> &Ops = S->getOperands();
|
||||||
return expandAddToGEP(&Ops[0], &Ops[Ops.size() - 1],
|
return expandAddToGEP(&Ops[0], &Ops[Ops.size() - 1],
|
||||||
PTy, Ty, V);
|
PTy, Ty, V);
|
||||||
}
|
}
|
||||||
|
@ -420,7 +420,7 @@ Value *SCEVExpander::visitUDivExpr(const SCEVUDivExpr *S) {
|
||||||
/// Move parts of Base into Rest to leave Base with the minimal
|
/// Move parts of Base into Rest to leave Base with the minimal
|
||||||
/// expression that provides a pointer operand suitable for a
|
/// expression that provides a pointer operand suitable for a
|
||||||
/// GEP expansion.
|
/// GEP expansion.
|
||||||
static void ExposePointerBase(SCEVHandle &Base, SCEVHandle &Rest,
|
static void ExposePointerBase(const SCEV* &Base, const SCEV* &Rest,
|
||||||
ScalarEvolution &SE) {
|
ScalarEvolution &SE) {
|
||||||
while (const SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(Base)) {
|
while (const SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(Base)) {
|
||||||
Base = A->getStart();
|
Base = A->getStart();
|
||||||
|
@ -431,7 +431,7 @@ static void ExposePointerBase(SCEVHandle &Base, SCEVHandle &Rest,
|
||||||
}
|
}
|
||||||
if (const SCEVAddExpr *A = dyn_cast<SCEVAddExpr>(Base)) {
|
if (const SCEVAddExpr *A = dyn_cast<SCEVAddExpr>(Base)) {
|
||||||
Base = A->getOperand(A->getNumOperands()-1);
|
Base = A->getOperand(A->getNumOperands()-1);
|
||||||
SmallVector<SCEVHandle, 8> NewAddOps(A->op_begin(), A->op_end());
|
SmallVector<const SCEV*, 8> NewAddOps(A->op_begin(), A->op_end());
|
||||||
NewAddOps.back() = Rest;
|
NewAddOps.back() = Rest;
|
||||||
Rest = SE.getAddExpr(NewAddOps);
|
Rest = SE.getAddExpr(NewAddOps);
|
||||||
ExposePointerBase(Base, Rest, SE);
|
ExposePointerBase(Base, Rest, SE);
|
||||||
|
@ -455,9 +455,9 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
|
||||||
if (CanonicalIV &&
|
if (CanonicalIV &&
|
||||||
SE.getTypeSizeInBits(CanonicalIV->getType()) >
|
SE.getTypeSizeInBits(CanonicalIV->getType()) >
|
||||||
SE.getTypeSizeInBits(Ty)) {
|
SE.getTypeSizeInBits(Ty)) {
|
||||||
SCEVHandle Start = SE.getAnyExtendExpr(S->getStart(),
|
const SCEV* Start = SE.getAnyExtendExpr(S->getStart(),
|
||||||
CanonicalIV->getType());
|
CanonicalIV->getType());
|
||||||
SCEVHandle Step = SE.getAnyExtendExpr(S->getStepRecurrence(SE),
|
const SCEV* Step = SE.getAnyExtendExpr(S->getStepRecurrence(SE),
|
||||||
CanonicalIV->getType());
|
CanonicalIV->getType());
|
||||||
Value *V = expand(SE.getAddRecExpr(Start, Step, S->getLoop()));
|
Value *V = expand(SE.getAddRecExpr(Start, Step, S->getLoop()));
|
||||||
BasicBlock::iterator SaveInsertPt = getInsertionPoint();
|
BasicBlock::iterator SaveInsertPt = getInsertionPoint();
|
||||||
|
@ -472,16 +472,16 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
|
||||||
|
|
||||||
// {X,+,F} --> X + {0,+,F}
|
// {X,+,F} --> X + {0,+,F}
|
||||||
if (!S->getStart()->isZero()) {
|
if (!S->getStart()->isZero()) {
|
||||||
const SmallVectorImpl<SCEVHandle> &SOperands = S->getOperands();
|
const SmallVectorImpl<const SCEV*> &SOperands = S->getOperands();
|
||||||
SmallVector<SCEVHandle, 4> NewOps(SOperands.begin(), SOperands.end());
|
SmallVector<const SCEV*, 4> NewOps(SOperands.begin(), SOperands.end());
|
||||||
NewOps[0] = SE.getIntegerSCEV(0, Ty);
|
NewOps[0] = SE.getIntegerSCEV(0, Ty);
|
||||||
SCEVHandle Rest = SE.getAddRecExpr(NewOps, L);
|
const SCEV* Rest = SE.getAddRecExpr(NewOps, L);
|
||||||
|
|
||||||
// Turn things like ptrtoint+arithmetic+inttoptr into GEP. See the
|
// Turn things like ptrtoint+arithmetic+inttoptr into GEP. See the
|
||||||
// comments on expandAddToGEP for details.
|
// comments on expandAddToGEP for details.
|
||||||
if (SE.TD) {
|
if (SE.TD) {
|
||||||
SCEVHandle Base = S->getStart();
|
const SCEV* Base = S->getStart();
|
||||||
SCEVHandle RestArray[1] = { Rest };
|
const SCEV* RestArray[1] = { Rest };
|
||||||
// Dig into the expression to find the pointer base for a GEP.
|
// Dig into the expression to find the pointer base for a GEP.
|
||||||
ExposePointerBase(Base, RestArray[0], SE);
|
ExposePointerBase(Base, RestArray[0], SE);
|
||||||
// If we found a pointer, expand the AddRec with a GEP.
|
// If we found a pointer, expand the AddRec with a GEP.
|
||||||
|
@ -581,19 +581,19 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
|
||||||
// folders, then expandCodeFor the closed form. This allows the folders to
|
// folders, then expandCodeFor the closed form. This allows the folders to
|
||||||
// simplify the expression without having to build a bunch of special code
|
// simplify the expression without having to build a bunch of special code
|
||||||
// into this folder.
|
// into this folder.
|
||||||
SCEVHandle IH = SE.getUnknown(I); // Get I as a "symbolic" SCEV.
|
const SCEV* IH = SE.getUnknown(I); // Get I as a "symbolic" SCEV.
|
||||||
|
|
||||||
// Promote S up to the canonical IV type, if the cast is foldable.
|
// Promote S up to the canonical IV type, if the cast is foldable.
|
||||||
SCEVHandle NewS = S;
|
const SCEV* NewS = S;
|
||||||
SCEVHandle Ext = SE.getNoopOrAnyExtend(S, I->getType());
|
const SCEV* Ext = SE.getNoopOrAnyExtend(S, I->getType());
|
||||||
if (isa<SCEVAddRecExpr>(Ext))
|
if (isa<SCEVAddRecExpr>(Ext))
|
||||||
NewS = Ext;
|
NewS = Ext;
|
||||||
|
|
||||||
SCEVHandle V = cast<SCEVAddRecExpr>(NewS)->evaluateAtIteration(IH, SE);
|
const SCEV* V = cast<SCEVAddRecExpr>(NewS)->evaluateAtIteration(IH, SE);
|
||||||
//cerr << "Evaluated: " << *this << "\n to: " << *V << "\n";
|
//cerr << "Evaluated: " << *this << "\n to: " << *V << "\n";
|
||||||
|
|
||||||
// Truncate the result down to the original type, if needed.
|
// Truncate the result down to the original type, if needed.
|
||||||
SCEVHandle T = SE.getTruncateOrNoop(V, Ty);
|
const SCEV* T = SE.getTruncateOrNoop(V, Ty);
|
||||||
return expand(V);
|
return expand(V);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,7 +654,7 @@ Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) {
|
||||||
return LHS;
|
return LHS;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *SCEVExpander::expandCodeFor(SCEVHandle SH, const Type *Ty) {
|
Value *SCEVExpander::expandCodeFor(const SCEV* SH, const Type *Ty) {
|
||||||
// Expand the code for this SCEV.
|
// Expand the code for this SCEV.
|
||||||
Value *V = expand(SH);
|
Value *V = expand(SH);
|
||||||
if (Ty) {
|
if (Ty) {
|
||||||
|
@ -667,7 +667,7 @@ Value *SCEVExpander::expandCodeFor(SCEVHandle SH, const Type *Ty) {
|
||||||
|
|
||||||
Value *SCEVExpander::expand(const SCEV *S) {
|
Value *SCEVExpander::expand(const SCEV *S) {
|
||||||
// Check to see if we already expanded this.
|
// Check to see if we already expanded this.
|
||||||
std::map<SCEVHandle, AssertingVH<Value> >::iterator I =
|
std::map<const SCEV*, AssertingVH<Value> >::iterator I =
|
||||||
InsertedExpressions.find(S);
|
InsertedExpressions.find(S);
|
||||||
if (I != InsertedExpressions.end())
|
if (I != InsertedExpressions.end())
|
||||||
return I->second;
|
return I->second;
|
||||||
|
@ -685,7 +685,7 @@ Value *
|
||||||
SCEVExpander::getOrInsertCanonicalInductionVariable(const Loop *L,
|
SCEVExpander::getOrInsertCanonicalInductionVariable(const Loop *L,
|
||||||
const Type *Ty) {
|
const Type *Ty) {
|
||||||
assert(Ty->isInteger() && "Can only insert integer induction variables!");
|
assert(Ty->isInteger() && "Can only insert integer induction variables!");
|
||||||
SCEVHandle H = SE.getAddRecExpr(SE.getIntegerSCEV(0, Ty),
|
const SCEV* H = SE.getAddRecExpr(SE.getIntegerSCEV(0, Ty),
|
||||||
SE.getIntegerSCEV(1, Ty), L);
|
SE.getIntegerSCEV(1, Ty), L);
|
||||||
return expand(H);
|
return expand(H);
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ namespace {
|
||||||
|
|
||||||
void RewriteNonIntegerIVs(Loop *L);
|
void RewriteNonIntegerIVs(Loop *L);
|
||||||
|
|
||||||
ICmpInst *LinearFunctionTestReplace(Loop *L, SCEVHandle BackedgeTakenCount,
|
ICmpInst *LinearFunctionTestReplace(Loop *L, const SCEV* BackedgeTakenCount,
|
||||||
Value *IndVar,
|
Value *IndVar,
|
||||||
BasicBlock *ExitingBlock,
|
BasicBlock *ExitingBlock,
|
||||||
BranchInst *BI,
|
BranchInst *BI,
|
||||||
|
@ -128,7 +128,7 @@ Pass *llvm::createIndVarSimplifyPass() {
|
||||||
/// SCEV analysis can determine a loop-invariant trip count of the loop, which
|
/// SCEV analysis can determine a loop-invariant trip count of the loop, which
|
||||||
/// is actually a much broader range than just linear tests.
|
/// is actually a much broader range than just linear tests.
|
||||||
ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L,
|
ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L,
|
||||||
SCEVHandle BackedgeTakenCount,
|
const SCEV* BackedgeTakenCount,
|
||||||
Value *IndVar,
|
Value *IndVar,
|
||||||
BasicBlock *ExitingBlock,
|
BasicBlock *ExitingBlock,
|
||||||
BranchInst *BI,
|
BranchInst *BI,
|
||||||
|
@ -137,13 +137,13 @@ ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L,
|
||||||
// against the preincremented value, otherwise we prefer to compare against
|
// against the preincremented value, otherwise we prefer to compare against
|
||||||
// the post-incremented value.
|
// the post-incremented value.
|
||||||
Value *CmpIndVar;
|
Value *CmpIndVar;
|
||||||
SCEVHandle RHS = BackedgeTakenCount;
|
const SCEV* RHS = BackedgeTakenCount;
|
||||||
if (ExitingBlock == L->getLoopLatch()) {
|
if (ExitingBlock == L->getLoopLatch()) {
|
||||||
// Add one to the "backedge-taken" count to get the trip count.
|
// Add one to the "backedge-taken" count to get the trip count.
|
||||||
// If this addition may overflow, we have to be more pessimistic and
|
// If this addition may overflow, we have to be more pessimistic and
|
||||||
// cast the induction variable before doing the add.
|
// cast the induction variable before doing the add.
|
||||||
SCEVHandle Zero = SE->getIntegerSCEV(0, BackedgeTakenCount->getType());
|
const SCEV* Zero = SE->getIntegerSCEV(0, BackedgeTakenCount->getType());
|
||||||
SCEVHandle N =
|
const SCEV* N =
|
||||||
SE->getAddExpr(BackedgeTakenCount,
|
SE->getAddExpr(BackedgeTakenCount,
|
||||||
SE->getIntegerSCEV(1, BackedgeTakenCount->getType()));
|
SE->getIntegerSCEV(1, BackedgeTakenCount->getType()));
|
||||||
if ((isa<SCEVConstant>(N) && !N->isZero()) ||
|
if ((isa<SCEVConstant>(N) && !N->isZero()) ||
|
||||||
|
@ -278,7 +278,7 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L,
|
||||||
// Okay, this instruction has a user outside of the current loop
|
// Okay, this instruction has a user outside of the current loop
|
||||||
// and varies predictably *inside* the loop. Evaluate the value it
|
// and varies predictably *inside* the loop. Evaluate the value it
|
||||||
// contains when the loop exits, if possible.
|
// contains when the loop exits, if possible.
|
||||||
SCEVHandle ExitValue = SE->getSCEVAtScope(Inst, L->getParentLoop());
|
const SCEV* ExitValue = SE->getSCEVAtScope(Inst, L->getParentLoop());
|
||||||
if (!ExitValue->isLoopInvariant(L))
|
if (!ExitValue->isLoopInvariant(L))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||||
|
|
||||||
BasicBlock *Header = L->getHeader();
|
BasicBlock *Header = L->getHeader();
|
||||||
BasicBlock *ExitingBlock = L->getExitingBlock(); // may be null
|
BasicBlock *ExitingBlock = L->getExitingBlock(); // may be null
|
||||||
SCEVHandle BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
const SCEV* BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
||||||
|
|
||||||
// Check to see if this loop has a computable loop-invariant execution count.
|
// Check to see if this loop has a computable loop-invariant execution count.
|
||||||
// If so, this means that we can compute the final value of any expressions
|
// If so, this means that we can compute the final value of any expressions
|
||||||
|
@ -373,14 +373,14 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||||
NeedCannIV = true;
|
NeedCannIV = true;
|
||||||
}
|
}
|
||||||
for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
|
for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
|
||||||
SCEVHandle Stride = IU->StrideOrder[i];
|
const SCEV* Stride = IU->StrideOrder[i];
|
||||||
const Type *Ty = SE->getEffectiveSCEVType(Stride->getType());
|
const Type *Ty = SE->getEffectiveSCEVType(Stride->getType());
|
||||||
if (!LargestType ||
|
if (!LargestType ||
|
||||||
SE->getTypeSizeInBits(Ty) >
|
SE->getTypeSizeInBits(Ty) >
|
||||||
SE->getTypeSizeInBits(LargestType))
|
SE->getTypeSizeInBits(LargestType))
|
||||||
LargestType = Ty;
|
LargestType = Ty;
|
||||||
|
|
||||||
std::map<SCEVHandle, IVUsersOfOneStride *>::iterator SI =
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator SI =
|
||||||
IU->IVUsesByStride.find(IU->StrideOrder[i]);
|
IU->IVUsesByStride.find(IU->StrideOrder[i]);
|
||||||
assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
|
assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
|
||||||
|
|
||||||
|
@ -473,21 +473,21 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType,
|
||||||
// the need for the code evaluation methods to insert induction variables
|
// the need for the code evaluation methods to insert induction variables
|
||||||
// of different sizes.
|
// of different sizes.
|
||||||
for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
|
for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
|
||||||
SCEVHandle Stride = IU->StrideOrder[i];
|
const SCEV* Stride = IU->StrideOrder[i];
|
||||||
|
|
||||||
std::map<SCEVHandle, IVUsersOfOneStride *>::iterator SI =
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator SI =
|
||||||
IU->IVUsesByStride.find(IU->StrideOrder[i]);
|
IU->IVUsesByStride.find(IU->StrideOrder[i]);
|
||||||
assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
|
assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
|
||||||
ilist<IVStrideUse> &List = SI->second->Users;
|
ilist<IVStrideUse> &List = SI->second->Users;
|
||||||
for (ilist<IVStrideUse>::iterator UI = List.begin(),
|
for (ilist<IVStrideUse>::iterator UI = List.begin(),
|
||||||
E = List.end(); UI != E; ++UI) {
|
E = List.end(); UI != E; ++UI) {
|
||||||
SCEVHandle Offset = UI->getOffset();
|
const SCEV* Offset = UI->getOffset();
|
||||||
Value *Op = UI->getOperandValToReplace();
|
Value *Op = UI->getOperandValToReplace();
|
||||||
const Type *UseTy = Op->getType();
|
const Type *UseTy = Op->getType();
|
||||||
Instruction *User = UI->getUser();
|
Instruction *User = UI->getUser();
|
||||||
|
|
||||||
// Compute the final addrec to expand into code.
|
// Compute the final addrec to expand into code.
|
||||||
SCEVHandle AR = IU->getReplacementExpr(*UI);
|
const SCEV* AR = IU->getReplacementExpr(*UI);
|
||||||
|
|
||||||
Value *NewVal = 0;
|
Value *NewVal = 0;
|
||||||
if (AR->isLoopInvariant(L)) {
|
if (AR->isLoopInvariant(L)) {
|
||||||
|
|
|
@ -187,7 +187,7 @@ bool LoopDeletion::runOnLoop(Loop* L, LPPassManager& LPM) {
|
||||||
// Don't remove loops for which we can't solve the trip count.
|
// Don't remove loops for which we can't solve the trip count.
|
||||||
// They could be infinite, in which case we'd be changing program behavior.
|
// They could be infinite, in which case we'd be changing program behavior.
|
||||||
ScalarEvolution& SE = getAnalysis<ScalarEvolution>();
|
ScalarEvolution& SE = getAnalysis<ScalarEvolution>();
|
||||||
SCEVHandle S = SE.getBackedgeTakenCount(L);
|
const SCEV* S = SE.getBackedgeTakenCount(L);
|
||||||
if (isa<SCEVCouldNotCompute>(S))
|
if (isa<SCEVCouldNotCompute>(S))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -64,11 +64,11 @@ namespace {
|
||||||
/// StrengthReduceStridedIVUsers. It contains the stride, the common base, as
|
/// StrengthReduceStridedIVUsers. It contains the stride, the common base, as
|
||||||
/// well as the PHI node and increment value created for rewrite.
|
/// well as the PHI node and increment value created for rewrite.
|
||||||
struct VISIBILITY_HIDDEN IVExpr {
|
struct VISIBILITY_HIDDEN IVExpr {
|
||||||
SCEVHandle Stride;
|
const SCEV* Stride;
|
||||||
SCEVHandle Base;
|
const SCEV* Base;
|
||||||
PHINode *PHI;
|
PHINode *PHI;
|
||||||
|
|
||||||
IVExpr(const SCEVHandle &stride, const SCEVHandle &base, PHINode *phi)
|
IVExpr(const SCEV* const stride, const SCEV* const base, PHINode *phi)
|
||||||
: Stride(stride), Base(base), PHI(phi) {}
|
: Stride(stride), Base(base), PHI(phi) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ namespace {
|
||||||
struct VISIBILITY_HIDDEN IVsOfOneStride {
|
struct VISIBILITY_HIDDEN IVsOfOneStride {
|
||||||
std::vector<IVExpr> IVs;
|
std::vector<IVExpr> IVs;
|
||||||
|
|
||||||
void addIV(const SCEVHandle &Stride, const SCEVHandle &Base, PHINode *PHI) {
|
void addIV(const SCEV* const Stride, const SCEV* const Base, PHINode *PHI) {
|
||||||
IVs.push_back(IVExpr(Stride, Base, PHI));
|
IVs.push_back(IVExpr(Stride, Base, PHI));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -91,11 +91,11 @@ namespace {
|
||||||
|
|
||||||
/// IVsByStride - Keep track of all IVs that have been inserted for a
|
/// IVsByStride - Keep track of all IVs that have been inserted for a
|
||||||
/// particular stride.
|
/// particular stride.
|
||||||
std::map<SCEVHandle, IVsOfOneStride> IVsByStride;
|
std::map<const SCEV*, IVsOfOneStride> IVsByStride;
|
||||||
|
|
||||||
/// StrideNoReuse - Keep track of all the strides whose ivs cannot be
|
/// StrideNoReuse - Keep track of all the strides whose ivs cannot be
|
||||||
/// reused (nor should they be rewritten to reuse other strides).
|
/// reused (nor should they be rewritten to reuse other strides).
|
||||||
SmallSet<SCEVHandle, 4> StrideNoReuse;
|
SmallSet<const SCEV*, 4> StrideNoReuse;
|
||||||
|
|
||||||
/// DeadInsts - Keep track of instructions we may have made dead, so that
|
/// DeadInsts - Keep track of instructions we may have made dead, so that
|
||||||
/// we can remove them after we are done working.
|
/// we can remove them after we are done working.
|
||||||
|
@ -133,7 +133,7 @@ namespace {
|
||||||
private:
|
private:
|
||||||
ICmpInst *ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
ICmpInst *ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
||||||
IVStrideUse* &CondUse,
|
IVStrideUse* &CondUse,
|
||||||
const SCEVHandle* &CondStride);
|
const SCEV* const * &CondStride);
|
||||||
|
|
||||||
void OptimizeIndvars(Loop *L);
|
void OptimizeIndvars(Loop *L);
|
||||||
void OptimizeLoopCountIV(Loop *L);
|
void OptimizeLoopCountIV(Loop *L);
|
||||||
|
@ -149,16 +149,16 @@ namespace {
|
||||||
IVStrideUse* &CondUse);
|
IVStrideUse* &CondUse);
|
||||||
|
|
||||||
bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
|
bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
|
||||||
const SCEVHandle *&CondStride);
|
const SCEV* const * &CondStride);
|
||||||
bool RequiresTypeConversion(const Type *Ty, const Type *NewTy);
|
bool RequiresTypeConversion(const Type *Ty, const Type *NewTy);
|
||||||
SCEVHandle CheckForIVReuse(bool, bool, bool, const SCEVHandle&,
|
const SCEV* CheckForIVReuse(bool, bool, bool, const SCEV* const&,
|
||||||
IVExpr&, const Type*,
|
IVExpr&, const Type*,
|
||||||
const std::vector<BasedUser>& UsersToProcess);
|
const std::vector<BasedUser>& UsersToProcess);
|
||||||
bool ValidScale(bool, int64_t,
|
bool ValidScale(bool, int64_t,
|
||||||
const std::vector<BasedUser>& UsersToProcess);
|
const std::vector<BasedUser>& UsersToProcess);
|
||||||
bool ValidOffset(bool, int64_t, int64_t,
|
bool ValidOffset(bool, int64_t, int64_t,
|
||||||
const std::vector<BasedUser>& UsersToProcess);
|
const std::vector<BasedUser>& UsersToProcess);
|
||||||
SCEVHandle CollectIVUsers(const SCEVHandle &Stride,
|
const SCEV* CollectIVUsers(const SCEV* const &Stride,
|
||||||
IVUsersOfOneStride &Uses,
|
IVUsersOfOneStride &Uses,
|
||||||
Loop *L,
|
Loop *L,
|
||||||
bool &AllUsesAreAddresses,
|
bool &AllUsesAreAddresses,
|
||||||
|
@ -168,11 +168,11 @@ namespace {
|
||||||
const std::vector<BasedUser> &UsersToProcess,
|
const std::vector<BasedUser> &UsersToProcess,
|
||||||
const Loop *L,
|
const Loop *L,
|
||||||
bool AllUsesAreAddresses,
|
bool AllUsesAreAddresses,
|
||||||
SCEVHandle Stride);
|
const SCEV* Stride);
|
||||||
void PrepareToStrengthReduceFully(
|
void PrepareToStrengthReduceFully(
|
||||||
std::vector<BasedUser> &UsersToProcess,
|
std::vector<BasedUser> &UsersToProcess,
|
||||||
SCEVHandle Stride,
|
const SCEV* Stride,
|
||||||
SCEVHandle CommonExprs,
|
const SCEV* CommonExprs,
|
||||||
const Loop *L,
|
const Loop *L,
|
||||||
SCEVExpander &PreheaderRewriter);
|
SCEVExpander &PreheaderRewriter);
|
||||||
void PrepareToStrengthReduceFromSmallerStride(
|
void PrepareToStrengthReduceFromSmallerStride(
|
||||||
|
@ -182,13 +182,13 @@ namespace {
|
||||||
Instruction *PreInsertPt);
|
Instruction *PreInsertPt);
|
||||||
void PrepareToStrengthReduceWithNewPhi(
|
void PrepareToStrengthReduceWithNewPhi(
|
||||||
std::vector<BasedUser> &UsersToProcess,
|
std::vector<BasedUser> &UsersToProcess,
|
||||||
SCEVHandle Stride,
|
const SCEV* Stride,
|
||||||
SCEVHandle CommonExprs,
|
const SCEV* CommonExprs,
|
||||||
Value *CommonBaseV,
|
Value *CommonBaseV,
|
||||||
Instruction *IVIncInsertPt,
|
Instruction *IVIncInsertPt,
|
||||||
const Loop *L,
|
const Loop *L,
|
||||||
SCEVExpander &PreheaderRewriter);
|
SCEVExpander &PreheaderRewriter);
|
||||||
void StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
void StrengthReduceStridedIVUsers(const SCEV* const &Stride,
|
||||||
IVUsersOfOneStride &Uses,
|
IVUsersOfOneStride &Uses,
|
||||||
Loop *L);
|
Loop *L);
|
||||||
void DeleteTriviallyDeadInstructions();
|
void DeleteTriviallyDeadInstructions();
|
||||||
|
@ -232,7 +232,7 @@ void LoopStrengthReduce::DeleteTriviallyDeadInstructions() {
|
||||||
/// containsAddRecFromDifferentLoop - Determine whether expression S involves a
|
/// containsAddRecFromDifferentLoop - Determine whether expression S involves a
|
||||||
/// subexpression that is an AddRec from a loop other than L. An outer loop
|
/// subexpression that is an AddRec from a loop other than L. An outer loop
|
||||||
/// of L is OK, but not an inner loop nor a disjoint loop.
|
/// of L is OK, but not an inner loop nor a disjoint loop.
|
||||||
static bool containsAddRecFromDifferentLoop(SCEVHandle S, Loop *L) {
|
static bool containsAddRecFromDifferentLoop(const SCEV* S, Loop *L) {
|
||||||
// This is very common, put it first.
|
// This is very common, put it first.
|
||||||
if (isa<SCEVConstant>(S))
|
if (isa<SCEVConstant>(S))
|
||||||
return false;
|
return false;
|
||||||
|
@ -327,7 +327,7 @@ namespace {
|
||||||
/// this use. As the use is processed, information gets moved from this
|
/// this use. As the use is processed, information gets moved from this
|
||||||
/// field to the Imm field (below). BasedUser values are sorted by this
|
/// field to the Imm field (below). BasedUser values are sorted by this
|
||||||
/// field.
|
/// field.
|
||||||
SCEVHandle Base;
|
const SCEV* Base;
|
||||||
|
|
||||||
/// Inst - The instruction using the induction variable.
|
/// Inst - The instruction using the induction variable.
|
||||||
Instruction *Inst;
|
Instruction *Inst;
|
||||||
|
@ -340,7 +340,7 @@ namespace {
|
||||||
/// before Inst, because it will be folded into the imm field of the
|
/// before Inst, because it will be folded into the imm field of the
|
||||||
/// instruction. This is also sometimes used for loop-variant values that
|
/// instruction. This is also sometimes used for loop-variant values that
|
||||||
/// must be added inside the loop.
|
/// must be added inside the loop.
|
||||||
SCEVHandle Imm;
|
const SCEV* Imm;
|
||||||
|
|
||||||
/// Phi - The induction variable that performs the striding that
|
/// Phi - The induction variable that performs the striding that
|
||||||
/// should be used for this user.
|
/// should be used for this user.
|
||||||
|
@ -362,13 +362,13 @@ namespace {
|
||||||
// Once we rewrite the code to insert the new IVs we want, update the
|
// Once we rewrite the code to insert the new IVs we want, update the
|
||||||
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
|
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
|
||||||
// to it.
|
// to it.
|
||||||
void RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
|
void RewriteInstructionToUseNewBase(const SCEV* const &NewBase,
|
||||||
Instruction *InsertPt,
|
Instruction *InsertPt,
|
||||||
SCEVExpander &Rewriter, Loop *L, Pass *P,
|
SCEVExpander &Rewriter, Loop *L, Pass *P,
|
||||||
LoopInfo &LI,
|
LoopInfo &LI,
|
||||||
SmallVectorImpl<WeakVH> &DeadInsts);
|
SmallVectorImpl<WeakVH> &DeadInsts);
|
||||||
|
|
||||||
Value *InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
|
Value *InsertCodeForBaseAtPosition(const SCEV* const &NewBase,
|
||||||
const Type *Ty,
|
const Type *Ty,
|
||||||
SCEVExpander &Rewriter,
|
SCEVExpander &Rewriter,
|
||||||
Instruction *IP, Loop *L,
|
Instruction *IP, Loop *L,
|
||||||
|
@ -383,7 +383,7 @@ void BasedUser::dump() const {
|
||||||
cerr << " Inst: " << *Inst;
|
cerr << " Inst: " << *Inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *BasedUser::InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
|
Value *BasedUser::InsertCodeForBaseAtPosition(const SCEV* const &NewBase,
|
||||||
const Type *Ty,
|
const Type *Ty,
|
||||||
SCEVExpander &Rewriter,
|
SCEVExpander &Rewriter,
|
||||||
Instruction *IP, Loop *L,
|
Instruction *IP, Loop *L,
|
||||||
|
@ -407,7 +407,7 @@ Value *BasedUser::InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
|
||||||
|
|
||||||
Value *Base = Rewriter.expandCodeFor(NewBase, 0, BaseInsertPt);
|
Value *Base = Rewriter.expandCodeFor(NewBase, 0, BaseInsertPt);
|
||||||
|
|
||||||
SCEVHandle NewValSCEV = SE->getUnknown(Base);
|
const SCEV* NewValSCEV = SE->getUnknown(Base);
|
||||||
|
|
||||||
// If there is no immediate value, skip the next part.
|
// If there is no immediate value, skip the next part.
|
||||||
if (!Imm->isZero()) {
|
if (!Imm->isZero()) {
|
||||||
|
@ -430,7 +430,7 @@ Value *BasedUser::InsertCodeForBaseAtPosition(const SCEVHandle &NewBase,
|
||||||
// value of NewBase in the case that it's a diffferent instruction from
|
// value of NewBase in the case that it's a diffferent instruction from
|
||||||
// the PHI that NewBase is computed from, or null otherwise.
|
// the PHI that NewBase is computed from, or null otherwise.
|
||||||
//
|
//
|
||||||
void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
|
void BasedUser::RewriteInstructionToUseNewBase(const SCEV* const &NewBase,
|
||||||
Instruction *NewBasePt,
|
Instruction *NewBasePt,
|
||||||
SCEVExpander &Rewriter, Loop *L, Pass *P,
|
SCEVExpander &Rewriter, Loop *L, Pass *P,
|
||||||
LoopInfo &LI,
|
LoopInfo &LI,
|
||||||
|
@ -542,7 +542,7 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase,
|
||||||
|
|
||||||
/// fitsInAddressMode - Return true if V can be subsumed within an addressing
|
/// fitsInAddressMode - Return true if V can be subsumed within an addressing
|
||||||
/// mode, and does not need to be put in a register first.
|
/// mode, and does not need to be put in a register first.
|
||||||
static bool fitsInAddressMode(const SCEVHandle &V, const Type *AccessTy,
|
static bool fitsInAddressMode(const SCEV* const &V, const Type *AccessTy,
|
||||||
const TargetLowering *TLI, bool HasBaseReg) {
|
const TargetLowering *TLI, bool HasBaseReg) {
|
||||||
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(V)) {
|
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(V)) {
|
||||||
int64_t VC = SC->getValue()->getSExtValue();
|
int64_t VC = SC->getValue()->getSExtValue();
|
||||||
|
@ -574,12 +574,12 @@ static bool fitsInAddressMode(const SCEVHandle &V, const Type *AccessTy,
|
||||||
|
|
||||||
/// MoveLoopVariantsToImmediateField - Move any subexpressions from Val that are
|
/// MoveLoopVariantsToImmediateField - Move any subexpressions from Val that are
|
||||||
/// loop varying to the Imm operand.
|
/// loop varying to the Imm operand.
|
||||||
static void MoveLoopVariantsToImmediateField(SCEVHandle &Val, SCEVHandle &Imm,
|
static void MoveLoopVariantsToImmediateField(const SCEV* &Val, const SCEV* &Imm,
|
||||||
Loop *L, ScalarEvolution *SE) {
|
Loop *L, ScalarEvolution *SE) {
|
||||||
if (Val->isLoopInvariant(L)) return; // Nothing to do.
|
if (Val->isLoopInvariant(L)) return; // Nothing to do.
|
||||||
|
|
||||||
if (const SCEVAddExpr *SAE = dyn_cast<SCEVAddExpr>(Val)) {
|
if (const SCEVAddExpr *SAE = dyn_cast<SCEVAddExpr>(Val)) {
|
||||||
SmallVector<SCEVHandle, 4> NewOps;
|
SmallVector<const SCEV*, 4> NewOps;
|
||||||
NewOps.reserve(SAE->getNumOperands());
|
NewOps.reserve(SAE->getNumOperands());
|
||||||
|
|
||||||
for (unsigned i = 0; i != SAE->getNumOperands(); ++i)
|
for (unsigned i = 0; i != SAE->getNumOperands(); ++i)
|
||||||
|
@ -597,10 +597,10 @@ static void MoveLoopVariantsToImmediateField(SCEVHandle &Val, SCEVHandle &Imm,
|
||||||
Val = SE->getAddExpr(NewOps);
|
Val = SE->getAddExpr(NewOps);
|
||||||
} else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Val)) {
|
} else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Val)) {
|
||||||
// Try to pull immediates out of the start value of nested addrec's.
|
// Try to pull immediates out of the start value of nested addrec's.
|
||||||
SCEVHandle Start = SARE->getStart();
|
const SCEV* Start = SARE->getStart();
|
||||||
MoveLoopVariantsToImmediateField(Start, Imm, L, SE);
|
MoveLoopVariantsToImmediateField(Start, Imm, L, SE);
|
||||||
|
|
||||||
SmallVector<SCEVHandle, 4> Ops(SARE->op_begin(), SARE->op_end());
|
SmallVector<const SCEV*, 4> Ops(SARE->op_begin(), SARE->op_end());
|
||||||
Ops[0] = Start;
|
Ops[0] = Start;
|
||||||
Val = SE->getAddRecExpr(Ops, SARE->getLoop());
|
Val = SE->getAddRecExpr(Ops, SARE->getLoop());
|
||||||
} else {
|
} else {
|
||||||
|
@ -616,15 +616,15 @@ static void MoveLoopVariantsToImmediateField(SCEVHandle &Val, SCEVHandle &Imm,
|
||||||
/// Accumulate these immediate values into the Imm value.
|
/// Accumulate these immediate values into the Imm value.
|
||||||
static void MoveImmediateValues(const TargetLowering *TLI,
|
static void MoveImmediateValues(const TargetLowering *TLI,
|
||||||
const Type *AccessTy,
|
const Type *AccessTy,
|
||||||
SCEVHandle &Val, SCEVHandle &Imm,
|
const SCEV* &Val, const SCEV* &Imm,
|
||||||
bool isAddress, Loop *L,
|
bool isAddress, Loop *L,
|
||||||
ScalarEvolution *SE) {
|
ScalarEvolution *SE) {
|
||||||
if (const SCEVAddExpr *SAE = dyn_cast<SCEVAddExpr>(Val)) {
|
if (const SCEVAddExpr *SAE = dyn_cast<SCEVAddExpr>(Val)) {
|
||||||
SmallVector<SCEVHandle, 4> NewOps;
|
SmallVector<const SCEV*, 4> NewOps;
|
||||||
NewOps.reserve(SAE->getNumOperands());
|
NewOps.reserve(SAE->getNumOperands());
|
||||||
|
|
||||||
for (unsigned i = 0; i != SAE->getNumOperands(); ++i) {
|
for (unsigned i = 0; i != SAE->getNumOperands(); ++i) {
|
||||||
SCEVHandle NewOp = SAE->getOperand(i);
|
const SCEV* NewOp = SAE->getOperand(i);
|
||||||
MoveImmediateValues(TLI, AccessTy, NewOp, Imm, isAddress, L, SE);
|
MoveImmediateValues(TLI, AccessTy, NewOp, Imm, isAddress, L, SE);
|
||||||
|
|
||||||
if (!NewOp->isLoopInvariant(L)) {
|
if (!NewOp->isLoopInvariant(L)) {
|
||||||
|
@ -643,11 +643,11 @@ static void MoveImmediateValues(const TargetLowering *TLI,
|
||||||
return;
|
return;
|
||||||
} else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Val)) {
|
} else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Val)) {
|
||||||
// Try to pull immediates out of the start value of nested addrec's.
|
// Try to pull immediates out of the start value of nested addrec's.
|
||||||
SCEVHandle Start = SARE->getStart();
|
const SCEV* Start = SARE->getStart();
|
||||||
MoveImmediateValues(TLI, AccessTy, Start, Imm, isAddress, L, SE);
|
MoveImmediateValues(TLI, AccessTy, Start, Imm, isAddress, L, SE);
|
||||||
|
|
||||||
if (Start != SARE->getStart()) {
|
if (Start != SARE->getStart()) {
|
||||||
SmallVector<SCEVHandle, 4> Ops(SARE->op_begin(), SARE->op_end());
|
SmallVector<const SCEV*, 4> Ops(SARE->op_begin(), SARE->op_end());
|
||||||
Ops[0] = Start;
|
Ops[0] = Start;
|
||||||
Val = SE->getAddRecExpr(Ops, SARE->getLoop());
|
Val = SE->getAddRecExpr(Ops, SARE->getLoop());
|
||||||
}
|
}
|
||||||
|
@ -658,8 +658,8 @@ static void MoveImmediateValues(const TargetLowering *TLI,
|
||||||
fitsInAddressMode(SME->getOperand(0), AccessTy, TLI, false) &&
|
fitsInAddressMode(SME->getOperand(0), AccessTy, TLI, false) &&
|
||||||
SME->getNumOperands() == 2 && SME->isLoopInvariant(L)) {
|
SME->getNumOperands() == 2 && SME->isLoopInvariant(L)) {
|
||||||
|
|
||||||
SCEVHandle SubImm = SE->getIntegerSCEV(0, Val->getType());
|
const SCEV* SubImm = SE->getIntegerSCEV(0, Val->getType());
|
||||||
SCEVHandle NewOp = SME->getOperand(1);
|
const SCEV* NewOp = SME->getOperand(1);
|
||||||
MoveImmediateValues(TLI, AccessTy, NewOp, SubImm, isAddress, L, SE);
|
MoveImmediateValues(TLI, AccessTy, NewOp, SubImm, isAddress, L, SE);
|
||||||
|
|
||||||
// If we extracted something out of the subexpressions, see if we can
|
// If we extracted something out of the subexpressions, see if we can
|
||||||
|
@ -694,7 +694,7 @@ static void MoveImmediateValues(const TargetLowering *TLI,
|
||||||
|
|
||||||
static void MoveImmediateValues(const TargetLowering *TLI,
|
static void MoveImmediateValues(const TargetLowering *TLI,
|
||||||
Instruction *User,
|
Instruction *User,
|
||||||
SCEVHandle &Val, SCEVHandle &Imm,
|
const SCEV* &Val, const SCEV* &Imm,
|
||||||
bool isAddress, Loop *L,
|
bool isAddress, Loop *L,
|
||||||
ScalarEvolution *SE) {
|
ScalarEvolution *SE) {
|
||||||
const Type *AccessTy = getAccessType(User);
|
const Type *AccessTy = getAccessType(User);
|
||||||
|
@ -704,19 +704,19 @@ static void MoveImmediateValues(const TargetLowering *TLI,
|
||||||
/// SeparateSubExprs - Decompose Expr into all of the subexpressions that are
|
/// SeparateSubExprs - Decompose Expr into all of the subexpressions that are
|
||||||
/// added together. This is used to reassociate common addition subexprs
|
/// added together. This is used to reassociate common addition subexprs
|
||||||
/// together for maximal sharing when rewriting bases.
|
/// together for maximal sharing when rewriting bases.
|
||||||
static void SeparateSubExprs(SmallVector<SCEVHandle, 16> &SubExprs,
|
static void SeparateSubExprs(SmallVector<const SCEV*, 16> &SubExprs,
|
||||||
SCEVHandle Expr,
|
const SCEV* Expr,
|
||||||
ScalarEvolution *SE) {
|
ScalarEvolution *SE) {
|
||||||
if (const SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(Expr)) {
|
if (const SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(Expr)) {
|
||||||
for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j)
|
for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j)
|
||||||
SeparateSubExprs(SubExprs, AE->getOperand(j), SE);
|
SeparateSubExprs(SubExprs, AE->getOperand(j), SE);
|
||||||
} else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Expr)) {
|
} else if (const SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Expr)) {
|
||||||
SCEVHandle Zero = SE->getIntegerSCEV(0, Expr->getType());
|
const SCEV* Zero = SE->getIntegerSCEV(0, Expr->getType());
|
||||||
if (SARE->getOperand(0) == Zero) {
|
if (SARE->getOperand(0) == Zero) {
|
||||||
SubExprs.push_back(Expr);
|
SubExprs.push_back(Expr);
|
||||||
} else {
|
} else {
|
||||||
// Compute the addrec with zero as its base.
|
// Compute the addrec with zero as its base.
|
||||||
SmallVector<SCEVHandle, 4> Ops(SARE->op_begin(), SARE->op_end());
|
SmallVector<const SCEV*, 4> Ops(SARE->op_begin(), SARE->op_end());
|
||||||
Ops[0] = Zero; // Start with zero base.
|
Ops[0] = Zero; // Start with zero base.
|
||||||
SubExprs.push_back(SE->getAddRecExpr(Ops, SARE->getLoop()));
|
SubExprs.push_back(SE->getAddRecExpr(Ops, SARE->getLoop()));
|
||||||
|
|
||||||
|
@ -740,7 +740,7 @@ struct SubExprUseData { unsigned Count; bool notAllUsesAreFree; };
|
||||||
/// not remove anything. This looks for things like (a+b+c) and
|
/// not remove anything. This looks for things like (a+b+c) and
|
||||||
/// (a+c+d) and computes the common (a+c) subexpression. The common expression
|
/// (a+c+d) and computes the common (a+c) subexpression. The common expression
|
||||||
/// is *removed* from the Bases and returned.
|
/// is *removed* from the Bases and returned.
|
||||||
static SCEVHandle
|
static const SCEV*
|
||||||
RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
||||||
ScalarEvolution *SE, Loop *L,
|
ScalarEvolution *SE, Loop *L,
|
||||||
const TargetLowering *TLI) {
|
const TargetLowering *TLI) {
|
||||||
|
@ -748,9 +748,9 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
||||||
|
|
||||||
// Only one use? This is a very common case, so we handle it specially and
|
// Only one use? This is a very common case, so we handle it specially and
|
||||||
// cheaply.
|
// cheaply.
|
||||||
SCEVHandle Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType());
|
const SCEV* Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType());
|
||||||
SCEVHandle Result = Zero;
|
const SCEV* Result = Zero;
|
||||||
SCEVHandle FreeResult = Zero;
|
const SCEV* FreeResult = Zero;
|
||||||
if (NumUses == 1) {
|
if (NumUses == 1) {
|
||||||
// If the use is inside the loop, use its base, regardless of what it is:
|
// If the use is inside the loop, use its base, regardless of what it is:
|
||||||
// it is clearly shared across all the IV's. If the use is outside the loop
|
// it is clearly shared across all the IV's. If the use is outside the loop
|
||||||
|
@ -766,13 +766,13 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
||||||
// Also track whether all uses of each expression can be moved into an
|
// Also track whether all uses of each expression can be moved into an
|
||||||
// an addressing mode "for free"; such expressions are left within the loop.
|
// an addressing mode "for free"; such expressions are left within the loop.
|
||||||
// struct SubExprUseData { unsigned Count; bool notAllUsesAreFree; };
|
// struct SubExprUseData { unsigned Count; bool notAllUsesAreFree; };
|
||||||
std::map<SCEVHandle, SubExprUseData> SubExpressionUseData;
|
std::map<const SCEV*, SubExprUseData> SubExpressionUseData;
|
||||||
|
|
||||||
// UniqueSubExprs - Keep track of all of the subexpressions we see in the
|
// UniqueSubExprs - Keep track of all of the subexpressions we see in the
|
||||||
// order we see them.
|
// order we see them.
|
||||||
SmallVector<SCEVHandle, 16> UniqueSubExprs;
|
SmallVector<const SCEV*, 16> UniqueSubExprs;
|
||||||
|
|
||||||
SmallVector<SCEVHandle, 16> SubExprs;
|
SmallVector<const SCEV*, 16> SubExprs;
|
||||||
unsigned NumUsesInsideLoop = 0;
|
unsigned NumUsesInsideLoop = 0;
|
||||||
for (unsigned i = 0; i != NumUses; ++i) {
|
for (unsigned i = 0; i != NumUses; ++i) {
|
||||||
// If the user is outside the loop, just ignore it for base computation.
|
// If the user is outside the loop, just ignore it for base computation.
|
||||||
|
@ -816,7 +816,7 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
||||||
// Now that we know how many times each is used, build Result. Iterate over
|
// Now that we know how many times each is used, build Result. Iterate over
|
||||||
// UniqueSubexprs so that we have a stable ordering.
|
// UniqueSubexprs so that we have a stable ordering.
|
||||||
for (unsigned i = 0, e = UniqueSubExprs.size(); i != e; ++i) {
|
for (unsigned i = 0, e = UniqueSubExprs.size(); i != e; ++i) {
|
||||||
std::map<SCEVHandle, SubExprUseData>::iterator I =
|
std::map<const SCEV*, SubExprUseData>::iterator I =
|
||||||
SubExpressionUseData.find(UniqueSubExprs[i]);
|
SubExpressionUseData.find(UniqueSubExprs[i]);
|
||||||
assert(I != SubExpressionUseData.end() && "Entry not found?");
|
assert(I != SubExpressionUseData.end() && "Entry not found?");
|
||||||
if (I->second.Count == NumUsesInsideLoop) { // Found CSE!
|
if (I->second.Count == NumUsesInsideLoop) { // Found CSE!
|
||||||
|
@ -860,7 +860,7 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses,
|
||||||
if (FreeResult != Zero) {
|
if (FreeResult != Zero) {
|
||||||
SeparateSubExprs(SubExprs, FreeResult, SE);
|
SeparateSubExprs(SubExprs, FreeResult, SE);
|
||||||
for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) {
|
for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) {
|
||||||
std::map<SCEVHandle, SubExprUseData>::iterator I =
|
std::map<const SCEV*, SubExprUseData>::iterator I =
|
||||||
SubExpressionUseData.find(SubExprs[j]);
|
SubExpressionUseData.find(SubExprs[j]);
|
||||||
SubExpressionUseData.erase(I);
|
SubExpressionUseData.erase(I);
|
||||||
}
|
}
|
||||||
|
@ -989,10 +989,10 @@ bool LoopStrengthReduce::RequiresTypeConversion(const Type *Ty1,
|
||||||
/// be folded into the addressing mode, nor even that the factor be constant;
|
/// be folded into the addressing mode, nor even that the factor be constant;
|
||||||
/// a multiply (executed once) outside the loop is better than another IV
|
/// a multiply (executed once) outside the loop is better than another IV
|
||||||
/// within. Well, usually.
|
/// within. Well, usually.
|
||||||
SCEVHandle LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg,
|
const SCEV* LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg,
|
||||||
bool AllUsesAreAddresses,
|
bool AllUsesAreAddresses,
|
||||||
bool AllUsesAreOutsideLoop,
|
bool AllUsesAreOutsideLoop,
|
||||||
const SCEVHandle &Stride,
|
const SCEV* const &Stride,
|
||||||
IVExpr &IV, const Type *Ty,
|
IVExpr &IV, const Type *Ty,
|
||||||
const std::vector<BasedUser>& UsersToProcess) {
|
const std::vector<BasedUser>& UsersToProcess) {
|
||||||
if (StrideNoReuse.count(Stride))
|
if (StrideNoReuse.count(Stride))
|
||||||
|
@ -1002,7 +1002,7 @@ SCEVHandle LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg,
|
||||||
int64_t SInt = SC->getValue()->getSExtValue();
|
int64_t SInt = SC->getValue()->getSExtValue();
|
||||||
for (unsigned NewStride = 0, e = IU->StrideOrder.size();
|
for (unsigned NewStride = 0, e = IU->StrideOrder.size();
|
||||||
NewStride != e; ++NewStride) {
|
NewStride != e; ++NewStride) {
|
||||||
std::map<SCEVHandle, IVsOfOneStride>::iterator SI =
|
std::map<const SCEV*, IVsOfOneStride>::iterator SI =
|
||||||
IVsByStride.find(IU->StrideOrder[NewStride]);
|
IVsByStride.find(IU->StrideOrder[NewStride]);
|
||||||
if (SI == IVsByStride.end() || !isa<SCEVConstant>(SI->first) ||
|
if (SI == IVsByStride.end() || !isa<SCEVConstant>(SI->first) ||
|
||||||
StrideNoReuse.count(SI->first))
|
StrideNoReuse.count(SI->first))
|
||||||
|
@ -1055,7 +1055,7 @@ SCEVHandle LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg,
|
||||||
// an existing IV if we can.
|
// an existing IV if we can.
|
||||||
for (unsigned NewStride = 0, e = IU->StrideOrder.size();
|
for (unsigned NewStride = 0, e = IU->StrideOrder.size();
|
||||||
NewStride != e; ++NewStride) {
|
NewStride != e; ++NewStride) {
|
||||||
std::map<SCEVHandle, IVsOfOneStride>::iterator SI =
|
std::map<const SCEV*, IVsOfOneStride>::iterator SI =
|
||||||
IVsByStride.find(IU->StrideOrder[NewStride]);
|
IVsByStride.find(IU->StrideOrder[NewStride]);
|
||||||
if (SI == IVsByStride.end() || !isa<SCEVConstant>(SI->first))
|
if (SI == IVsByStride.end() || !isa<SCEVConstant>(SI->first))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1075,7 +1075,7 @@ SCEVHandle LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg,
|
||||||
// -1*old.
|
// -1*old.
|
||||||
for (unsigned NewStride = 0, e = IU->StrideOrder.size();
|
for (unsigned NewStride = 0, e = IU->StrideOrder.size();
|
||||||
NewStride != e; ++NewStride) {
|
NewStride != e; ++NewStride) {
|
||||||
std::map<SCEVHandle, IVsOfOneStride>::iterator SI =
|
std::map<const SCEV*, IVsOfOneStride>::iterator SI =
|
||||||
IVsByStride.find(IU->StrideOrder[NewStride]);
|
IVsByStride.find(IU->StrideOrder[NewStride]);
|
||||||
if (SI == IVsByStride.end())
|
if (SI == IVsByStride.end())
|
||||||
continue;
|
continue;
|
||||||
|
@ -1104,7 +1104,7 @@ static bool PartitionByIsUseOfPostIncrementedValue(const BasedUser &Val) {
|
||||||
|
|
||||||
/// isNonConstantNegative - Return true if the specified scev is negated, but
|
/// isNonConstantNegative - Return true if the specified scev is negated, but
|
||||||
/// not a constant.
|
/// not a constant.
|
||||||
static bool isNonConstantNegative(const SCEVHandle &Expr) {
|
static bool isNonConstantNegative(const SCEV* const &Expr) {
|
||||||
const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(Expr);
|
const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(Expr);
|
||||||
if (!Mul) return false;
|
if (!Mul) return false;
|
||||||
|
|
||||||
|
@ -1121,7 +1121,7 @@ static bool isNonConstantNegative(const SCEVHandle &Expr) {
|
||||||
/// of the strided accesses, as well as the old information from Uses. We
|
/// of the strided accesses, as well as the old information from Uses. We
|
||||||
/// progressively move information from the Base field to the Imm field, until
|
/// progressively move information from the Base field to the Imm field, until
|
||||||
/// we eventually have the full access expression to rewrite the use.
|
/// we eventually have the full access expression to rewrite the use.
|
||||||
SCEVHandle LoopStrengthReduce::CollectIVUsers(const SCEVHandle &Stride,
|
const SCEV* LoopStrengthReduce::CollectIVUsers(const SCEV* const &Stride,
|
||||||
IVUsersOfOneStride &Uses,
|
IVUsersOfOneStride &Uses,
|
||||||
Loop *L,
|
Loop *L,
|
||||||
bool &AllUsesAreAddresses,
|
bool &AllUsesAreAddresses,
|
||||||
|
@ -1152,7 +1152,7 @@ SCEVHandle LoopStrengthReduce::CollectIVUsers(const SCEVHandle &Stride,
|
||||||
// for the strides (e.g. if we have "A+C+B" and "A+B+D" as our bases, find
|
// for the strides (e.g. if we have "A+C+B" and "A+B+D" as our bases, find
|
||||||
// "A+B"), emit it to the preheader, then remove the expression from the
|
// "A+B"), emit it to the preheader, then remove the expression from the
|
||||||
// UsersToProcess base values.
|
// UsersToProcess base values.
|
||||||
SCEVHandle CommonExprs =
|
const SCEV* CommonExprs =
|
||||||
RemoveCommonExpressionsFromUseBases(UsersToProcess, SE, L, TLI);
|
RemoveCommonExpressionsFromUseBases(UsersToProcess, SE, L, TLI);
|
||||||
|
|
||||||
// Next, figure out what we can represent in the immediate fields of
|
// Next, figure out what we can represent in the immediate fields of
|
||||||
|
@ -1218,7 +1218,7 @@ bool LoopStrengthReduce::ShouldUseFullStrengthReductionMode(
|
||||||
const std::vector<BasedUser> &UsersToProcess,
|
const std::vector<BasedUser> &UsersToProcess,
|
||||||
const Loop *L,
|
const Loop *L,
|
||||||
bool AllUsesAreAddresses,
|
bool AllUsesAreAddresses,
|
||||||
SCEVHandle Stride) {
|
const SCEV* Stride) {
|
||||||
if (!EnableFullLSRMode)
|
if (!EnableFullLSRMode)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1255,7 +1255,7 @@ bool LoopStrengthReduce::ShouldUseFullStrengthReductionMode(
|
||||||
if (!Imm) Imm = SE->getIntegerSCEV(0, Stride->getType());
|
if (!Imm) Imm = SE->getIntegerSCEV(0, Stride->getType());
|
||||||
const Instruction *Inst = UsersToProcess[i].Inst;
|
const Instruction *Inst = UsersToProcess[i].Inst;
|
||||||
const Type *AccessTy = getAccessType(Inst);
|
const Type *AccessTy = getAccessType(Inst);
|
||||||
SCEVHandle Diff = SE->getMinusSCEV(UsersToProcess[i].Imm, Imm);
|
const SCEV* Diff = SE->getMinusSCEV(UsersToProcess[i].Imm, Imm);
|
||||||
if (!Diff->isZero() &&
|
if (!Diff->isZero() &&
|
||||||
(!AllUsesAreAddresses ||
|
(!AllUsesAreAddresses ||
|
||||||
!fitsInAddressMode(Diff, AccessTy, TLI, /*HasBaseReg=*/true)))
|
!fitsInAddressMode(Diff, AccessTy, TLI, /*HasBaseReg=*/true)))
|
||||||
|
@ -1289,7 +1289,7 @@ bool LoopStrengthReduce::ShouldUseFullStrengthReductionMode(
|
||||||
///
|
///
|
||||||
/// Return the created phi node.
|
/// Return the created phi node.
|
||||||
///
|
///
|
||||||
static PHINode *InsertAffinePhi(SCEVHandle Start, SCEVHandle Step,
|
static PHINode *InsertAffinePhi(const SCEV* Start, const SCEV* Step,
|
||||||
Instruction *IVIncInsertPt,
|
Instruction *IVIncInsertPt,
|
||||||
const Loop *L,
|
const Loop *L,
|
||||||
SCEVExpander &Rewriter) {
|
SCEVExpander &Rewriter) {
|
||||||
|
@ -1309,7 +1309,7 @@ static PHINode *InsertAffinePhi(SCEVHandle Start, SCEVHandle Step,
|
||||||
// If the stride is negative, insert a sub instead of an add for the
|
// If the stride is negative, insert a sub instead of an add for the
|
||||||
// increment.
|
// increment.
|
||||||
bool isNegative = isNonConstantNegative(Step);
|
bool isNegative = isNonConstantNegative(Step);
|
||||||
SCEVHandle IncAmount = Step;
|
const SCEV* IncAmount = Step;
|
||||||
if (isNegative)
|
if (isNegative)
|
||||||
IncAmount = Rewriter.SE.getNegativeSCEV(Step);
|
IncAmount = Rewriter.SE.getNegativeSCEV(Step);
|
||||||
|
|
||||||
|
@ -1348,13 +1348,13 @@ static void SortUsersToProcess(std::vector<BasedUser> &UsersToProcess) {
|
||||||
// loop before users outside of the loop with a particular base.
|
// loop before users outside of the loop with a particular base.
|
||||||
//
|
//
|
||||||
// We would like to use stable_sort here, but we can't. The problem is that
|
// We would like to use stable_sort here, but we can't. The problem is that
|
||||||
// SCEVHandle's don't have a deterministic ordering w.r.t to each other, so
|
// const SCEV*'s don't have a deterministic ordering w.r.t to each other, so
|
||||||
// we don't have anything to do a '<' comparison on. Because we think the
|
// we don't have anything to do a '<' comparison on. Because we think the
|
||||||
// number of uses is small, do a horrible bubble sort which just relies on
|
// number of uses is small, do a horrible bubble sort which just relies on
|
||||||
// ==.
|
// ==.
|
||||||
for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
|
for (unsigned i = 0, e = UsersToProcess.size(); i != e; ++i) {
|
||||||
// Get a base value.
|
// Get a base value.
|
||||||
SCEVHandle Base = UsersToProcess[i].Base;
|
const SCEV* Base = UsersToProcess[i].Base;
|
||||||
|
|
||||||
// Compact everything with this base to be consecutive with this one.
|
// Compact everything with this base to be consecutive with this one.
|
||||||
for (unsigned j = i+1; j != e; ++j) {
|
for (unsigned j = i+1; j != e; ++j) {
|
||||||
|
@ -1373,8 +1373,8 @@ static void SortUsersToProcess(std::vector<BasedUser> &UsersToProcess) {
|
||||||
void
|
void
|
||||||
LoopStrengthReduce::PrepareToStrengthReduceFully(
|
LoopStrengthReduce::PrepareToStrengthReduceFully(
|
||||||
std::vector<BasedUser> &UsersToProcess,
|
std::vector<BasedUser> &UsersToProcess,
|
||||||
SCEVHandle Stride,
|
const SCEV* Stride,
|
||||||
SCEVHandle CommonExprs,
|
const SCEV* CommonExprs,
|
||||||
const Loop *L,
|
const Loop *L,
|
||||||
SCEVExpander &PreheaderRewriter) {
|
SCEVExpander &PreheaderRewriter) {
|
||||||
DOUT << " Fully reducing all users\n";
|
DOUT << " Fully reducing all users\n";
|
||||||
|
@ -1386,9 +1386,9 @@ LoopStrengthReduce::PrepareToStrengthReduceFully(
|
||||||
// TODO: The uses are grouped by base, but not sorted. We arbitrarily
|
// TODO: The uses are grouped by base, but not sorted. We arbitrarily
|
||||||
// pick the first Imm value here to start with, and adjust it for the
|
// pick the first Imm value here to start with, and adjust it for the
|
||||||
// other uses.
|
// other uses.
|
||||||
SCEVHandle Imm = UsersToProcess[i].Imm;
|
const SCEV* Imm = UsersToProcess[i].Imm;
|
||||||
SCEVHandle Base = UsersToProcess[i].Base;
|
const SCEV* Base = UsersToProcess[i].Base;
|
||||||
SCEVHandle Start = SE->getAddExpr(CommonExprs, Base, Imm);
|
const SCEV* Start = SE->getAddExpr(CommonExprs, Base, Imm);
|
||||||
PHINode *Phi = InsertAffinePhi(Start, Stride, IVIncInsertPt, L,
|
PHINode *Phi = InsertAffinePhi(Start, Stride, IVIncInsertPt, L,
|
||||||
PreheaderRewriter);
|
PreheaderRewriter);
|
||||||
// Loop over all the users with the same base.
|
// Loop over all the users with the same base.
|
||||||
|
@ -1420,8 +1420,8 @@ static Instruction *FindIVIncInsertPt(std::vector<BasedUser> &UsersToProcess,
|
||||||
void
|
void
|
||||||
LoopStrengthReduce::PrepareToStrengthReduceWithNewPhi(
|
LoopStrengthReduce::PrepareToStrengthReduceWithNewPhi(
|
||||||
std::vector<BasedUser> &UsersToProcess,
|
std::vector<BasedUser> &UsersToProcess,
|
||||||
SCEVHandle Stride,
|
const SCEV* Stride,
|
||||||
SCEVHandle CommonExprs,
|
const SCEV* CommonExprs,
|
||||||
Value *CommonBaseV,
|
Value *CommonBaseV,
|
||||||
Instruction *IVIncInsertPt,
|
Instruction *IVIncInsertPt,
|
||||||
const Loop *L,
|
const Loop *L,
|
||||||
|
@ -1497,7 +1497,7 @@ static bool IsImmFoldedIntoAddrMode(GlobalValue *GV, int64_t Offset,
|
||||||
/// StrengthReduceStridedIVUsers - Strength reduce all of the users of a single
|
/// StrengthReduceStridedIVUsers - Strength reduce all of the users of a single
|
||||||
/// stride of IV. All of the users may have different starting values, and this
|
/// stride of IV. All of the users may have different starting values, and this
|
||||||
/// may not be the only stride.
|
/// may not be the only stride.
|
||||||
void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEV* const &Stride,
|
||||||
IVUsersOfOneStride &Uses,
|
IVUsersOfOneStride &Uses,
|
||||||
Loop *L) {
|
Loop *L) {
|
||||||
// If all the users are moved to another stride, then there is nothing to do.
|
// If all the users are moved to another stride, then there is nothing to do.
|
||||||
|
@ -1520,7 +1520,7 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
||||||
// move information from the Base field to the Imm field, until we eventually
|
// move information from the Base field to the Imm field, until we eventually
|
||||||
// have the full access expression to rewrite the use.
|
// have the full access expression to rewrite the use.
|
||||||
std::vector<BasedUser> UsersToProcess;
|
std::vector<BasedUser> UsersToProcess;
|
||||||
SCEVHandle CommonExprs = CollectIVUsers(Stride, Uses, L, AllUsesAreAddresses,
|
const SCEV* CommonExprs = CollectIVUsers(Stride, Uses, L, AllUsesAreAddresses,
|
||||||
AllUsesAreOutsideLoop,
|
AllUsesAreOutsideLoop,
|
||||||
UsersToProcess);
|
UsersToProcess);
|
||||||
|
|
||||||
|
@ -1538,8 +1538,8 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
||||||
// If all uses are addresses, consider sinking the immediate part of the
|
// If all uses are addresses, consider sinking the immediate part of the
|
||||||
// common expression back into uses if they can fit in the immediate fields.
|
// common expression back into uses if they can fit in the immediate fields.
|
||||||
if (TLI && HaveCommonExprs && AllUsesAreAddresses) {
|
if (TLI && HaveCommonExprs && AllUsesAreAddresses) {
|
||||||
SCEVHandle NewCommon = CommonExprs;
|
const SCEV* NewCommon = CommonExprs;
|
||||||
SCEVHandle Imm = SE->getIntegerSCEV(0, ReplacedTy);
|
const SCEV* Imm = SE->getIntegerSCEV(0, ReplacedTy);
|
||||||
MoveImmediateValues(TLI, Type::VoidTy, NewCommon, Imm, true, L, SE);
|
MoveImmediateValues(TLI, Type::VoidTy, NewCommon, Imm, true, L, SE);
|
||||||
if (!Imm->isZero()) {
|
if (!Imm->isZero()) {
|
||||||
bool DoSink = true;
|
bool DoSink = true;
|
||||||
|
@ -1585,7 +1585,7 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
||||||
|
|
||||||
Value *CommonBaseV = Constant::getNullValue(ReplacedTy);
|
Value *CommonBaseV = Constant::getNullValue(ReplacedTy);
|
||||||
|
|
||||||
SCEVHandle RewriteFactor = SE->getIntegerSCEV(0, ReplacedTy);
|
const SCEV* RewriteFactor = SE->getIntegerSCEV(0, ReplacedTy);
|
||||||
IVExpr ReuseIV(SE->getIntegerSCEV(0, Type::Int32Ty),
|
IVExpr ReuseIV(SE->getIntegerSCEV(0, Type::Int32Ty),
|
||||||
SE->getIntegerSCEV(0, Type::Int32Ty),
|
SE->getIntegerSCEV(0, Type::Int32Ty),
|
||||||
0);
|
0);
|
||||||
|
@ -1625,7 +1625,7 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
||||||
// strength-reduced forms. This outer loop handles all bases, the inner
|
// strength-reduced forms. This outer loop handles all bases, the inner
|
||||||
// loop handles all users of a particular base.
|
// loop handles all users of a particular base.
|
||||||
while (!UsersToProcess.empty()) {
|
while (!UsersToProcess.empty()) {
|
||||||
SCEVHandle Base = UsersToProcess.back().Base;
|
const SCEV* Base = UsersToProcess.back().Base;
|
||||||
Instruction *Inst = UsersToProcess.back().Inst;
|
Instruction *Inst = UsersToProcess.back().Inst;
|
||||||
|
|
||||||
// Emit the code for Base into the preheader.
|
// Emit the code for Base into the preheader.
|
||||||
|
@ -1679,7 +1679,7 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
||||||
User.Inst->moveBefore(IVIncInsertPt);
|
User.Inst->moveBefore(IVIncInsertPt);
|
||||||
}
|
}
|
||||||
|
|
||||||
SCEVHandle RewriteExpr = SE->getUnknown(RewriteOp);
|
const SCEV* RewriteExpr = SE->getUnknown(RewriteOp);
|
||||||
|
|
||||||
if (SE->getEffectiveSCEVType(RewriteOp->getType()) !=
|
if (SE->getEffectiveSCEVType(RewriteOp->getType()) !=
|
||||||
SE->getEffectiveSCEVType(ReplacedTy)) {
|
SE->getEffectiveSCEVType(ReplacedTy)) {
|
||||||
|
@ -1711,7 +1711,7 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
||||||
// The base has been used to initialize the PHI node but we don't want
|
// The base has been used to initialize the PHI node but we don't want
|
||||||
// it here.
|
// it here.
|
||||||
if (!ReuseIV.Base->isZero()) {
|
if (!ReuseIV.Base->isZero()) {
|
||||||
SCEVHandle typedBase = ReuseIV.Base;
|
const SCEV* typedBase = ReuseIV.Base;
|
||||||
if (SE->getEffectiveSCEVType(RewriteExpr->getType()) !=
|
if (SE->getEffectiveSCEVType(RewriteExpr->getType()) !=
|
||||||
SE->getEffectiveSCEVType(ReuseIV.Base->getType())) {
|
SE->getEffectiveSCEVType(ReuseIV.Base->getType())) {
|
||||||
// It's possible the original IV is a larger type than the new IV,
|
// It's possible the original IV is a larger type than the new IV,
|
||||||
|
@ -1776,10 +1776,10 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
|
||||||
/// set the IV user and stride information and return true, otherwise return
|
/// set the IV user and stride information and return true, otherwise return
|
||||||
/// false.
|
/// false.
|
||||||
bool LoopStrengthReduce::FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
|
bool LoopStrengthReduce::FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
|
||||||
const SCEVHandle *&CondStride) {
|
const SCEV* const * &CondStride) {
|
||||||
for (unsigned Stride = 0, e = IU->StrideOrder.size();
|
for (unsigned Stride = 0, e = IU->StrideOrder.size();
|
||||||
Stride != e && !CondUse; ++Stride) {
|
Stride != e && !CondUse; ++Stride) {
|
||||||
std::map<SCEVHandle, IVUsersOfOneStride *>::iterator SI =
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator SI =
|
||||||
IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
|
IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
|
||||||
assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
|
assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
|
||||||
|
|
||||||
|
@ -1806,7 +1806,7 @@ namespace {
|
||||||
const ScalarEvolution *SE;
|
const ScalarEvolution *SE;
|
||||||
explicit StrideCompare(const ScalarEvolution *se) : SE(se) {}
|
explicit StrideCompare(const ScalarEvolution *se) : SE(se) {}
|
||||||
|
|
||||||
bool operator()(const SCEVHandle &LHS, const SCEVHandle &RHS) {
|
bool operator()(const SCEV* const &LHS, const SCEV* const &RHS) {
|
||||||
const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS);
|
const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS);
|
||||||
const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS);
|
const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS);
|
||||||
if (LHSC && RHSC) {
|
if (LHSC && RHSC) {
|
||||||
|
@ -1849,14 +1849,14 @@ namespace {
|
||||||
/// if (v1 < 30) goto loop
|
/// if (v1 < 30) goto loop
|
||||||
ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
||||||
IVStrideUse* &CondUse,
|
IVStrideUse* &CondUse,
|
||||||
const SCEVHandle* &CondStride) {
|
const SCEV* const* &CondStride) {
|
||||||
// If there's only one stride in the loop, there's nothing to do here.
|
// If there's only one stride in the loop, there's nothing to do here.
|
||||||
if (IU->StrideOrder.size() < 2)
|
if (IU->StrideOrder.size() < 2)
|
||||||
return Cond;
|
return Cond;
|
||||||
// If there are other users of the condition's stride, don't bother
|
// If there are other users of the condition's stride, don't bother
|
||||||
// trying to change the condition because the stride will still
|
// trying to change the condition because the stride will still
|
||||||
// remain.
|
// remain.
|
||||||
std::map<SCEVHandle, IVUsersOfOneStride *>::iterator I =
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator I =
|
||||||
IU->IVUsesByStride.find(*CondStride);
|
IU->IVUsesByStride.find(*CondStride);
|
||||||
if (I == IU->IVUsesByStride.end() ||
|
if (I == IU->IVUsesByStride.end() ||
|
||||||
I->second->Users.size() != 1)
|
I->second->Users.size() != 1)
|
||||||
|
@ -1873,11 +1873,11 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
||||||
const Type *NewCmpTy = NULL;
|
const Type *NewCmpTy = NULL;
|
||||||
unsigned TyBits = SE->getTypeSizeInBits(CmpTy);
|
unsigned TyBits = SE->getTypeSizeInBits(CmpTy);
|
||||||
unsigned NewTyBits = 0;
|
unsigned NewTyBits = 0;
|
||||||
SCEVHandle *NewStride = NULL;
|
const SCEV* *NewStride = NULL;
|
||||||
Value *NewCmpLHS = NULL;
|
Value *NewCmpLHS = NULL;
|
||||||
Value *NewCmpRHS = NULL;
|
Value *NewCmpRHS = NULL;
|
||||||
int64_t Scale = 1;
|
int64_t Scale = 1;
|
||||||
SCEVHandle NewOffset = SE->getIntegerSCEV(0, CmpTy);
|
const SCEV* NewOffset = SE->getIntegerSCEV(0, CmpTy);
|
||||||
|
|
||||||
if (ConstantInt *C = dyn_cast<ConstantInt>(Cond->getOperand(1))) {
|
if (ConstantInt *C = dyn_cast<ConstantInt>(Cond->getOperand(1))) {
|
||||||
int64_t CmpVal = C->getValue().getSExtValue();
|
int64_t CmpVal = C->getValue().getSExtValue();
|
||||||
|
@ -1889,7 +1889,7 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
||||||
|
|
||||||
// Look for a suitable stride / iv as replacement.
|
// Look for a suitable stride / iv as replacement.
|
||||||
for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
|
for (unsigned i = 0, e = IU->StrideOrder.size(); i != e; ++i) {
|
||||||
std::map<SCEVHandle, IVUsersOfOneStride *>::iterator SI =
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator SI =
|
||||||
IU->IVUsesByStride.find(IU->StrideOrder[i]);
|
IU->IVUsesByStride.find(IU->StrideOrder[i]);
|
||||||
if (!isa<SCEVConstant>(SI->first))
|
if (!isa<SCEVConstant>(SI->first))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1969,7 +1969,7 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
||||||
bool AllUsesAreAddresses = true;
|
bool AllUsesAreAddresses = true;
|
||||||
bool AllUsesAreOutsideLoop = true;
|
bool AllUsesAreOutsideLoop = true;
|
||||||
std::vector<BasedUser> UsersToProcess;
|
std::vector<BasedUser> UsersToProcess;
|
||||||
SCEVHandle CommonExprs = CollectIVUsers(SI->first, *SI->second, L,
|
const SCEV* CommonExprs = CollectIVUsers(SI->first, *SI->second, L,
|
||||||
AllUsesAreAddresses,
|
AllUsesAreAddresses,
|
||||||
AllUsesAreOutsideLoop,
|
AllUsesAreOutsideLoop,
|
||||||
UsersToProcess);
|
UsersToProcess);
|
||||||
|
@ -2104,13 +2104,13 @@ ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
|
||||||
SelectInst *Sel = dyn_cast<SelectInst>(Cond->getOperand(1));
|
SelectInst *Sel = dyn_cast<SelectInst>(Cond->getOperand(1));
|
||||||
if (!Sel || !Sel->hasOneUse()) return Cond;
|
if (!Sel || !Sel->hasOneUse()) return Cond;
|
||||||
|
|
||||||
SCEVHandle BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
const SCEV* BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
||||||
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
|
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
|
||||||
return Cond;
|
return Cond;
|
||||||
SCEVHandle One = SE->getIntegerSCEV(1, BackedgeTakenCount->getType());
|
const SCEV* One = SE->getIntegerSCEV(1, BackedgeTakenCount->getType());
|
||||||
|
|
||||||
// Add one to the backedge-taken count to get the trip count.
|
// Add one to the backedge-taken count to get the trip count.
|
||||||
SCEVHandle IterationCount = SE->getAddExpr(BackedgeTakenCount, One);
|
const SCEV* IterationCount = SE->getAddExpr(BackedgeTakenCount, One);
|
||||||
|
|
||||||
// Check for a max calculation that matches the pattern.
|
// Check for a max calculation that matches the pattern.
|
||||||
if (!isa<SCEVSMaxExpr>(IterationCount) && !isa<SCEVUMaxExpr>(IterationCount))
|
if (!isa<SCEVSMaxExpr>(IterationCount) && !isa<SCEVUMaxExpr>(IterationCount))
|
||||||
|
@ -2123,13 +2123,13 @@ ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
|
||||||
if (Max->getNumOperands() != 2)
|
if (Max->getNumOperands() != 2)
|
||||||
return Cond;
|
return Cond;
|
||||||
|
|
||||||
SCEVHandle MaxLHS = Max->getOperand(0);
|
const SCEV* MaxLHS = Max->getOperand(0);
|
||||||
SCEVHandle MaxRHS = Max->getOperand(1);
|
const SCEV* MaxRHS = Max->getOperand(1);
|
||||||
if (!MaxLHS || MaxLHS != One) return Cond;
|
if (!MaxLHS || MaxLHS != One) return Cond;
|
||||||
|
|
||||||
// Check the relevant induction variable for conformance to
|
// Check the relevant induction variable for conformance to
|
||||||
// the pattern.
|
// the pattern.
|
||||||
SCEVHandle IV = SE->getSCEV(Cond->getOperand(0));
|
const SCEV* IV = SE->getSCEV(Cond->getOperand(0));
|
||||||
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(IV);
|
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(IV);
|
||||||
if (!AR || !AR->isAffine() ||
|
if (!AR || !AR->isAffine() ||
|
||||||
AR->getStart() != One ||
|
AR->getStart() != One ||
|
||||||
|
@ -2175,13 +2175,13 @@ ICmpInst *LoopStrengthReduce::OptimizeMax(Loop *L, ICmpInst *Cond,
|
||||||
/// inside the loop then try to eliminate the cast opeation.
|
/// inside the loop then try to eliminate the cast opeation.
|
||||||
void LoopStrengthReduce::OptimizeShadowIV(Loop *L) {
|
void LoopStrengthReduce::OptimizeShadowIV(Loop *L) {
|
||||||
|
|
||||||
SCEVHandle BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
const SCEV* BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
||||||
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
|
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (unsigned Stride = 0, e = IU->StrideOrder.size(); Stride != e;
|
for (unsigned Stride = 0, e = IU->StrideOrder.size(); Stride != e;
|
||||||
++Stride) {
|
++Stride) {
|
||||||
std::map<SCEVHandle, IVUsersOfOneStride *>::iterator SI =
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator SI =
|
||||||
IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
|
IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
|
||||||
assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
|
assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
|
||||||
if (!isa<SCEVConstant>(SI->first))
|
if (!isa<SCEVConstant>(SI->first))
|
||||||
|
@ -2311,7 +2311,7 @@ void LoopStrengthReduce::OptimizeLoopTermCond(Loop *L) {
|
||||||
|
|
||||||
// Search IVUsesByStride to find Cond's IVUse if there is one.
|
// Search IVUsesByStride to find Cond's IVUse if there is one.
|
||||||
IVStrideUse *CondUse = 0;
|
IVStrideUse *CondUse = 0;
|
||||||
const SCEVHandle *CondStride = 0;
|
const SCEV* const *CondStride = 0;
|
||||||
ICmpInst *Cond = cast<ICmpInst>(TermBr->getCondition());
|
ICmpInst *Cond = cast<ICmpInst>(TermBr->getCondition());
|
||||||
if (!FindIVUserForCond(Cond, CondUse, CondStride))
|
if (!FindIVUserForCond(Cond, CondUse, CondStride))
|
||||||
return; // setcc doesn't use the IV.
|
return; // setcc doesn't use the IV.
|
||||||
|
@ -2341,7 +2341,7 @@ void LoopStrengthReduce::OptimizeLoopTermCond(Loop *L) {
|
||||||
int64_t SInt = SC->getValue()->getSExtValue();
|
int64_t SInt = SC->getValue()->getSExtValue();
|
||||||
for (unsigned NewStride = 0, ee = IU->StrideOrder.size(); NewStride != ee;
|
for (unsigned NewStride = 0, ee = IU->StrideOrder.size(); NewStride != ee;
|
||||||
++NewStride) {
|
++NewStride) {
|
||||||
std::map<SCEVHandle, IVUsersOfOneStride *>::iterator SI =
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator SI =
|
||||||
IU->IVUsesByStride.find(IU->StrideOrder[NewStride]);
|
IU->IVUsesByStride.find(IU->StrideOrder[NewStride]);
|
||||||
if (!isa<SCEVConstant>(SI->first) || SI->first == *CondStride)
|
if (!isa<SCEVConstant>(SI->first) || SI->first == *CondStride)
|
||||||
continue;
|
continue;
|
||||||
|
@ -2355,7 +2355,7 @@ void LoopStrengthReduce::OptimizeLoopTermCond(Loop *L) {
|
||||||
bool AllUsesAreAddresses = true;
|
bool AllUsesAreAddresses = true;
|
||||||
bool AllUsesAreOutsideLoop = true;
|
bool AllUsesAreOutsideLoop = true;
|
||||||
std::vector<BasedUser> UsersToProcess;
|
std::vector<BasedUser> UsersToProcess;
|
||||||
SCEVHandle CommonExprs = CollectIVUsers(SI->first, *SI->second, L,
|
const SCEV* CommonExprs = CollectIVUsers(SI->first, *SI->second, L,
|
||||||
AllUsesAreAddresses,
|
AllUsesAreAddresses,
|
||||||
AllUsesAreOutsideLoop,
|
AllUsesAreOutsideLoop,
|
||||||
UsersToProcess);
|
UsersToProcess);
|
||||||
|
@ -2416,7 +2416,7 @@ void LoopStrengthReduce::OptimizeLoopTermCond(Loop *L) {
|
||||||
void LoopStrengthReduce::OptimizeLoopCountIV(Loop *L) {
|
void LoopStrengthReduce::OptimizeLoopCountIV(Loop *L) {
|
||||||
|
|
||||||
// If the number of times the loop is executed isn't computable, give up.
|
// If the number of times the loop is executed isn't computable, give up.
|
||||||
SCEVHandle BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
const SCEV* BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
||||||
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
|
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -2445,9 +2445,9 @@ void LoopStrengthReduce::OptimizeLoopCountIV(Loop *L) {
|
||||||
// Handle only tests for equality for the moment, and only stride 1.
|
// Handle only tests for equality for the moment, and only stride 1.
|
||||||
if (Cond->getPredicate() != CmpInst::ICMP_EQ)
|
if (Cond->getPredicate() != CmpInst::ICMP_EQ)
|
||||||
return;
|
return;
|
||||||
SCEVHandle IV = SE->getSCEV(Cond->getOperand(0));
|
const SCEV* IV = SE->getSCEV(Cond->getOperand(0));
|
||||||
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(IV);
|
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(IV);
|
||||||
SCEVHandle One = SE->getIntegerSCEV(1, BackedgeTakenCount->getType());
|
const SCEV* One = SE->getIntegerSCEV(1, BackedgeTakenCount->getType());
|
||||||
if (!AR || !AR->isAffine() || AR->getStepRecurrence(*SE) != One)
|
if (!AR || !AR->isAffine() || AR->getStepRecurrence(*SE) != One)
|
||||||
return;
|
return;
|
||||||
// If the RHS of the comparison is defined inside the loop, the rewrite
|
// If the RHS of the comparison is defined inside the loop, the rewrite
|
||||||
|
@ -2563,7 +2563,7 @@ bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||||
// strides deterministic - not dependent on map order.
|
// strides deterministic - not dependent on map order.
|
||||||
for (unsigned Stride = 0, e = IU->StrideOrder.size();
|
for (unsigned Stride = 0, e = IU->StrideOrder.size();
|
||||||
Stride != e; ++Stride) {
|
Stride != e; ++Stride) {
|
||||||
std::map<SCEVHandle, IVUsersOfOneStride *>::iterator SI =
|
std::map<const SCEV*, IVUsersOfOneStride *>::iterator SI =
|
||||||
IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
|
IU->IVUsesByStride.find(IU->StrideOrder[Stride]);
|
||||||
assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
|
assert(SI != IU->IVUsesByStride.end() && "Stride doesn't exist!");
|
||||||
// FIXME: Generalize to non-affine IV's.
|
// FIXME: Generalize to non-affine IV's.
|
||||||
|
|
Loading…
Reference in New Issue