File indexing completed on 2026-05-10 08:43:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_ANALYSIS_IVUSERS_H
0015 #define LLVM_ANALYSIS_IVUSERS_H
0016
0017 #include "llvm/Analysis/LoopAnalysisManager.h"
0018 #include "llvm/Analysis/LoopPass.h"
0019 #include "llvm/Analysis/ScalarEvolutionNormalization.h"
0020 #include "llvm/IR/Instruction.h"
0021 #include "llvm/IR/ValueHandle.h"
0022
0023 namespace llvm {
0024
0025 class AssumptionCache;
0026 class DominatorTree;
0027 class ScalarEvolution;
0028 class SCEV;
0029 class IVUsers;
0030
0031
0032
0033
0034
0035 class IVStrideUse final : public CallbackVH, public ilist_node<IVStrideUse> {
0036 friend class IVUsers;
0037 public:
0038 IVStrideUse(IVUsers *P, Instruction* U, Value *O)
0039 : CallbackVH(U), Parent(P), OperandValToReplace(O) {
0040 }
0041
0042
0043 Instruction *getUser() const {
0044 return cast<Instruction>(getValPtr());
0045 }
0046
0047
0048 void setUser(Instruction *NewUser) {
0049 setValPtr(NewUser);
0050 }
0051
0052
0053
0054 Value *getOperandValToReplace() const {
0055 return OperandValToReplace;
0056 }
0057
0058
0059
0060 void setOperandValToReplace(Value *Op) {
0061 OperandValToReplace = Op;
0062 }
0063
0064
0065
0066 const PostIncLoopSet &getPostIncLoops() const {
0067 return PostIncLoops;
0068 }
0069
0070
0071
0072 void transformToPostInc(const Loop *L);
0073
0074 private:
0075
0076 IVUsers *Parent;
0077
0078
0079
0080 WeakTrackingVH OperandValToReplace;
0081
0082
0083
0084 PostIncLoopSet PostIncLoops;
0085
0086
0087
0088 void deleted() override;
0089 };
0090
0091 class IVUsers {
0092 friend class IVStrideUse;
0093 Loop *L;
0094 AssumptionCache *AC;
0095 LoopInfo *LI;
0096 DominatorTree *DT;
0097 ScalarEvolution *SE;
0098 SmallPtrSet<Instruction*, 16> Processed;
0099
0100
0101
0102 ilist<IVStrideUse> IVUses;
0103
0104
0105 SmallPtrSet<const Value *, 32> EphValues;
0106
0107 public:
0108 IVUsers(Loop *L, AssumptionCache *AC, LoopInfo *LI, DominatorTree *DT,
0109 ScalarEvolution *SE);
0110
0111 IVUsers(IVUsers &&X)
0112 : L(std::move(X.L)), AC(std::move(X.AC)), DT(std::move(X.DT)),
0113 SE(std::move(X.SE)), Processed(std::move(X.Processed)),
0114 IVUses(std::move(X.IVUses)), EphValues(std::move(X.EphValues)) {
0115 for (IVStrideUse &U : IVUses)
0116 U.Parent = this;
0117 }
0118 IVUsers(const IVUsers &) = delete;
0119 IVUsers &operator=(IVUsers &&) = delete;
0120 IVUsers &operator=(const IVUsers &) = delete;
0121
0122 Loop *getLoop() const { return L; }
0123
0124
0125
0126
0127 bool AddUsersIfInteresting(Instruction *I);
0128
0129 IVStrideUse &AddUser(Instruction *User, Value *Operand);
0130
0131
0132
0133 const SCEV *getReplacementExpr(const IVStrideUse &IU) const;
0134
0135
0136
0137 const SCEV *getExpr(const IVStrideUse &IU) const;
0138
0139 const SCEV *getStride(const IVStrideUse &IU, const Loop *L) const;
0140
0141 typedef ilist<IVStrideUse>::iterator iterator;
0142 typedef ilist<IVStrideUse>::const_iterator const_iterator;
0143 iterator begin() { return IVUses.begin(); }
0144 iterator end() { return IVUses.end(); }
0145 const_iterator begin() const { return IVUses.begin(); }
0146 const_iterator end() const { return IVUses.end(); }
0147 bool empty() const { return IVUses.empty(); }
0148
0149 bool isIVUserOrOperand(Instruction *Inst) const {
0150 return Processed.count(Inst);
0151 }
0152
0153 void releaseMemory();
0154
0155 void print(raw_ostream &OS, const Module * = nullptr) const;
0156
0157
0158 void dump() const;
0159 };
0160
0161 Pass *createIVUsersPass();
0162
0163 class IVUsersWrapperPass : public LoopPass {
0164 std::unique_ptr<IVUsers> IU;
0165
0166 public:
0167 static char ID;
0168
0169 IVUsersWrapperPass();
0170
0171 IVUsers &getIU() { return *IU; }
0172 const IVUsers &getIU() const { return *IU; }
0173
0174 void getAnalysisUsage(AnalysisUsage &AU) const override;
0175
0176 bool runOnLoop(Loop *L, LPPassManager &LPM) override;
0177
0178 void releaseMemory() override;
0179
0180 void print(raw_ostream &OS, const Module * = nullptr) const override;
0181 };
0182
0183
0184 class IVUsersAnalysis : public AnalysisInfoMixin<IVUsersAnalysis> {
0185 friend AnalysisInfoMixin<IVUsersAnalysis>;
0186 static AnalysisKey Key;
0187
0188 public:
0189 typedef IVUsers Result;
0190
0191 IVUsers run(Loop &L, LoopAnalysisManager &AM,
0192 LoopStandardAnalysisResults &AR);
0193 };
0194
0195 }
0196
0197 #endif