File indexing completed on 2026-05-10 08:48:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef POLLY_SUPPORT_VIRTUALINSTRUCTION_H
0015 #define POLLY_SUPPORT_VIRTUALINSTRUCTION_H
0016
0017 #include "polly/ScopInfo.h"
0018
0019 namespace polly {
0020 using llvm::User;
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 class VirtualUse final {
0032 public:
0033
0034
0035
0036 enum UseKind {
0037
0038 Constant,
0039
0040
0041 Block,
0042
0043
0044 Synthesizable,
0045
0046
0047
0048
0049 Hoisted,
0050
0051
0052
0053
0054
0055 ReadOnly,
0056
0057
0058
0059 Intra,
0060
0061
0062
0063 Inter
0064 };
0065
0066 private:
0067
0068 ScopStmt *User;
0069
0070
0071 Value *Val;
0072
0073
0074 UseKind Kind;
0075
0076
0077 const SCEV *ScevExpr;
0078
0079
0080
0081
0082
0083 MemoryAccess *InputMA;
0084
0085 VirtualUse(ScopStmt *User, Value *Val, UseKind Kind, const SCEV *ScevExpr,
0086 MemoryAccess *InputMA)
0087 : User(User), Val(Val), Kind(Kind), ScevExpr(ScevExpr), InputMA(InputMA) {
0088 }
0089
0090 public:
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 static VirtualUse create(Scop *S, const Use &U, LoopInfo *LI, bool Virtual);
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 static VirtualUse create(Scop *S, ScopStmt *UserStmt, Loop *UserScope,
0122 Value *Val, bool Virtual);
0123
0124 static VirtualUse create(ScopStmt *UserStmt, Loop *UserScope, Value *Val,
0125 bool Virtual) {
0126 return create(UserStmt->getParent(), UserStmt, UserScope, Val, Virtual);
0127 }
0128
0129 bool isConstant() const { return Kind == Constant; }
0130 bool isBlock() const { return Kind == Block; }
0131 bool isSynthesizable() const { return Kind == Synthesizable; }
0132 bool isHoisted() const { return Kind == Hoisted; }
0133 bool isReadOnly() const { return Kind == ReadOnly; }
0134 bool isIntra() const { return Kind == Intra; }
0135 bool isInter() const { return Kind == Inter; }
0136
0137
0138 ScopStmt *getUser() const { return User; }
0139
0140
0141 llvm::Value *getValue() const { return Val; }
0142
0143
0144 UseKind getKind() const { return Kind; }
0145
0146
0147 const SCEV *getScevExpr() const { return ScevExpr; }
0148
0149
0150
0151 MemoryAccess *getMemoryAccess() const { return InputMA; }
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162 void print(raw_ostream &OS, bool Reproducible = true) const;
0163
0164 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0165 void dump() const;
0166 #endif
0167 };
0168
0169
0170 class VirtualOperandIterator final {
0171 friend class VirtualInstruction;
0172 friend class VirtualUse;
0173
0174 using Self = VirtualOperandIterator;
0175
0176 ScopStmt *User;
0177 User::op_iterator U;
0178
0179 VirtualOperandIterator(ScopStmt *User, User::op_iterator U)
0180 : User(User), U(U) {}
0181
0182 public:
0183 using iterator_category = std::forward_iterator_tag;
0184 using value_type = VirtualUse;
0185 using difference_type = std::ptrdiff_t;
0186 using pointer = value_type *;
0187 using reference = value_type &;
0188
0189 inline bool operator==(const Self &that) const {
0190 assert(this->User == that.User);
0191 return this->U == that.U;
0192 }
0193
0194 inline bool operator!=(const Self &that) const {
0195 assert(this->User == that.User);
0196 return this->U != that.U;
0197 }
0198
0199 VirtualUse operator*() const {
0200 return VirtualUse::create(User, User->getSurroundingLoop(), U->get(), true);
0201 }
0202
0203 Use *operator->() const { return U; }
0204
0205 Self &operator++() {
0206 U++;
0207 return *this;
0208 }
0209
0210 Self operator++(int) {
0211 Self tmp = *this;
0212 ++*this;
0213 return tmp;
0214 }
0215 };
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231 class VirtualInstruction final {
0232 friend class VirtualOperandIterator;
0233 friend struct llvm::DenseMapInfo<VirtualInstruction>;
0234
0235 private:
0236
0237 ScopStmt *Stmt = nullptr;
0238
0239
0240 Instruction *Inst = nullptr;
0241
0242 public:
0243 VirtualInstruction() {}
0244
0245
0246 VirtualInstruction(ScopStmt *Stmt, Instruction *Inst)
0247 : Stmt(Stmt), Inst(Inst) {
0248 assert(Stmt && Inst);
0249 }
0250
0251 VirtualOperandIterator operand_begin() const {
0252 return VirtualOperandIterator(Stmt, Inst->op_begin());
0253 }
0254
0255 VirtualOperandIterator operand_end() const {
0256 return VirtualOperandIterator(Stmt, Inst->op_end());
0257 }
0258
0259
0260
0261
0262
0263 llvm::iterator_range<VirtualOperandIterator> operands() const {
0264 return {operand_begin(), operand_end()};
0265 }
0266
0267
0268 Scop *getScop() const { return Stmt->getParent(); }
0269
0270
0271 ScopStmt *getStmt() const { return Stmt; }
0272
0273
0274 Instruction *getInstruction() const { return Inst; }
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285 void print(raw_ostream &OS, bool Reproducible = true) const;
0286
0287 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0288 void dump() const;
0289 #endif
0290 };
0291
0292 static inline bool operator==(VirtualInstruction LHS, VirtualInstruction RHS) {
0293 return LHS.getStmt() == RHS.getStmt() &&
0294 LHS.getInstruction() == RHS.getInstruction();
0295 }
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307 void markReachable(Scop *S, LoopInfo *LI,
0308 DenseSet<VirtualInstruction> &UsedInsts,
0309 DenseSet<MemoryAccess *> &UsedAccs,
0310 ScopStmt *OnlyLocal = nullptr);
0311 }
0312
0313 namespace llvm {
0314
0315 template <> struct DenseMapInfo<polly::VirtualInstruction> {
0316 public:
0317 static bool isEqual(polly::VirtualInstruction LHS,
0318 polly::VirtualInstruction RHS) {
0319 return DenseMapInfo<polly::ScopStmt *>::isEqual(LHS.getStmt(),
0320 RHS.getStmt()) &&
0321 DenseMapInfo<Instruction *>::isEqual(LHS.getInstruction(),
0322 RHS.getInstruction());
0323 }
0324
0325 static polly::VirtualInstruction getTombstoneKey() {
0326 polly::VirtualInstruction TombstoneKey;
0327 TombstoneKey.Stmt = DenseMapInfo<polly::ScopStmt *>::getTombstoneKey();
0328 TombstoneKey.Inst = DenseMapInfo<Instruction *>::getTombstoneKey();
0329 return TombstoneKey;
0330 }
0331
0332 static polly::VirtualInstruction getEmptyKey() {
0333 polly::VirtualInstruction EmptyKey;
0334 EmptyKey.Stmt = DenseMapInfo<polly::ScopStmt *>::getEmptyKey();
0335 EmptyKey.Inst = DenseMapInfo<Instruction *>::getEmptyKey();
0336 return EmptyKey;
0337 }
0338
0339 static unsigned getHashValue(polly::VirtualInstruction Val) {
0340 return DenseMapInfo<std::pair<polly::ScopStmt *, Instruction *>>::
0341 getHashValue(std::make_pair(Val.getStmt(), Val.getInstruction()));
0342 }
0343 };
0344 }
0345
0346 #endif