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
operator *() const14 Use OperandUseIterator::operator*() const { return Use; }
15
operator ++()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
operator ++()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
operator +(unsigned Num) const39 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
operator -(unsigned Num) const45 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
operator -(const OperandUseIterator & Other) const52 int OperandUseIterator::operator-(const OperandUseIterator &Other) const {
53 int ThisOpNo = Use.getOperandNo();
54 int OtherOpNo = Other.Use.getOperandNo();
55 return ThisOpNo - OtherOpNo;
56 }
57
getOperandUseDefault(unsigned OpIdx,bool Verify) const58 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
verifyUserOfLLVMUse(const llvm::Use & Use) const70 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
classof(const Value * From)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
setOperand(unsigned OperandIdx,Value * Operand)91 void User::setOperand(unsigned OperandIdx, Value *Operand) {
92 assert(isa<llvm::User>(Val) && "No operands!");
93 const auto &U = getOperandUse(OperandIdx);
94 Ctx.getTracker().emplaceIfTracking<UseSet>(U);
95 Ctx.runSetUseCallbacks(U, Operand);
96 // We are delegating to llvm::User::setOperand().
97 cast<llvm::User>(Val)->setOperand(OperandIdx, Operand->Val);
98 }
99
replaceUsesOfWith(Value * FromV,Value * ToV)100 bool User::replaceUsesOfWith(Value *FromV, Value *ToV) {
101 auto &Tracker = Ctx.getTracker();
102 for (auto OpIdx : seq<unsigned>(0, getNumOperands())) {
103 auto Use = getOperandUse(OpIdx);
104 if (Use.get() == FromV) {
105 Ctx.runSetUseCallbacks(Use, ToV);
106 if (Tracker.isTracking())
107 Tracker.emplaceIfTracking<UseSet>(Use);
108 }
109 }
110 // We are delegating RUOW to LLVM IR's RUOW.
111 return cast<llvm::User>(Val)->replaceUsesOfWith(FromV->Val, ToV->Val);
112 }
113
114 #ifndef NDEBUG
dumpCommonHeader(raw_ostream & OS) const115 void User::dumpCommonHeader(raw_ostream &OS) const {
116 Value::dumpCommonHeader(OS);
117 // TODO: This is incomplete
118 }
119 #endif // NDEBUG
120
121 } // namespace llvm::sandboxir
122