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