Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:48:20

0001 //===------ VirtualInstruction.cpp ------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Tools for determining which instructions are within a statement and the
0010 // nature of their operands.
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 /// Determine the nature of a value's use within a statement.
0023 ///
0024 /// These are not always representable by llvm::Use. For instance, scalar write
0025 /// MemoryAccesses do use a value, but are not associated with an instruction's
0026 /// argument.
0027 ///
0028 /// Despite its name it is not tied to virtual instructions (although it works
0029 /// fine with them), but to promote consistent handling of values used in
0030 /// statements.
0031 class VirtualUse final {
0032 public:
0033   /// The different types of uses. Handling usually differentiates a lot between
0034   /// these; one can use a switch to handle each case (and get warned by the
0035   /// compiler if one is not handled).
0036   enum UseKind {
0037     // An llvm::Constant.
0038     Constant,
0039 
0040     // An llvm::BasicBlock.
0041     Block,
0042 
0043     // A value that can be generated using ScopExpander.
0044     Synthesizable,
0045 
0046     // A load that always reads the same value throughout the SCoP (address and
0047     // the value located there a SCoP-invariant) and has been hoisted in front
0048     // of the SCoP.
0049     Hoisted,
0050 
0051     // Definition before the SCoP and not synthesizable. Can be an instruction
0052     // outside the SCoP, a function argument or a global value. Whether there is
0053     // a scalar MemoryAccess in this statement for reading it depends on the
0054     // -polly-analyze-read-only-scalars switch.
0055     ReadOnly,
0056 
0057     // A definition within the same statement. No MemoryAccess between
0058     // definition and use are necessary.
0059     Intra,
0060 
0061     // Definition in another statement. There is a scalar MemoryAccess that
0062     // makes it available in this statement.
0063     Inter
0064   };
0065 
0066 private:
0067   /// The statement where a value is used.
0068   ScopStmt *User;
0069 
0070   /// The value that is used.
0071   Value *Val;
0072 
0073   /// The type of value use.
0074   UseKind Kind;
0075 
0076   /// The value represented as llvm::SCEV expression.
0077   const SCEV *ScevExpr;
0078 
0079   /// If this is an inter-statement (or read-only) use, contains the
0080   /// MemoryAccess that makes the value available in this statement. In case of
0081   /// intra-statement uses, can contain a MemoryKind::Array access. In all other
0082   /// cases, it is a nullptr.
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   /// Get a VirtualUse for an llvm::Use.
0092   ///
0093   /// @param S       The Scop object.
0094   /// @param U       The llvm::Use the get information for.
0095   /// @param LI      The LoopInfo analysis. Needed to determine whether the
0096   ///                value is synthesizable.
0097   /// @param Virtual Whether to ignore existing MemoryAccess.
0098   ///
0099   /// @return The VirtualUse representing the same use as @p U.
0100   static VirtualUse create(Scop *S, const Use &U, LoopInfo *LI, bool Virtual);
0101 
0102   /// Get a VirtualUse for uses within statements.
0103   ///
0104   /// It is assumed that the user is not a PHINode. Such uses are always
0105   /// VirtualUse::Inter unless in a regions statement.
0106   ///
0107   /// @param S         The Scop object.
0108   /// @param UserStmt  The statement in which @p Val is used. Can be nullptr, in
0109   ///                  which case it assumed that the statement has been
0110   ///                  removed, which is only possible if no instruction in it
0111   ///                  had side-effects or computes a value used by another
0112   ///                  statement.
0113   /// @param UserScope Loop scope in which the value is used. Needed to
0114   ///                  determine whether the value is synthesizable.
0115   /// @param Val       The value being used.
0116   /// @param Virtual   Whether to use (and prioritize over instruction location)
0117   ///                  information about MemoryAccesses.
0118   ///
0119   /// @return A VirtualUse object that gives information about @p Val's use in
0120   ///         @p UserStmt.
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   /// Return user statement.
0138   ScopStmt *getUser() const { return User; }
0139 
0140   /// Return the used value.
0141   llvm::Value *getValue() const { return Val; }
0142 
0143   /// Return the type of use.
0144   UseKind getKind() const { return Kind; }
0145 
0146   /// Return the ScalarEvolution representation of @p Val.
0147   const SCEV *getScevExpr() const { return ScevExpr; }
0148 
0149   /// Return the MemoryAccess that makes the value available in this statement,
0150   /// if any.
0151   MemoryAccess *getMemoryAccess() const { return InputMA; }
0152 
0153   /// Print a description of this object.
0154   ///
0155   /// @param OS           Stream to print to.
0156   /// @param Reproducible If true, ensures that the output is stable between
0157   ///                     runs and is suitable to check in regression tests.
0158   ///                     This excludes printing e.g. pointer values. If false,
0159   ///                     the output should not be used for regression tests,
0160   ///                     but may contain more information useful in debugger
0161   ///                     sessions.
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 /// An iterator for virtual operands.
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 /// This class represents a "virtual instruction", an instruction in a ScopStmt,
0218 /// effectively a ScopStmt/Instruction-pair.
0219 ///
0220 /// An instructions can be moved between statements (e.g. to avoid a scalar
0221 /// dependency) and even can be contained in multiple statements (for instance,
0222 /// to recompute a value instead of transferring it), hence 'virtual'. This
0223 /// class is required to represent such instructions that are not in their
0224 /// 'physical' location anymore.
0225 ///
0226 /// A statement can currently not contain the same instructions multiple times
0227 /// (that is, from different loop iterations). Therefore, a
0228 /// ScopStmt/Instruction-pair uniquely identifies a virtual instructions.
0229 /// ScopStmt::getInstruction() can contain the same instruction multiple times,
0230 /// but they necessarily compute the same value.
0231 class VirtualInstruction final {
0232   friend class VirtualOperandIterator;
0233   friend struct llvm::DenseMapInfo<VirtualInstruction>;
0234 
0235 private:
0236   /// The statement this virtual instruction is in.
0237   ScopStmt *Stmt = nullptr;
0238 
0239   /// The instruction of a statement.
0240   Instruction *Inst = nullptr;
0241 
0242 public:
0243   VirtualInstruction() {}
0244 
0245   /// Create a new virtual instruction of an instruction @p Inst in @p Stmt.
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   /// Returns a list of virtual operands.
0260   ///
0261   /// Virtual operands, like virtual instructions, need to encode the ScopStmt
0262   /// they are in.
0263   llvm::iterator_range<VirtualOperandIterator> operands() const {
0264     return {operand_begin(), operand_end()};
0265   }
0266 
0267   /// Return the SCoP everything is contained in.
0268   Scop *getScop() const { return Stmt->getParent(); }
0269 
0270   /// Return the ScopStmt this virtual instruction is in.
0271   ScopStmt *getStmt() const { return Stmt; }
0272 
0273   /// Return the instruction in the statement.
0274   Instruction *getInstruction() const { return Inst; }
0275 
0276   /// Print a description of this object.
0277   ///
0278   /// @param OS           Stream to print to.
0279   /// @param Reproducible If true, ensures that the output is stable between
0280   ///                     runs and is suitable for checks in regression tests.
0281   ///                     This excludes printing e.g., pointer values. If false,
0282   ///                     the output should not be used for regression tests,
0283   ///                     but may contain more information useful in debugger
0284   ///                     sessions.
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 /// Find all reachable instructions and accesses.
0298 ///
0299 /// @param S              The SCoP to find everything reachable in.
0300 /// @param LI             LoopInfo required for analysis.
0301 /// @param UsedInsts[out] Receives all reachable instructions.
0302 /// @param UsedAccs[out]  Receives all reachable accesses.
0303 /// @param OnlyLocal      If non-nullptr, activates local mode: The SCoP is
0304 ///                       assumed to consist only of this statement and is
0305 ///                       conservatively correct. Does not require walking the
0306 ///                       whole SCoP.
0307 void markReachable(Scop *S, LoopInfo *LI,
0308                    DenseSet<VirtualInstruction> &UsedInsts,
0309                    DenseSet<MemoryAccess *> &UsedAccs,
0310                    ScopStmt *OnlyLocal = nullptr);
0311 } // namespace polly
0312 
0313 namespace llvm {
0314 /// Support VirtualInstructions in llvm::DenseMaps.
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 } // namespace llvm
0345 
0346 #endif /* POLLY_SUPPORT_VIRTUALINSTRUCTION_H */