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