#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
namespace llvm {
+class AssumptionCache;
class DominatorTree;
class Instruction;
class Value;
-class IVUsers;
class ScalarEvolution;
class SCEV;
-class SCEVAddRecExpr;
class IVUsers;
+class DataLayout;
/// IVStrideUse - Keep track of one use of a strided induction variable.
/// The Expr member keeps track of the expression, User is the actual user
/// Deleted - Implementation of CallbackVH virtual function to
/// receive notification when the User is deleted.
- virtual void deleted();
+ void deleted() override;
};
template<> struct ilist_traits<IVStrideUse>
class IVUsers : public LoopPass {
friend class IVStrideUse;
Loop *L;
+ AssumptionCache *AC;
LoopInfo *LI;
DominatorTree *DT;
ScalarEvolution *SE;
- SmallPtrSet<Instruction *, 16> Processed;
+ SmallPtrSet<Instruction*, 16> Processed;
/// IVUses - A list of all tracked IV uses of induction variable expressions
/// we are interested in.
ilist<IVStrideUse> IVUses;
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ // Ephemeral values used by @llvm.assume in this function.
+ SmallPtrSet<const Value *, 32> EphValues;
- virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
- virtual void releaseMemory();
+ bool runOnLoop(Loop *L, LPPassManager &LPM) override;
- const SCEVAddRecExpr *findInterestingAddRec(const SCEV *S) const;
- bool isInterestingUser(const Instruction *User) const;
+ void releaseMemory() override;
public:
static char ID; // Pass ID, replacement for typeid
IVUsers();
- /// AddUsersIfInteresting - Inspect the def-use graph starting at the
- /// specified Instruction and add IVUsers.
- void AddUsersIfInteresting(Instruction *I);
+ Loop *getLoop() const { return L; }
+
+ /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a
+ /// reducible SCEV, recursively add its users to the IVUsesByStride set and
+ /// return true. Otherwise, return false.
+ bool AddUsersIfInteresting(Instruction *I);
IVStrideUse &AddUser(Instruction *User, Value *Operand);
const_iterator end() const { return IVUses.end(); }
bool empty() const { return IVUses.empty(); }
- void print(raw_ostream &OS, const Module* = 0) const;
+ bool isIVUserOrOperand(Instruction *Inst) const {
+ return Processed.count(Inst);
+ }
+
+ void print(raw_ostream &OS, const Module* = nullptr) const override;
/// dump - This method is used for debugging.
void dump() const;
+protected:
+ bool AddUsersImpl(Instruction *I, SmallPtrSetImpl<Loop*> &SimpleLoopNests);
};
Pass *createIVUsersPass();