xref: /freebsd/contrib/llvm-project/llvm/include/llvm/SandboxIR/Value.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- Value.h --------------------------------------------------*- 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 #ifndef LLVM_SANDBOXIR_VALUE_H
10 #define LLVM_SANDBOXIR_VALUE_H
11 
12 #include "llvm/IR/Metadata.h"
13 #include "llvm/IR/Value.h"
14 #include "llvm/SandboxIR/Use.h"
15 #include "llvm/Support/Compiler.h"
16 
17 namespace llvm::sandboxir {
18 
19 // Forward declare all classes to avoid some MSVC build errors.
20 #define DEF_INSTR(ID, OPC, CLASS) class CLASS;
21 #define DEF_CONST(ID, CLASS) class CLASS;
22 #define DEF_USER(ID, CLASS) class CLASS;
23 #include "llvm/SandboxIR/Values.def"
24 class Context;
25 class FuncletPadInst;
26 class Type;
27 class GlobalValue;
28 class GlobalObject;
29 class Module;
30 class UnaryInstruction;
31 class CmpInst;
32 class IntrinsicInst;
33 class Operator;
34 class OverflowingBinaryOperator;
35 class FPMathOperator;
36 class Region;
37 
38 /// Iterator for the `Use` edges of a Value's users.
39 /// \Returns a `Use` when dereferenced.
40 class UserUseIterator {
41   sandboxir::Use Use;
42   /// Don't let the user create a non-empty UserUseIterator.
UserUseIterator(const class Use & Use)43   UserUseIterator(const class Use &Use) : Use(Use) {}
44   friend class Value; // For constructor
45 
46 public:
47   using difference_type = std::ptrdiff_t;
48   using value_type = sandboxir::Use;
49   using pointer = value_type *;
50   using reference = value_type &;
51   using iterator_category = std::input_iterator_tag;
52 
53   UserUseIterator() = default;
54   value_type operator*() const { return Use; }
55   LLVM_ABI UserUseIterator &operator++();
56   bool operator==(const UserUseIterator &Other) const {
57     return Use == Other.Use;
58   }
59   bool operator!=(const UserUseIterator &Other) const {
60     return !(*this == Other);
61   }
getUse()62   const sandboxir::Use &getUse() const { return Use; }
63 };
64 
65 /// A SandboxIR Value has users. This is the base class.
66 class Value {
67 public:
68   enum class ClassID : unsigned {
69 #define DEF_VALUE(ID, CLASS) ID,
70 #define DEF_USER(ID, CLASS) ID,
71 #define DEF_CONST(ID, CLASS) ID,
72 #define DEF_INSTR(ID, OPC, CLASS) ID,
73 #include "llvm/SandboxIR/Values.def"
74   };
75 
76 protected:
getSubclassIDStr(ClassID ID)77   static const char *getSubclassIDStr(ClassID ID) {
78     switch (ID) {
79 #define DEF_VALUE(ID, CLASS)                                                   \
80   case ClassID::ID:                                                            \
81     return #ID;
82 #define DEF_USER(ID, CLASS)                                                    \
83   case ClassID::ID:                                                            \
84     return #ID;
85 #define DEF_CONST(ID, CLASS)                                                   \
86   case ClassID::ID:                                                            \
87     return #ID;
88 #define DEF_INSTR(ID, OPC, CLASS)                                              \
89   case ClassID::ID:                                                            \
90     return #ID;
91 #include "llvm/SandboxIR/Values.def"
92     }
93     llvm_unreachable("Unimplemented ID");
94   }
95 
96   /// For isa/dyn_cast.
97   ClassID SubclassID;
98 #ifndef NDEBUG
99   /// A unique ID used for forming the name (used for debugging).
100   unsigned UID;
101 #endif
102   /// The LLVM Value that corresponds to this SandboxIR Value.
103   /// NOTE: Some sandboxir Instructions, like Packs, may include more than one
104   /// value and in these cases `Val` points to the last instruction in program
105   /// order.
106   llvm::Value *Val = nullptr;
107 
108   friend class Context;               // For getting `Val`.
109   friend class User;                  // For getting `Val`.
110   friend class Use;                   // For getting `Val`.
111   friend class VAArgInst;             // For getting `Val`.
112   friend class FreezeInst;            // For getting `Val`.
113   friend class FenceInst;             // For getting `Val`.
114   friend class SelectInst;            // For getting `Val`.
115   friend class ExtractElementInst;    // For getting `Val`.
116   friend class InsertElementInst;     // For getting `Val`.
117   friend class ShuffleVectorInst;     // For getting `Val`.
118   friend class ExtractValueInst;      // For getting `Val`.
119   friend class InsertValueInst;       // For getting `Val`.
120   friend class BranchInst;            // For getting `Val`.
121   friend class LoadInst;              // For getting `Val`.
122   friend class StoreInst;             // For getting `Val`.
123   friend class ReturnInst;            // For getting `Val`.
124   friend class CallBase;              // For getting `Val`.
125   friend class CallInst;              // For getting `Val`.
126   friend class InvokeInst;            // For getting `Val`.
127   friend class CallBrInst;            // For getting `Val`.
128   friend class LandingPadInst;        // For getting `Val`.
129   friend class FuncletPadInst;        // For getting `Val`.
130   friend class CatchPadInst;          // For getting `Val`.
131   friend class CleanupPadInst;        // For getting `Val`.
132   friend class CatchReturnInst;       // For getting `Val`.
133   friend class GetElementPtrInst;     // For getting `Val`.
134   friend class ResumeInst;            // For getting `Val`.
135   friend class CatchSwitchInst;       // For getting `Val`.
136   friend class CleanupReturnInst;     // For getting `Val`.
137   friend class SwitchInst;            // For getting `Val`.
138   friend class UnaryOperator;         // For getting `Val`.
139   friend class BinaryOperator;        // For getting `Val`.
140   friend class AtomicRMWInst;         // For getting `Val`.
141   friend class AtomicCmpXchgInst;     // For getting `Val`.
142   friend class AllocaInst;            // For getting `Val`.
143   friend class CastInst;              // For getting `Val`.
144   friend class PHINode;               // For getting `Val`.
145   friend class UnreachableInst;       // For getting `Val`.
146   friend class CatchSwitchAddHandler; // For `Val`.
147   friend class CmpInst;               // For getting `Val`.
148   friend class ConstantArray;         // For `Val`.
149   friend class ConstantStruct;        // For `Val`.
150   friend class ConstantVector;        // For `Val`.
151   friend class ConstantAggregateZero; // For `Val`.
152   friend class ConstantPointerNull;   // For `Val`.
153   friend class UndefValue;            // For `Val`.
154   friend class PoisonValue;           // For `Val`.
155   friend class BlockAddress;          // For `Val`.
156   friend class GlobalValue;           // For `Val`.
157   friend class DSOLocalEquivalent;    // For `Val`.
158   friend class GlobalObject;          // For `Val`.
159   friend class GlobalIFunc;           // For `Val`.
160   friend class GlobalVariable;        // For `Val`.
161   friend class GlobalAlias;           // For `Val`.
162   friend class NoCFIValue;            // For `Val`.
163   friend class ConstantPtrAuth;       // For `Val`.
164   friend class ConstantExpr;          // For `Val`.
165   friend class Utils;                 // For `Val`.
166   friend class Module;                // For `Val`.
167   friend class IntrinsicInst;         // For `Val`.
168   friend class Operator;              // For `Val`.
169   friend class OverflowingBinaryOperator; // For `Val`.
170   friend class FPMathOperator;            // For `Val`.
171   // Region needs to manipulate metadata in the underlying LLVM Value, we don't
172   // expose metadata in sandboxir.
173   friend class Region;
174   friend class ScoreBoard; // Needs access to `Val` for the instruction cost.
175   friend class ConstantDataArray; // For `Val`
176   friend class ConstantDataVector; // For `Val`
177 
178   /// All values point to the context.
179   Context &Ctx;
180   // This is used by eraseFromParent().
clearValue()181   void clearValue() { Val = nullptr; }
182   template <typename ItTy, typename SBTy> friend class LLVMOpUserItToSBTy;
183 
184   LLVM_ABI Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx);
185   /// Disable copies.
186   Value(const Value &) = delete;
187   Value &operator=(const Value &) = delete;
188 
189 public:
190   virtual ~Value() = default;
getSubclassID()191   ClassID getSubclassID() const { return SubclassID; }
192 
193   using use_iterator = UserUseIterator;
194   using const_use_iterator = UserUseIterator;
195 
196   LLVM_ABI use_iterator use_begin();
use_begin()197   const_use_iterator use_begin() const {
198     return const_cast<Value *>(this)->use_begin();
199   }
use_end()200   use_iterator use_end() { return use_iterator(Use(nullptr, nullptr, Ctx)); }
use_end()201   const_use_iterator use_end() const {
202     return const_cast<Value *>(this)->use_end();
203   }
204 
uses()205   iterator_range<use_iterator> uses() {
206     return make_range<use_iterator>(use_begin(), use_end());
207   }
uses()208   iterator_range<const_use_iterator> uses() const {
209     return make_range<const_use_iterator>(use_begin(), use_end());
210   }
211 
212   /// Helper for mapped_iterator.
213   struct UseToUser {
operatorUseToUser214     User *operator()(const Use &Use) const { return &*Use.getUser(); }
215   };
216 
217   using user_iterator = mapped_iterator<sandboxir::UserUseIterator, UseToUser>;
218   using const_user_iterator = user_iterator;
219 
220   LLVM_ABI user_iterator user_begin();
user_end()221   user_iterator user_end() {
222     return user_iterator(Use(nullptr, nullptr, Ctx), UseToUser());
223   }
user_begin()224   const_user_iterator user_begin() const {
225     return const_cast<Value *>(this)->user_begin();
226   }
user_end()227   const_user_iterator user_end() const {
228     return const_cast<Value *>(this)->user_end();
229   }
230 
users()231   iterator_range<user_iterator> users() {
232     return make_range<user_iterator>(user_begin(), user_end());
233   }
users()234   iterator_range<const_user_iterator> users() const {
235     return make_range<const_user_iterator>(user_begin(), user_end());
236   }
237   /// \Returns the number of user edges (not necessarily to unique users).
238   /// WARNING: This is a linear-time operation.
239   LLVM_ABI unsigned getNumUses() const;
240   /// Return true if this value has N uses or more.
241   /// This is logically equivalent to getNumUses() >= N.
242   /// WARNING: This can be expensive, as it is linear to the number of users.
hasNUsesOrMore(unsigned Num)243   bool hasNUsesOrMore(unsigned Num) const {
244     unsigned Cnt = 0;
245     for (auto It = use_begin(), ItE = use_end(); It != ItE; ++It) {
246       if (++Cnt >= Num)
247         return true;
248     }
249     return false;
250   }
251   /// Return true if this Value has exactly N uses.
hasNUses(unsigned Num)252   bool hasNUses(unsigned Num) const {
253     unsigned Cnt = 0;
254     for (auto It = use_begin(), ItE = use_end(); It != ItE; ++It) {
255       if (++Cnt > Num)
256         return false;
257     }
258     return Cnt == Num;
259   }
260 
261   LLVM_ABI Type *getType() const;
262 
getContext()263   Context &getContext() const { return Ctx; }
264 
265   LLVM_ABI void
266   replaceUsesWithIf(Value *OtherV,
267                     llvm::function_ref<bool(const Use &)> ShouldReplace);
268   LLVM_ABI void replaceAllUsesWith(Value *Other);
269 
270   /// \Returns the LLVM IR name of the bottom-most LLVM value.
getName()271   StringRef getName() const { return Val->getName(); }
272 
273 #ifndef NDEBUG
274   /// Should crash if there is something wrong with the instruction.
275   virtual void verify() const = 0;
276   /// Returns the unique id in the form 'SB<number>.' like 'SB1.'
277   std::string getUid() const;
278   virtual void dumpCommonHeader(raw_ostream &OS) const;
279   void dumpCommonFooter(raw_ostream &OS) const;
280   void dumpCommonPrefix(raw_ostream &OS) const;
281   void dumpCommonSuffix(raw_ostream &OS) const;
282   void printAsOperandCommon(raw_ostream &OS) const;
283   friend raw_ostream &operator<<(raw_ostream &OS, const sandboxir::Value &V) {
284     V.dumpOS(OS);
285     return OS;
286   }
287   virtual void dumpOS(raw_ostream &OS) const = 0;
288   LLVM_DUMP_METHOD void dump() const;
289 #endif
290 };
291 
292 class OpaqueValue : public Value {
293 protected:
OpaqueValue(llvm::Value * V,Context & Ctx)294   OpaqueValue(llvm::Value *V, Context &Ctx)
295       : Value(ClassID::OpaqueValue, V, Ctx) {}
296   friend class Context; // For constructor.
297 
298 public:
classof(const Value * From)299   static bool classof(const Value *From) {
300     return From->getSubclassID() == ClassID::OpaqueValue;
301   }
302 #ifndef NDEBUG
verify()303   void verify() const override {
304     assert((isa<llvm::MetadataAsValue>(Val) || isa<llvm::InlineAsm>(Val)) &&
305            "Expected Metadata or InlineAssembly!");
306   }
dumpOS(raw_ostream & OS)307   void dumpOS(raw_ostream &OS) const override {
308     dumpCommonPrefix(OS);
309     dumpCommonSuffix(OS);
310   }
311 #endif // NDEBUG
312 };
313 
314 } // namespace llvm::sandboxir
315 
316 #endif // LLVM_SANDBOXIR_VALUE_H
317