|
114 | 114 | #include "llvm/SandboxIR/Tracker.h" |
115 | 115 | #include "llvm/SandboxIR/Type.h" |
116 | 116 | #include "llvm/SandboxIR/Use.h" |
| 117 | +#include "llvm/SandboxIR/Value.h" |
117 | 118 | #include "llvm/Support/raw_ostream.h" |
118 | 119 | #include <iterator> |
119 | 120 |
|
@@ -223,251 +224,6 @@ class OperandUseIterator { |
223 | 224 | int operator-(const OperandUseIterator &Other) const; |
224 | 225 | }; |
225 | 226 |
|
226 | | -/// Iterator for the `Use` edges of a Value's users. |
227 | | -/// \Returns a `Use` when dereferenced. |
228 | | -class UserUseIterator { |
229 | | - sandboxir::Use Use; |
230 | | - /// Don't let the user create a non-empty UserUseIterator. |
231 | | - UserUseIterator(const class Use &Use) : Use(Use) {} |
232 | | - friend class Value; // For constructor |
233 | | - |
234 | | -public: |
235 | | - using difference_type = std::ptrdiff_t; |
236 | | - using value_type = sandboxir::Use; |
237 | | - using pointer = value_type *; |
238 | | - using reference = value_type &; |
239 | | - using iterator_category = std::input_iterator_tag; |
240 | | - |
241 | | - UserUseIterator() = default; |
242 | | - value_type operator*() const { return Use; } |
243 | | - UserUseIterator &operator++(); |
244 | | - bool operator==(const UserUseIterator &Other) const { |
245 | | - return Use == Other.Use; |
246 | | - } |
247 | | - bool operator!=(const UserUseIterator &Other) const { |
248 | | - return !(*this == Other); |
249 | | - } |
250 | | - const sandboxir::Use &getUse() const { return Use; } |
251 | | -}; |
252 | | - |
253 | | -/// A SandboxIR Value has users. This is the base class. |
254 | | -class Value { |
255 | | -public: |
256 | | - enum class ClassID : unsigned { |
257 | | -#define DEF_VALUE(ID, CLASS) ID, |
258 | | -#define DEF_USER(ID, CLASS) ID, |
259 | | -#define DEF_CONST(ID, CLASS) ID, |
260 | | -#define DEF_INSTR(ID, OPC, CLASS) ID, |
261 | | -#include "llvm/SandboxIR/SandboxIRValues.def" |
262 | | - }; |
263 | | - |
264 | | -protected: |
265 | | - static const char *getSubclassIDStr(ClassID ID) { |
266 | | - switch (ID) { |
267 | | -#define DEF_VALUE(ID, CLASS) \ |
268 | | - case ClassID::ID: \ |
269 | | - return #ID; |
270 | | -#define DEF_USER(ID, CLASS) \ |
271 | | - case ClassID::ID: \ |
272 | | - return #ID; |
273 | | -#define DEF_CONST(ID, CLASS) \ |
274 | | - case ClassID::ID: \ |
275 | | - return #ID; |
276 | | -#define DEF_INSTR(ID, OPC, CLASS) \ |
277 | | - case ClassID::ID: \ |
278 | | - return #ID; |
279 | | -#include "llvm/SandboxIR/SandboxIRValues.def" |
280 | | - } |
281 | | - llvm_unreachable("Unimplemented ID"); |
282 | | - } |
283 | | - |
284 | | - /// For isa/dyn_cast. |
285 | | - ClassID SubclassID; |
286 | | -#ifndef NDEBUG |
287 | | - /// A unique ID used for forming the name (used for debugging). |
288 | | - unsigned UID; |
289 | | -#endif |
290 | | - /// The LLVM Value that corresponds to this SandboxIR Value. |
291 | | - /// NOTE: Some sandboxir Instructions, like Packs, may include more than one |
292 | | - /// value and in these cases `Val` points to the last instruction in program |
293 | | - /// order. |
294 | | - llvm::Value *Val = nullptr; |
295 | | - |
296 | | - friend class Context; // For getting `Val`. |
297 | | - friend class User; // For getting `Val`. |
298 | | - friend class Use; // For getting `Val`. |
299 | | - friend class VAArgInst; // For getting `Val`. |
300 | | - friend class FreezeInst; // For getting `Val`. |
301 | | - friend class FenceInst; // For getting `Val`. |
302 | | - friend class SelectInst; // For getting `Val`. |
303 | | - friend class ExtractElementInst; // For getting `Val`. |
304 | | - friend class InsertElementInst; // For getting `Val`. |
305 | | - friend class ShuffleVectorInst; // For getting `Val`. |
306 | | - friend class ExtractValueInst; // For getting `Val`. |
307 | | - friend class InsertValueInst; // For getting `Val`. |
308 | | - friend class BranchInst; // For getting `Val`. |
309 | | - friend class LoadInst; // For getting `Val`. |
310 | | - friend class StoreInst; // For getting `Val`. |
311 | | - friend class ReturnInst; // For getting `Val`. |
312 | | - friend class CallBase; // For getting `Val`. |
313 | | - friend class CallInst; // For getting `Val`. |
314 | | - friend class InvokeInst; // For getting `Val`. |
315 | | - friend class CallBrInst; // For getting `Val`. |
316 | | - friend class LandingPadInst; // For getting `Val`. |
317 | | - friend class FuncletPadInst; // For getting `Val`. |
318 | | - friend class CatchPadInst; // For getting `Val`. |
319 | | - friend class CleanupPadInst; // For getting `Val`. |
320 | | - friend class CatchReturnInst; // For getting `Val`. |
321 | | - friend class GetElementPtrInst; // For getting `Val`. |
322 | | - friend class ResumeInst; // For getting `Val`. |
323 | | - friend class CatchSwitchInst; // For getting `Val`. |
324 | | - friend class CleanupReturnInst; // For getting `Val`. |
325 | | - friend class SwitchInst; // For getting `Val`. |
326 | | - friend class UnaryOperator; // For getting `Val`. |
327 | | - friend class BinaryOperator; // For getting `Val`. |
328 | | - friend class AtomicRMWInst; // For getting `Val`. |
329 | | - friend class AtomicCmpXchgInst; // For getting `Val`. |
330 | | - friend class AllocaInst; // For getting `Val`. |
331 | | - friend class CastInst; // For getting `Val`. |
332 | | - friend class PHINode; // For getting `Val`. |
333 | | - friend class UnreachableInst; // For getting `Val`. |
334 | | - friend class CatchSwitchAddHandler; // For `Val`. |
335 | | - friend class CmpInst; // For getting `Val`. |
336 | | - friend class ConstantArray; // For `Val`. |
337 | | - friend class ConstantStruct; // For `Val`. |
338 | | - friend class ConstantAggregateZero; // For `Val`. |
339 | | - friend class ConstantPointerNull; // For `Val`. |
340 | | - friend class UndefValue; // For `Val`. |
341 | | - friend class PoisonValue; // For `Val`. |
342 | | - friend class BlockAddress; // For `Val`. |
343 | | - friend class GlobalValue; // For `Val`. |
344 | | - friend class DSOLocalEquivalent; // For `Val`. |
345 | | - friend class GlobalObject; // For `Val`. |
346 | | - friend class GlobalIFunc; // For `Val`. |
347 | | - friend class GlobalVariable; // For `Val`. |
348 | | - friend class GlobalAlias; // For `Val`. |
349 | | - friend class NoCFIValue; // For `Val`. |
350 | | - friend class ConstantPtrAuth; // For `Val`. |
351 | | - friend class ConstantExpr; // For `Val`. |
352 | | - friend class Utils; // For `Val`. |
353 | | - friend class Module; // For `Val`. |
354 | | - // Region needs to manipulate metadata in the underlying LLVM Value, we don't |
355 | | - // expose metadata in sandboxir. |
356 | | - friend class Region; |
357 | | - |
358 | | - /// All values point to the context. |
359 | | - Context &Ctx; |
360 | | - // This is used by eraseFromParent(). |
361 | | - void clearValue() { Val = nullptr; } |
362 | | - template <typename ItTy, typename SBTy> friend class LLVMOpUserItToSBTy; |
363 | | - |
364 | | - Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx); |
365 | | - /// Disable copies. |
366 | | - Value(const Value &) = delete; |
367 | | - Value &operator=(const Value &) = delete; |
368 | | - |
369 | | -public: |
370 | | - virtual ~Value() = default; |
371 | | - ClassID getSubclassID() const { return SubclassID; } |
372 | | - |
373 | | - using use_iterator = UserUseIterator; |
374 | | - using const_use_iterator = UserUseIterator; |
375 | | - |
376 | | - use_iterator use_begin(); |
377 | | - const_use_iterator use_begin() const { |
378 | | - return const_cast<Value *>(this)->use_begin(); |
379 | | - } |
380 | | - use_iterator use_end() { return use_iterator(Use(nullptr, nullptr, Ctx)); } |
381 | | - const_use_iterator use_end() const { |
382 | | - return const_cast<Value *>(this)->use_end(); |
383 | | - } |
384 | | - |
385 | | - iterator_range<use_iterator> uses() { |
386 | | - return make_range<use_iterator>(use_begin(), use_end()); |
387 | | - } |
388 | | - iterator_range<const_use_iterator> uses() const { |
389 | | - return make_range<const_use_iterator>(use_begin(), use_end()); |
390 | | - } |
391 | | - |
392 | | - /// Helper for mapped_iterator. |
393 | | - struct UseToUser { |
394 | | - User *operator()(const Use &Use) const { return &*Use.getUser(); } |
395 | | - }; |
396 | | - |
397 | | - using user_iterator = mapped_iterator<sandboxir::UserUseIterator, UseToUser>; |
398 | | - using const_user_iterator = user_iterator; |
399 | | - |
400 | | - user_iterator user_begin(); |
401 | | - user_iterator user_end() { |
402 | | - return user_iterator(Use(nullptr, nullptr, Ctx), UseToUser()); |
403 | | - } |
404 | | - const_user_iterator user_begin() const { |
405 | | - return const_cast<Value *>(this)->user_begin(); |
406 | | - } |
407 | | - const_user_iterator user_end() const { |
408 | | - return const_cast<Value *>(this)->user_end(); |
409 | | - } |
410 | | - |
411 | | - iterator_range<user_iterator> users() { |
412 | | - return make_range<user_iterator>(user_begin(), user_end()); |
413 | | - } |
414 | | - iterator_range<const_user_iterator> users() const { |
415 | | - return make_range<const_user_iterator>(user_begin(), user_end()); |
416 | | - } |
417 | | - /// \Returns the number of user edges (not necessarily to unique users). |
418 | | - /// WARNING: This is a linear-time operation. |
419 | | - unsigned getNumUses() const; |
420 | | - /// Return true if this value has N uses or more. |
421 | | - /// This is logically equivalent to getNumUses() >= N. |
422 | | - /// WARNING: This can be expensive, as it is linear to the number of users. |
423 | | - bool hasNUsesOrMore(unsigned Num) const { |
424 | | - unsigned Cnt = 0; |
425 | | - for (auto It = use_begin(), ItE = use_end(); It != ItE; ++It) { |
426 | | - if (++Cnt >= Num) |
427 | | - return true; |
428 | | - } |
429 | | - return false; |
430 | | - } |
431 | | - /// Return true if this Value has exactly N uses. |
432 | | - bool hasNUses(unsigned Num) const { |
433 | | - unsigned Cnt = 0; |
434 | | - for (auto It = use_begin(), ItE = use_end(); It != ItE; ++It) { |
435 | | - if (++Cnt > Num) |
436 | | - return false; |
437 | | - } |
438 | | - return Cnt == Num; |
439 | | - } |
440 | | - |
441 | | - Type *getType() const; |
442 | | - |
443 | | - Context &getContext() const { return Ctx; } |
444 | | - |
445 | | - void replaceUsesWithIf(Value *OtherV, |
446 | | - llvm::function_ref<bool(const Use &)> ShouldReplace); |
447 | | - void replaceAllUsesWith(Value *Other); |
448 | | - |
449 | | - /// \Returns the LLVM IR name of the bottom-most LLVM value. |
450 | | - StringRef getName() const { return Val->getName(); } |
451 | | - |
452 | | -#ifndef NDEBUG |
453 | | - /// Should crash if there is something wrong with the instruction. |
454 | | - virtual void verify() const = 0; |
455 | | - /// Returns the unique id in the form 'SB<number>.' like 'SB1.' |
456 | | - std::string getUid() const; |
457 | | - virtual void dumpCommonHeader(raw_ostream &OS) const; |
458 | | - void dumpCommonFooter(raw_ostream &OS) const; |
459 | | - void dumpCommonPrefix(raw_ostream &OS) const; |
460 | | - void dumpCommonSuffix(raw_ostream &OS) const; |
461 | | - void printAsOperandCommon(raw_ostream &OS) const; |
462 | | - friend raw_ostream &operator<<(raw_ostream &OS, const sandboxir::Value &V) { |
463 | | - V.dumpOS(OS); |
464 | | - return OS; |
465 | | - } |
466 | | - virtual void dumpOS(raw_ostream &OS) const = 0; |
467 | | - LLVM_DUMP_METHOD void dump() const; |
468 | | -#endif |
469 | | -}; |
470 | | - |
471 | 227 | /// Argument of a sandboxir::Function. |
472 | 228 | class Argument : public sandboxir::Value { |
473 | 229 | Argument(llvm::Argument *Arg, sandboxir::Context &Ctx) |
|
0 commit comments