xref: /llvm-project/llvm/lib/SandboxIR/User.cpp (revision 9e85937b835e82846ab8db53586f0844e6783804)
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