Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===- User.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_USER_H
0010 #define LLVM_SANDBOXIR_USER_H
0011 
0012 #include "llvm/IR/User.h"
0013 #include "llvm/IR/Value.h"
0014 #include "llvm/SandboxIR/Use.h"
0015 #include "llvm/SandboxIR/Value.h"
0016 
0017 namespace llvm::sandboxir {
0018 
0019 class Context;
0020 
0021 /// Iterator for the `Use` edges of a User's operands.
0022 /// \Returns the operand `Use` when dereferenced.
0023 class OperandUseIterator {
0024   sandboxir::Use Use;
0025   /// Don't let the user create a non-empty OperandUseIterator.
0026   OperandUseIterator(const class Use &Use) : Use(Use) {}
0027   friend class User;                                  // For constructor
0028 #define DEF_INSTR(ID, OPC, CLASS) friend class CLASS; // For constructor
0029 #include "llvm/SandboxIR/Values.def"
0030 
0031 public:
0032   using difference_type = std::ptrdiff_t;
0033   using value_type = sandboxir::Use;
0034   using pointer = value_type *;
0035   using reference = value_type &;
0036   using iterator_category = std::input_iterator_tag;
0037 
0038   OperandUseIterator() = default;
0039   value_type operator*() const;
0040   OperandUseIterator &operator++();
0041   OperandUseIterator operator++(int) {
0042     auto Copy = *this;
0043     this->operator++();
0044     return Copy;
0045   }
0046   bool operator==(const OperandUseIterator &Other) const {
0047     return Use == Other.Use;
0048   }
0049   bool operator!=(const OperandUseIterator &Other) const {
0050     return !(*this == Other);
0051   }
0052   OperandUseIterator operator+(unsigned Num) const;
0053   OperandUseIterator operator-(unsigned Num) const;
0054   int operator-(const OperandUseIterator &Other) const;
0055 };
0056 
0057 /// A sandboxir::User has operands.
0058 class User : public Value {
0059 protected:
0060   User(ClassID ID, llvm::Value *V, Context &Ctx) : Value(ID, V, Ctx) {}
0061 
0062   /// \Returns the Use edge that corresponds to \p OpIdx.
0063   /// Note: This is the default implementation that works for instructions that
0064   /// match the underlying LLVM instruction. All others should use a different
0065   /// implementation.
0066   Use getOperandUseDefault(unsigned OpIdx, bool Verify) const;
0067   /// \Returns the Use for the \p OpIdx'th operand. This is virtual to allow
0068   /// instructions to deviate from the LLVM IR operands, which is a requirement
0069   /// for sandboxir Instructions that consist of more than one LLVM Instruction.
0070   virtual Use getOperandUseInternal(unsigned OpIdx, bool Verify) const = 0;
0071   friend class OperandUseIterator; // for getOperandUseInternal()
0072 
0073   /// The default implementation works only for single-LLVMIR-instruction
0074   /// Users and only if they match exactly the LLVM instruction.
0075   unsigned getUseOperandNoDefault(const Use &Use) const {
0076     return Use.LLVMUse->getOperandNo();
0077   }
0078   /// \Returns the operand index of \p Use.
0079   virtual unsigned getUseOperandNo(const Use &Use) const = 0;
0080   friend unsigned Use::getOperandNo() const; // For getUseOperandNo()
0081 
0082   void swapOperandsInternal(unsigned OpIdxA, unsigned OpIdxB) {
0083     assert(OpIdxA < getNumOperands() && "OpIdxA out of bounds!");
0084     assert(OpIdxB < getNumOperands() && "OpIdxB out of bounds!");
0085     auto UseA = getOperandUse(OpIdxA);
0086     auto UseB = getOperandUse(OpIdxB);
0087     UseA.swap(UseB);
0088   }
0089 
0090 #ifndef NDEBUG
0091   void verifyUserOfLLVMUse(const llvm::Use &Use) const;
0092 #endif // NDEBUG
0093 
0094 public:
0095   /// For isa/dyn_cast.
0096   static bool classof(const Value *From);
0097   using op_iterator = OperandUseIterator;
0098   using const_op_iterator = OperandUseIterator;
0099   using op_range = iterator_range<op_iterator>;
0100   using const_op_range = iterator_range<const_op_iterator>;
0101 
0102   virtual op_iterator op_begin() {
0103     assert(isa<llvm::User>(Val) && "Expect User value!");
0104     return op_iterator(getOperandUseInternal(0, /*Verify=*/false));
0105   }
0106   virtual op_iterator op_end() {
0107     assert(isa<llvm::User>(Val) && "Expect User value!");
0108     return op_iterator(
0109         getOperandUseInternal(getNumOperands(), /*Verify=*/false));
0110   }
0111   virtual const_op_iterator op_begin() const {
0112     return const_cast<User *>(this)->op_begin();
0113   }
0114   virtual const_op_iterator op_end() const {
0115     return const_cast<User *>(this)->op_end();
0116   }
0117 
0118   op_range operands() { return make_range<op_iterator>(op_begin(), op_end()); }
0119   const_op_range operands() const {
0120     return make_range<const_op_iterator>(op_begin(), op_end());
0121   }
0122   Value *getOperand(unsigned OpIdx) const { return getOperandUse(OpIdx).get(); }
0123   /// \Returns the operand edge for \p OpIdx. NOTE: This should also work for
0124   /// OpIdx == getNumOperands(), which is used for op_end().
0125   Use getOperandUse(unsigned OpIdx) const {
0126     return getOperandUseInternal(OpIdx, /*Verify=*/true);
0127   }
0128   virtual unsigned getNumOperands() const {
0129     return isa<llvm::User>(Val) ? cast<llvm::User>(Val)->getNumOperands() : 0;
0130   }
0131 
0132   virtual void setOperand(unsigned OperandIdx, Value *Operand);
0133   /// Replaces any operands that match \p FromV with \p ToV. Returns whether any
0134   /// operands were replaced.
0135   bool replaceUsesOfWith(Value *FromV, Value *ToV);
0136 
0137 #ifndef NDEBUG
0138   void verify() const override {
0139     assert(isa<llvm::User>(Val) && "Expected User!");
0140   }
0141   void dumpCommonHeader(raw_ostream &OS) const final;
0142   void dumpOS(raw_ostream &OS) const override {
0143     // TODO: Remove this tmp implementation once we get the Instruction classes.
0144   }
0145 #endif
0146 };
0147 
0148 } // namespace llvm::sandboxir
0149 
0150 #endif // LLVM_SANDBOXIR_USER_H