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