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