Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:26

0001 //===- Value.h --------------------------------------------------*- 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 #ifndef LLVM_SANDBOXIR_VALUE_H
0010 #define LLVM_SANDBOXIR_VALUE_H
0011 
0012 #include "llvm/IR/Value.h"
0013 #include "llvm/SandboxIR/Use.h"
0014 
0015 namespace llvm::sandboxir {
0016 
0017 // Forward declare all classes to avoid some MSVC build errors.
0018 #define DEF_INSTR(ID, OPC, CLASS) class CLASS;
0019 #define DEF_CONST(ID, CLASS) class CLASS;
0020 #define DEF_USER(ID, CLASS) class CLASS;
0021 #include "llvm/SandboxIR/Values.def"
0022 class Context;
0023 class FuncletPadInst;
0024 class Type;
0025 class GlobalValue;
0026 class GlobalObject;
0027 class Module;
0028 class UnaryInstruction;
0029 class CmpInst;
0030 class IntrinsicInst;
0031 class Operator;
0032 class OverflowingBinaryOperator;
0033 class FPMathOperator;
0034 
0035 /// Iterator for the `Use` edges of a Value's users.
0036 /// \Returns a `Use` when dereferenced.
0037 class UserUseIterator {
0038   sandboxir::Use Use;
0039   /// Don't let the user create a non-empty UserUseIterator.
0040   UserUseIterator(const class Use &Use) : Use(Use) {}
0041   friend class Value; // For constructor
0042 
0043 public:
0044   using difference_type = std::ptrdiff_t;
0045   using value_type = sandboxir::Use;
0046   using pointer = value_type *;
0047   using reference = value_type &;
0048   using iterator_category = std::input_iterator_tag;
0049 
0050   UserUseIterator() = default;
0051   value_type operator*() const { return Use; }
0052   UserUseIterator &operator++();
0053   bool operator==(const UserUseIterator &Other) const {
0054     return Use == Other.Use;
0055   }
0056   bool operator!=(const UserUseIterator &Other) const {
0057     return !(*this == Other);
0058   }
0059   const sandboxir::Use &getUse() const { return Use; }
0060 };
0061 
0062 /// A SandboxIR Value has users. This is the base class.
0063 class Value {
0064 public:
0065   enum class ClassID : unsigned {
0066 #define DEF_VALUE(ID, CLASS) ID,
0067 #define DEF_USER(ID, CLASS) ID,
0068 #define DEF_CONST(ID, CLASS) ID,
0069 #define DEF_INSTR(ID, OPC, CLASS) ID,
0070 #include "llvm/SandboxIR/Values.def"
0071   };
0072 
0073 protected:
0074   static const char *getSubclassIDStr(ClassID ID) {
0075     switch (ID) {
0076 #define DEF_VALUE(ID, CLASS)                                                   \
0077   case ClassID::ID:                                                            \
0078     return #ID;
0079 #define DEF_USER(ID, CLASS)                                                    \
0080   case ClassID::ID:                                                            \
0081     return #ID;
0082 #define DEF_CONST(ID, CLASS)                                                   \
0083   case ClassID::ID:                                                            \
0084     return #ID;
0085 #define DEF_INSTR(ID, OPC, CLASS)                                              \
0086   case ClassID::ID:                                                            \
0087     return #ID;
0088 #include "llvm/SandboxIR/Values.def"
0089     }
0090     llvm_unreachable("Unimplemented ID");
0091   }
0092 
0093   /// For isa/dyn_cast.
0094   ClassID SubclassID;
0095 #ifndef NDEBUG
0096   /// A unique ID used for forming the name (used for debugging).
0097   unsigned UID;
0098 #endif
0099   /// The LLVM Value that corresponds to this SandboxIR Value.
0100   /// NOTE: Some sandboxir Instructions, like Packs, may include more than one
0101   /// value and in these cases `Val` points to the last instruction in program
0102   /// order.
0103   llvm::Value *Val = nullptr;
0104 
0105   friend class Context;               // For getting `Val`.
0106   friend class User;                  // For getting `Val`.
0107   friend class Use;                   // For getting `Val`.
0108   friend class VAArgInst;             // For getting `Val`.
0109   friend class FreezeInst;            // For getting `Val`.
0110   friend class FenceInst;             // For getting `Val`.
0111   friend class SelectInst;            // For getting `Val`.
0112   friend class ExtractElementInst;    // For getting `Val`.
0113   friend class InsertElementInst;     // For getting `Val`.
0114   friend class ShuffleVectorInst;     // For getting `Val`.
0115   friend class ExtractValueInst;      // For getting `Val`.
0116   friend class InsertValueInst;       // For getting `Val`.
0117   friend class BranchInst;            // For getting `Val`.
0118   friend class LoadInst;              // For getting `Val`.
0119   friend class StoreInst;             // For getting `Val`.
0120   friend class ReturnInst;            // For getting `Val`.
0121   friend class CallBase;              // For getting `Val`.
0122   friend class CallInst;              // For getting `Val`.
0123   friend class InvokeInst;            // For getting `Val`.
0124   friend class CallBrInst;            // For getting `Val`.
0125   friend class LandingPadInst;        // For getting `Val`.
0126   friend class FuncletPadInst;        // For getting `Val`.
0127   friend class CatchPadInst;          // For getting `Val`.
0128   friend class CleanupPadInst;        // For getting `Val`.
0129   friend class CatchReturnInst;       // For getting `Val`.
0130   friend class GetElementPtrInst;     // For getting `Val`.
0131   friend class ResumeInst;            // For getting `Val`.
0132   friend class CatchSwitchInst;       // For getting `Val`.
0133   friend class CleanupReturnInst;     // For getting `Val`.
0134   friend class SwitchInst;            // For getting `Val`.
0135   friend class UnaryOperator;         // For getting `Val`.
0136   friend class BinaryOperator;        // For getting `Val`.
0137   friend class AtomicRMWInst;         // For getting `Val`.
0138   friend class AtomicCmpXchgInst;     // For getting `Val`.
0139   friend class AllocaInst;            // For getting `Val`.
0140   friend class CastInst;              // For getting `Val`.
0141   friend class PHINode;               // For getting `Val`.
0142   friend class UnreachableInst;       // For getting `Val`.
0143   friend class CatchSwitchAddHandler; // For `Val`.
0144   friend class CmpInst;               // For getting `Val`.
0145   friend class ConstantArray;         // For `Val`.
0146   friend class ConstantStruct;        // For `Val`.
0147   friend class ConstantAggregateZero; // For `Val`.
0148   friend class ConstantPointerNull;   // For `Val`.
0149   friend class UndefValue;            // For `Val`.
0150   friend class PoisonValue;           // For `Val`.
0151   friend class BlockAddress;          // For `Val`.
0152   friend class GlobalValue;           // For `Val`.
0153   friend class DSOLocalEquivalent;    // For `Val`.
0154   friend class GlobalObject;          // For `Val`.
0155   friend class GlobalIFunc;           // For `Val`.
0156   friend class GlobalVariable;        // For `Val`.
0157   friend class GlobalAlias;           // For `Val`.
0158   friend class NoCFIValue;            // For `Val`.
0159   friend class ConstantPtrAuth;       // For `Val`.
0160   friend class ConstantExpr;          // For `Val`.
0161   friend class Utils;                 // For `Val`.
0162   friend class Module;                // For `Val`.
0163   friend class IntrinsicInst;         // For `Val`.
0164   friend class Operator;              // For `Val`.
0165   friend class OverflowingBinaryOperator; // For `Val`.
0166   friend class FPMathOperator;            // For `Val`.
0167   // Region needs to manipulate metadata in the underlying LLVM Value, we don't
0168   // expose metadata in sandboxir.
0169   friend class Region;
0170   friend class ScoreBoard; // Needs access to `Val` for the instruction cost.
0171 
0172   /// All values point to the context.
0173   Context &Ctx;
0174   // This is used by eraseFromParent().
0175   void clearValue() { Val = nullptr; }
0176   template <typename ItTy, typename SBTy> friend class LLVMOpUserItToSBTy;
0177 
0178   Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx);
0179   /// Disable copies.
0180   Value(const Value &) = delete;
0181   Value &operator=(const Value &) = delete;
0182 
0183 public:
0184   virtual ~Value() = default;
0185   ClassID getSubclassID() const { return SubclassID; }
0186 
0187   using use_iterator = UserUseIterator;
0188   using const_use_iterator = UserUseIterator;
0189 
0190   use_iterator use_begin();
0191   const_use_iterator use_begin() const {
0192     return const_cast<Value *>(this)->use_begin();
0193   }
0194   use_iterator use_end() { return use_iterator(Use(nullptr, nullptr, Ctx)); }
0195   const_use_iterator use_end() const {
0196     return const_cast<Value *>(this)->use_end();
0197   }
0198 
0199   iterator_range<use_iterator> uses() {
0200     return make_range<use_iterator>(use_begin(), use_end());
0201   }
0202   iterator_range<const_use_iterator> uses() const {
0203     return make_range<const_use_iterator>(use_begin(), use_end());
0204   }
0205 
0206   /// Helper for mapped_iterator.
0207   struct UseToUser {
0208     User *operator()(const Use &Use) const { return &*Use.getUser(); }
0209   };
0210 
0211   using user_iterator = mapped_iterator<sandboxir::UserUseIterator, UseToUser>;
0212   using const_user_iterator = user_iterator;
0213 
0214   user_iterator user_begin();
0215   user_iterator user_end() {
0216     return user_iterator(Use(nullptr, nullptr, Ctx), UseToUser());
0217   }
0218   const_user_iterator user_begin() const {
0219     return const_cast<Value *>(this)->user_begin();
0220   }
0221   const_user_iterator user_end() const {
0222     return const_cast<Value *>(this)->user_end();
0223   }
0224 
0225   iterator_range<user_iterator> users() {
0226     return make_range<user_iterator>(user_begin(), user_end());
0227   }
0228   iterator_range<const_user_iterator> users() const {
0229     return make_range<const_user_iterator>(user_begin(), user_end());
0230   }
0231   /// \Returns the number of user edges (not necessarily to unique users).
0232   /// WARNING: This is a linear-time operation.
0233   unsigned getNumUses() const;
0234   /// Return true if this value has N uses or more.
0235   /// This is logically equivalent to getNumUses() >= N.
0236   /// WARNING: This can be expensive, as it is linear to the number of users.
0237   bool hasNUsesOrMore(unsigned Num) const {
0238     unsigned Cnt = 0;
0239     for (auto It = use_begin(), ItE = use_end(); It != ItE; ++It) {
0240       if (++Cnt >= Num)
0241         return true;
0242     }
0243     return false;
0244   }
0245   /// Return true if this Value has exactly N uses.
0246   bool hasNUses(unsigned Num) const {
0247     unsigned Cnt = 0;
0248     for (auto It = use_begin(), ItE = use_end(); It != ItE; ++It) {
0249       if (++Cnt > Num)
0250         return false;
0251     }
0252     return Cnt == Num;
0253   }
0254 
0255   Type *getType() const;
0256 
0257   Context &getContext() const { return Ctx; }
0258 
0259   void replaceUsesWithIf(Value *OtherV,
0260                          llvm::function_ref<bool(const Use &)> ShouldReplace);
0261   void replaceAllUsesWith(Value *Other);
0262 
0263   /// \Returns the LLVM IR name of the bottom-most LLVM value.
0264   StringRef getName() const { return Val->getName(); }
0265 
0266 #ifndef NDEBUG
0267   /// Should crash if there is something wrong with the instruction.
0268   virtual void verify() const = 0;
0269   /// Returns the unique id in the form 'SB<number>.' like 'SB1.'
0270   std::string getUid() const;
0271   virtual void dumpCommonHeader(raw_ostream &OS) const;
0272   void dumpCommonFooter(raw_ostream &OS) const;
0273   void dumpCommonPrefix(raw_ostream &OS) const;
0274   void dumpCommonSuffix(raw_ostream &OS) const;
0275   void printAsOperandCommon(raw_ostream &OS) const;
0276   friend raw_ostream &operator<<(raw_ostream &OS, const sandboxir::Value &V) {
0277     V.dumpOS(OS);
0278     return OS;
0279   }
0280   virtual void dumpOS(raw_ostream &OS) const = 0;
0281   LLVM_DUMP_METHOD void dump() const;
0282 #endif
0283 };
0284 
0285 } // namespace llvm::sandboxir
0286 
0287 #endif // LLVM_SANDBOXIR_VALUE_H