1 //===------ VirtualInstruction.cpp ------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Tools for determining which instructions are within a statement and the 10 // nature of their operands. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef POLLY_SUPPORT_VIRTUALINSTRUCTION_H 15 #define POLLY_SUPPORT_VIRTUALINSTRUCTION_H 16 17 #include "polly/ScopInfo.h" 18 19 namespace polly { 20 using llvm::User; 21 22 /// Determine the nature of a value's use within a statement. 23 /// 24 /// These are not always representable by llvm::Use. For instance, scalar write 25 /// MemoryAccesses do use a value, but are not associated with an instruction's 26 /// argument. 27 /// 28 /// Despite its name it is not tied to virtual instructions (although it works 29 /// fine with them), but to promote consistent handling of values used in 30 /// statements. 31 class VirtualUse { 32 public: 33 /// The different types of uses. Handling usually differentiates a lot between 34 /// these; one can use a switch to handle each case (and get warned by the 35 /// compiler if one is not handled). 36 enum UseKind { 37 // An llvm::Constant. 38 Constant, 39 40 // An llvm::BasicBlock. 41 Block, 42 43 // A value that can be generated using ScopExpander. 44 Synthesizable, 45 46 // A load that always reads the same value throughout the SCoP (address and 47 // the value located there a SCoP-invariant) and has been hoisted in front 48 // of the SCoP. 49 Hoisted, 50 51 // Definition before the SCoP and not synthesizable. Can be an instruction 52 // outside the SCoP, a function argument or a global value. Whether there is 53 // a scalar MemoryAccess in this statement for reading it depends on the 54 // -polly-analyze-read-only-scalars switch. 55 ReadOnly, 56 57 // A definition within the same statement. No MemoryAccess between 58 // definition and use are necessary. 59 Intra, 60 61 // Definition in another statement. There is a scalar MemoryAccess that 62 // makes it available in this statement. 63 Inter 64 }; 65 66 private: 67 /// The statement where a value is used. 68 ScopStmt *User; 69 70 /// The value that is used. 71 Value *Val; 72 73 /// The type of value use. 74 UseKind Kind; 75 76 /// The value represented as llvm::SCEV expression. 77 const SCEV *ScevExpr; 78 79 /// If this is an inter-statement (or read-only) use, contains the 80 /// MemoryAccess that makes the value available in this statement. In case of 81 /// intra-statement uses, can contain a MemoryKind::Array access. In all other 82 /// cases, it is a nullptr. 83 MemoryAccess *InputMA; 84 VirtualUse(ScopStmt * User,Value * Val,UseKind Kind,const SCEV * ScevExpr,MemoryAccess * InputMA)85 VirtualUse(ScopStmt *User, Value *Val, UseKind Kind, const SCEV *ScevExpr, 86 MemoryAccess *InputMA) 87 : User(User), Val(Val), Kind(Kind), ScevExpr(ScevExpr), InputMA(InputMA) { 88 } 89 90 public: 91 /// Get a VirtualUse for an llvm::Use. 92 /// 93 /// @param S The Scop object. 94 /// @param U The llvm::Use the get information for. 95 /// @param LI The LoopInfo analysis. Needed to determine whether the 96 /// value is synthesizable. 97 /// @param Virtual Whether to ignore existing MemoryAcccess. 98 /// 99 /// @return The VirtualUse representing the same use as @p U. 100 static VirtualUse create(Scop *S, const Use &U, LoopInfo *LI, bool Virtual); 101 102 /// Get a VirtualUse for uses within statements. 103 /// 104 /// It is assumed that the user is not a PHINode. Such uses are always 105 /// VirtualUse::Inter unless in a regions statement. 106 /// 107 /// @param S The Scop object. 108 /// @param UserStmt The statement in which @p Val is used. Can be nullptr, in 109 /// which case it assumed that the statement has been 110 /// removed, which is only possible if no instruction in it 111 /// had side-effects or computes a value used by another 112 /// statement. 113 /// @param UserScope Loop scope in which the value is used. Needed to 114 /// determine whether the value is synthesizable. 115 /// @param Val The value being used. 116 /// @param Virtual Whether to use (and prioritize over instruction location) 117 /// information about MemoryAccesses. 118 /// 119 /// @return A VirtualUse object that gives information about @p Val's use in 120 /// @p UserStmt. 121 static VirtualUse create(Scop *S, ScopStmt *UserStmt, Loop *UserScope, 122 Value *Val, bool Virtual); 123 create(ScopStmt * UserStmt,Loop * UserScope,Value * Val,bool Virtual)124 static VirtualUse create(ScopStmt *UserStmt, Loop *UserScope, Value *Val, 125 bool Virtual) { 126 return create(UserStmt->getParent(), UserStmt, UserScope, Val, Virtual); 127 } 128 isConstant()129 bool isConstant() const { return Kind == Constant; } isBlock()130 bool isBlock() const { return Kind == Block; } isSynthesizable()131 bool isSynthesizable() const { return Kind == Synthesizable; } isHoisted()132 bool isHoisted() const { return Kind == Hoisted; } isReadOnly()133 bool isReadOnly() const { return Kind == ReadOnly; } isIntra()134 bool isIntra() const { return Kind == Intra; } isInter()135 bool isInter() const { return Kind == Inter; } 136 137 /// Return user statement. getUser()138 ScopStmt *getUser() const { return User; } 139 140 /// Return the used value. getValue()141 llvm::Value *getValue() const { return Val; } 142 143 /// Return the type of use. getKind()144 UseKind getKind() const { return Kind; } 145 146 /// Return the ScalarEvolution representation of @p Val. getScevExpr()147 const SCEV *getScevExpr() const { return ScevExpr; } 148 149 /// Return the MemoryAccess that makes the value available in this statement, 150 /// if any. getMemoryAccess()151 MemoryAccess *getMemoryAccess() const { return InputMA; } 152 153 /// Print a description of this object. 154 /// 155 /// @param OS Stream to print to. 156 /// @param Reproducible If true, ensures that the output is stable between 157 /// runs and is suitable to check in regression tests. 158 /// This excludes printing e.g. pointer values. If false, 159 /// the output should not be used for regression tests, 160 /// but may contain more information useful in debugger 161 /// sessions. 162 void print(raw_ostream &OS, bool Reproducible = true) const; 163 164 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 165 void dump() const; 166 #endif 167 }; 168 169 /// An iterator for virtual operands. 170 class VirtualOperandIterator { 171 friend class VirtualInstruction; 172 friend class VirtualUse; 173 174 using Self = VirtualOperandIterator; 175 176 ScopStmt *User; 177 User::op_iterator U; 178 VirtualOperandIterator(ScopStmt * User,User::op_iterator U)179 VirtualOperandIterator(ScopStmt *User, User::op_iterator U) 180 : User(User), U(U) {} 181 182 public: 183 using iterator_category = std::forward_iterator_tag; 184 using value_type = VirtualUse; 185 using difference_type = std::ptrdiff_t; 186 using pointer = value_type *; 187 using reference = value_type &; 188 189 inline bool operator==(const Self &that) const { 190 assert(this->User == that.User); 191 return this->U == that.U; 192 } 193 194 inline bool operator!=(const Self &that) const { 195 assert(this->User == that.User); 196 return this->U != that.U; 197 } 198 199 VirtualUse operator*() const { 200 return VirtualUse::create(User, User->getSurroundingLoop(), U->get(), true); 201 } 202 203 Use *operator->() const { return U; } 204 205 Self &operator++() { 206 U++; 207 return *this; 208 } 209 210 Self operator++(int) { 211 Self tmp = *this; 212 ++*this; 213 return tmp; 214 } 215 }; 216 217 /// This class represents a "virtual instruction", an instruction in a ScopStmt, 218 /// effectively a ScopStmt/Instruction-pair. 219 /// 220 /// An instructions can be moved between statements (e.g. to avoid a scalar 221 /// dependency) and even can be contained in multiple statements (for instance, 222 /// to recompute a value instead of transferring it), hence 'virtual'. This 223 /// class is required to represent such instructions that are not in their 224 /// 'physical' location anymore. 225 /// 226 /// A statement can currently not contain the same instructions multiple times 227 /// (that is, from different loop iterations). Therefore, a 228 /// ScopStmt/Instruction-pair uniquely identifies a virtual instructions. 229 /// ScopStmt::getInstruction() can contain the same instruction multiple times, 230 /// but they necessarily compute the same value. 231 class VirtualInstruction { 232 friend class VirtualOperandIterator; 233 friend struct llvm::DenseMapInfo<VirtualInstruction>; 234 235 private: 236 /// The statement this virtual instruction is in. 237 ScopStmt *Stmt = nullptr; 238 239 /// The instruction of a statement. 240 Instruction *Inst = nullptr; 241 242 public: 243 VirtualInstruction() {} 244 245 /// Create a new virtual instruction of an instruction @p Inst in @p Stmt. 246 VirtualInstruction(ScopStmt *Stmt, Instruction *Inst) 247 : Stmt(Stmt), Inst(Inst) { 248 assert(Stmt && Inst); 249 } 250 251 VirtualOperandIterator operand_begin() const { 252 return VirtualOperandIterator(Stmt, Inst->op_begin()); 253 } 254 255 VirtualOperandIterator operand_end() const { 256 return VirtualOperandIterator(Stmt, Inst->op_end()); 257 } 258 259 /// Returns a list of virtual operands. 260 /// 261 /// Virtual operands, like virtual instructions, need to encode the ScopStmt 262 /// they are in. 263 llvm::iterator_range<VirtualOperandIterator> operands() const { 264 return {operand_begin(), operand_end()}; 265 } 266 267 /// Return the SCoP everything is contained in. 268 Scop *getScop() const { return Stmt->getParent(); } 269 270 /// Return the ScopStmt this virtual instruction is in. 271 ScopStmt *getStmt() const { return Stmt; } 272 273 /// Return the instruction in the statement. 274 Instruction *getInstruction() const { return Inst; } 275 276 /// Print a description of this object. 277 /// 278 /// @param OS Stream to print to. 279 /// @param Reproducible If true, ensures that the output is stable between 280 /// runs and is suitable for checks in regression tests. 281 /// This excludes printing e.g., pointer values. If false, 282 /// the output should not be used for regression tests, 283 /// but may contain more information useful in debugger 284 /// sessions. 285 void print(raw_ostream &OS, bool Reproducible = true) const; 286 287 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 288 void dump() const; 289 #endif 290 }; 291 292 static inline bool operator==(VirtualInstruction LHS, VirtualInstruction RHS) { 293 return LHS.getStmt() == RHS.getStmt() && 294 LHS.getInstruction() == RHS.getInstruction(); 295 } 296 297 /// Find all reachable instructions and accesses. 298 /// 299 /// @param S The SCoP to find everything reachable in. 300 /// @param LI LoopInfo required for analysis. 301 /// @param UsedInsts[out] Receives all reachable instructions. 302 /// @param UsedAccs[out] Receives all reachable accesses. 303 /// @param OnlyLocal If non-nullptr, activates local mode: The SCoP is 304 /// assumed to consist only of this statement and is 305 /// conservatively correct. Does not require walking the 306 /// whole SCoP. 307 void markReachable(Scop *S, LoopInfo *LI, 308 DenseSet<VirtualInstruction> &UsedInsts, 309 DenseSet<MemoryAccess *> &UsedAccs, 310 ScopStmt *OnlyLocal = nullptr); 311 } // namespace polly 312 313 namespace llvm { 314 /// Support VirtualInstructions in llvm::DenseMaps. 315 template <> struct DenseMapInfo<polly::VirtualInstruction> { 316 public: 317 static bool isEqual(polly::VirtualInstruction LHS, 318 polly::VirtualInstruction RHS) { 319 return DenseMapInfo<polly::ScopStmt *>::isEqual(LHS.getStmt(), 320 RHS.getStmt()) && 321 DenseMapInfo<Instruction *>::isEqual(LHS.getInstruction(), 322 RHS.getInstruction()); 323 } 324 325 static polly::VirtualInstruction getTombstoneKey() { 326 polly::VirtualInstruction TombstoneKey; 327 TombstoneKey.Stmt = DenseMapInfo<polly::ScopStmt *>::getTombstoneKey(); 328 TombstoneKey.Inst = DenseMapInfo<Instruction *>::getTombstoneKey(); 329 return TombstoneKey; 330 } 331 332 static polly::VirtualInstruction getEmptyKey() { 333 polly::VirtualInstruction EmptyKey; 334 EmptyKey.Stmt = DenseMapInfo<polly::ScopStmt *>::getEmptyKey(); 335 EmptyKey.Inst = DenseMapInfo<Instruction *>::getEmptyKey(); 336 return EmptyKey; 337 } 338 339 static unsigned getHashValue(polly::VirtualInstruction Val) { 340 return DenseMapInfo<std::pair<polly::ScopStmt *, Instruction *>>:: 341 getHashValue(std::make_pair(Val.getStmt(), Val.getInstruction())); 342 } 343 }; 344 } // namespace llvm 345 346 #endif /* POLLY_SUPPORT_VIRTUALINSTRUCTION_H */ 347