1 //===- User.cpp - The User class of Sandbox IR ----------------------------===// 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 #include "llvm/SandboxIR/User.h" 10 #include "llvm/SandboxIR/Context.h" 11 12 namespace llvm::sandboxir { 13 14 Use OperandUseIterator::operator*() const { return Use; } 15 16 OperandUseIterator &OperandUseIterator::operator++() { 17 assert(Use.LLVMUse != nullptr && "Already at end!"); 18 User *User = Use.getUser(); 19 Use = User->getOperandUseInternal(Use.getOperandNo() + 1, /*Verify=*/false); 20 return *this; 21 } 22 23 UserUseIterator &UserUseIterator::operator++() { 24 // Get the corresponding llvm::Use, get the next in the list, and update the 25 // sandboxir::Use. 26 llvm::Use *&LLVMUse = Use.LLVMUse; 27 assert(LLVMUse != nullptr && "Already at end!"); 28 LLVMUse = LLVMUse->getNext(); 29 if (LLVMUse == nullptr) { 30 Use.Usr = nullptr; 31 return *this; 32 } 33 auto *Ctx = Use.Ctx; 34 auto *LLVMUser = LLVMUse->getUser(); 35 Use.Usr = cast_or_null<sandboxir::User>(Ctx->getValue(LLVMUser)); 36 return *this; 37 } 38 39 OperandUseIterator OperandUseIterator::operator+(unsigned Num) const { 40 sandboxir::Use U = Use.getUser()->getOperandUseInternal( 41 Use.getOperandNo() + Num, /*Verify=*/true); 42 return OperandUseIterator(U); 43 } 44 45 OperandUseIterator OperandUseIterator::operator-(unsigned Num) const { 46 assert(Use.getOperandNo() >= Num && "Out of bounds!"); 47 sandboxir::Use U = Use.getUser()->getOperandUseInternal( 48 Use.getOperandNo() - Num, /*Verify=*/true); 49 return OperandUseIterator(U); 50 } 51 52 int OperandUseIterator::operator-(const OperandUseIterator &Other) const { 53 int ThisOpNo = Use.getOperandNo(); 54 int OtherOpNo = Other.Use.getOperandNo(); 55 return ThisOpNo - OtherOpNo; 56 } 57 58 Use User::getOperandUseDefault(unsigned OpIdx, bool Verify) const { 59 assert((!Verify || OpIdx < getNumOperands()) && "Out of bounds!"); 60 assert(isa<llvm::User>(Val) && "Non-users have no operands!"); 61 llvm::Use *LLVMUse; 62 if (OpIdx != getNumOperands()) 63 LLVMUse = &cast<llvm::User>(Val)->getOperandUse(OpIdx); 64 else 65 LLVMUse = cast<llvm::User>(Val)->op_end(); 66 return Use(LLVMUse, const_cast<User *>(this), Ctx); 67 } 68 69 #ifndef NDEBUG 70 void User::verifyUserOfLLVMUse(const llvm::Use &Use) const { 71 assert(Ctx.getValue(Use.getUser()) == this && 72 "Use not found in this SBUser's operands!"); 73 } 74 #endif 75 76 bool User::classof(const Value *From) { 77 switch (From->getSubclassID()) { 78 #define DEF_VALUE(ID, CLASS) 79 #define DEF_USER(ID, CLASS) \ 80 case ClassID::ID: \ 81 return true; 82 #define DEF_INSTR(ID, OPC, CLASS) \ 83 case ClassID::ID: \ 84 return true; 85 #include "llvm/SandboxIR/Values.def" 86 default: 87 return false; 88 } 89 } 90 91 void User::setOperand(unsigned OperandIdx, Value *Operand) { 92 assert(isa<llvm::User>(Val) && "No operands!"); 93 Ctx.getTracker().emplaceIfTracking<UseSet>(getOperandUse(OperandIdx)); 94 // We are delegating to llvm::User::setOperand(). 95 cast<llvm::User>(Val)->setOperand(OperandIdx, Operand->Val); 96 } 97 98 bool User::replaceUsesOfWith(Value *FromV, Value *ToV) { 99 auto &Tracker = Ctx.getTracker(); 100 if (Tracker.isTracking()) { 101 for (auto OpIdx : seq<unsigned>(0, getNumOperands())) { 102 auto Use = getOperandUse(OpIdx); 103 if (Use.get() == FromV) 104 Tracker.emplaceIfTracking<UseSet>(Use); 105 } 106 } 107 // We are delegating RUOW to LLVM IR's RUOW. 108 return cast<llvm::User>(Val)->replaceUsesOfWith(FromV->Val, ToV->Val); 109 } 110 111 #ifndef NDEBUG 112 void User::dumpCommonHeader(raw_ostream &OS) const { 113 Value::dumpCommonHeader(OS); 114 // TODO: This is incomplete 115 } 116 #endif // NDEBUG 117 118 } // namespace llvm::sandboxir 119