1 //===- User.cpp - The User class of Sandbox IR ----------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/SandboxIR/User.h"
10 #include "llvm/SandboxIR/Context.h"
12 namespace llvm::sandboxir
{
14 Use
OperandUseIterator::operator*() const { return Use
; }
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);
23 UserUseIterator
&UserUseIterator::operator++() {
24 // Get the corresponding llvm::Use, get the next in the list, and update the
26 llvm::Use
*&LLVMUse
= Use
.LLVMUse
;
27 assert(LLVMUse
!= nullptr && "Already at end!");
28 LLVMUse
= LLVMUse
->getNext();
29 if (LLVMUse
== nullptr) {
34 auto *LLVMUser
= LLVMUse
->getUser();
35 Use
.Usr
= cast_or_null
<sandboxir::User
>(Ctx
->getValue(LLVMUser
));
39 OperandUseIterator
OperandUseIterator::operator+(unsigned Num
) const {
40 sandboxir::Use U
= Use
.getUser()->getOperandUseInternal(
41 Use
.getOperandNo() + Num
, /*Verify=*/true);
42 return OperandUseIterator(U
);
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
);
52 int OperandUseIterator::operator-(const OperandUseIterator
&Other
) const {
53 int ThisOpNo
= Use
.getOperandNo();
54 int OtherOpNo
= Other
.Use
.getOperandNo();
55 return ThisOpNo
- OtherOpNo
;
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!");
62 if (OpIdx
!= getNumOperands())
63 LLVMUse
= &cast
<llvm::User
>(Val
)->getOperandUse(OpIdx
);
65 LLVMUse
= cast
<llvm::User
>(Val
)->op_end();
66 return Use(LLVMUse
, const_cast<User
*>(this), Ctx
);
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!");
76 bool User::classof(const Value
*From
) {
77 switch (From
->getSubclassID()) {
78 #define DEF_VALUE(ID, CLASS)
79 #define DEF_USER(ID, CLASS) \
82 #define DEF_INSTR(ID, OPC, CLASS) \
85 #include "llvm/SandboxIR/Values.def"
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
);
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
);
107 // We are delegating RUOW to LLVM IR's RUOW.
108 return cast
<llvm::User
>(Val
)->replaceUsesOfWith(FromV
->Val
, ToV
->Val
);
112 void User::dumpCommonHeader(raw_ostream
&OS
) const {
113 Value::dumpCommonHeader(OS
);
114 // TODO: This is incomplete
118 } // namespace llvm::sandboxir