SCEVHandle is no more!

llvm-svn: 73906
This commit is contained in:
Owen Anderson 2009-06-22 21:39:50 +00:00
parent 482495695e
commit 65b6056e37
12 changed files with 567 additions and 640 deletions

View File

@ -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;

View File

@ -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;
}; };

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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";

View File

@ -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

View File

@ -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);
} }

View File

@ -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)) {

View File

@ -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;

View File

@ -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.