17a2c5c69Svporpo //===- User.cpp - The User class of Sandbox IR ----------------------------===// 27a2c5c69Svporpo // 37a2c5c69Svporpo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 47a2c5c69Svporpo // See https://llvm.org/LICENSE.txt for license information. 57a2c5c69Svporpo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 67a2c5c69Svporpo // 77a2c5c69Svporpo //===----------------------------------------------------------------------===// 87a2c5c69Svporpo 97a2c5c69Svporpo #include "llvm/SandboxIR/User.h" 107a2c5c69Svporpo #include "llvm/SandboxIR/Context.h" 117a2c5c69Svporpo 127a2c5c69Svporpo namespace llvm::sandboxir { 137a2c5c69Svporpo 1437239461Svporpo Use OperandUseIterator::operator*() const { return Use; } 1537239461Svporpo 1637239461Svporpo OperandUseIterator &OperandUseIterator::operator++() { 1737239461Svporpo assert(Use.LLVMUse != nullptr && "Already at end!"); 1837239461Svporpo User *User = Use.getUser(); 1937239461Svporpo Use = User->getOperandUseInternal(Use.getOperandNo() + 1, /*Verify=*/false); 2037239461Svporpo return *this; 2137239461Svporpo } 2237239461Svporpo 2337239461Svporpo UserUseIterator &UserUseIterator::operator++() { 2437239461Svporpo // Get the corresponding llvm::Use, get the next in the list, and update the 2537239461Svporpo // sandboxir::Use. 2637239461Svporpo llvm::Use *&LLVMUse = Use.LLVMUse; 2737239461Svporpo assert(LLVMUse != nullptr && "Already at end!"); 2837239461Svporpo LLVMUse = LLVMUse->getNext(); 2937239461Svporpo if (LLVMUse == nullptr) { 3037239461Svporpo Use.Usr = nullptr; 3137239461Svporpo return *this; 3237239461Svporpo } 3337239461Svporpo auto *Ctx = Use.Ctx; 3437239461Svporpo auto *LLVMUser = LLVMUse->getUser(); 3537239461Svporpo Use.Usr = cast_or_null<sandboxir::User>(Ctx->getValue(LLVMUser)); 3637239461Svporpo return *this; 3737239461Svporpo } 3837239461Svporpo 3937239461Svporpo OperandUseIterator OperandUseIterator::operator+(unsigned Num) const { 4037239461Svporpo sandboxir::Use U = Use.getUser()->getOperandUseInternal( 4137239461Svporpo Use.getOperandNo() + Num, /*Verify=*/true); 4237239461Svporpo return OperandUseIterator(U); 4337239461Svporpo } 4437239461Svporpo 4537239461Svporpo OperandUseIterator OperandUseIterator::operator-(unsigned Num) const { 4637239461Svporpo assert(Use.getOperandNo() >= Num && "Out of bounds!"); 4737239461Svporpo sandboxir::Use U = Use.getUser()->getOperandUseInternal( 4837239461Svporpo Use.getOperandNo() - Num, /*Verify=*/true); 4937239461Svporpo return OperandUseIterator(U); 5037239461Svporpo } 5137239461Svporpo 5237239461Svporpo int OperandUseIterator::operator-(const OperandUseIterator &Other) const { 5337239461Svporpo int ThisOpNo = Use.getOperandNo(); 5437239461Svporpo int OtherOpNo = Other.Use.getOperandNo(); 5537239461Svporpo return ThisOpNo - OtherOpNo; 5637239461Svporpo } 5737239461Svporpo 587a2c5c69Svporpo Use User::getOperandUseDefault(unsigned OpIdx, bool Verify) const { 597a2c5c69Svporpo assert((!Verify || OpIdx < getNumOperands()) && "Out of bounds!"); 607a2c5c69Svporpo assert(isa<llvm::User>(Val) && "Non-users have no operands!"); 617a2c5c69Svporpo llvm::Use *LLVMUse; 627a2c5c69Svporpo if (OpIdx != getNumOperands()) 637a2c5c69Svporpo LLVMUse = &cast<llvm::User>(Val)->getOperandUse(OpIdx); 647a2c5c69Svporpo else 657a2c5c69Svporpo LLVMUse = cast<llvm::User>(Val)->op_end(); 667a2c5c69Svporpo return Use(LLVMUse, const_cast<User *>(this), Ctx); 677a2c5c69Svporpo } 687a2c5c69Svporpo 697a2c5c69Svporpo #ifndef NDEBUG 707a2c5c69Svporpo void User::verifyUserOfLLVMUse(const llvm::Use &Use) const { 717a2c5c69Svporpo assert(Ctx.getValue(Use.getUser()) == this && 727a2c5c69Svporpo "Use not found in this SBUser's operands!"); 737a2c5c69Svporpo } 747a2c5c69Svporpo #endif 757a2c5c69Svporpo 767a2c5c69Svporpo bool User::classof(const Value *From) { 777a2c5c69Svporpo switch (From->getSubclassID()) { 787a2c5c69Svporpo #define DEF_VALUE(ID, CLASS) 797a2c5c69Svporpo #define DEF_USER(ID, CLASS) \ 807a2c5c69Svporpo case ClassID::ID: \ 817a2c5c69Svporpo return true; 827a2c5c69Svporpo #define DEF_INSTR(ID, OPC, CLASS) \ 837a2c5c69Svporpo case ClassID::ID: \ 847a2c5c69Svporpo return true; 85*9e85937bSvporpo #include "llvm/SandboxIR/Values.def" 867a2c5c69Svporpo default: 877a2c5c69Svporpo return false; 887a2c5c69Svporpo } 897a2c5c69Svporpo } 907a2c5c69Svporpo 917a2c5c69Svporpo void User::setOperand(unsigned OperandIdx, Value *Operand) { 927a2c5c69Svporpo assert(isa<llvm::User>(Val) && "No operands!"); 937a2c5c69Svporpo Ctx.getTracker().emplaceIfTracking<UseSet>(getOperandUse(OperandIdx)); 947a2c5c69Svporpo // We are delegating to llvm::User::setOperand(). 957a2c5c69Svporpo cast<llvm::User>(Val)->setOperand(OperandIdx, Operand->Val); 967a2c5c69Svporpo } 977a2c5c69Svporpo 987a2c5c69Svporpo bool User::replaceUsesOfWith(Value *FromV, Value *ToV) { 997a2c5c69Svporpo auto &Tracker = Ctx.getTracker(); 1007a2c5c69Svporpo if (Tracker.isTracking()) { 1017a2c5c69Svporpo for (auto OpIdx : seq<unsigned>(0, getNumOperands())) { 1027a2c5c69Svporpo auto Use = getOperandUse(OpIdx); 1037a2c5c69Svporpo if (Use.get() == FromV) 1047a2c5c69Svporpo Tracker.emplaceIfTracking<UseSet>(Use); 1057a2c5c69Svporpo } 1067a2c5c69Svporpo } 1077a2c5c69Svporpo // We are delegating RUOW to LLVM IR's RUOW. 1087a2c5c69Svporpo return cast<llvm::User>(Val)->replaceUsesOfWith(FromV->Val, ToV->Val); 1097a2c5c69Svporpo } 1107a2c5c69Svporpo 1117a2c5c69Svporpo #ifndef NDEBUG 1127a2c5c69Svporpo void User::dumpCommonHeader(raw_ostream &OS) const { 1137a2c5c69Svporpo Value::dumpCommonHeader(OS); 1147a2c5c69Svporpo // TODO: This is incomplete 1157a2c5c69Svporpo } 1167a2c5c69Svporpo #endif // NDEBUG 1177a2c5c69Svporpo 1187a2c5c69Svporpo } // namespace llvm::sandboxir 119