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(OpIdx: 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>(Val: Ctx->getValue(V: LLVMUser)); |
36 | return *this; |
37 | } |
38 | |
39 | OperandUseIterator OperandUseIterator::operator+(unsigned Num) const { |
40 | sandboxir::Use U = Use.getUser()->getOperandUseInternal( |
41 | OpIdx: 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 | OpIdx: 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(i: 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 | const auto &U = getOperandUse(OpIdx: OperandIdx); |
94 | Ctx.getTracker().emplaceIfTracking<UseSet>(Args: U); |
95 | Ctx.runSetUseCallbacks(U, NewSrc: Operand); |
96 | // We are delegating to llvm::User::setOperand(). |
97 | cast<llvm::User>(Val)->setOperand(i: OperandIdx, Val: Operand->Val); |
98 | } |
99 | |
100 | bool User::replaceUsesOfWith(Value *FromV, Value *ToV) { |
101 | auto &Tracker = Ctx.getTracker(); |
102 | for (auto OpIdx : seq<unsigned>(Begin: 0, End: getNumOperands())) { |
103 | auto Use = getOperandUse(OpIdx); |
104 | if (Use.get() == FromV) { |
105 | Ctx.runSetUseCallbacks(U: Use, NewSrc: ToV); |
106 | if (Tracker.isTracking()) |
107 | Tracker.emplaceIfTracking<UseSet>(Args: Use); |
108 | } |
109 | } |
110 | // We are delegating RUOW to LLVM IR's RUOW. |
111 | return cast<llvm::User>(Val)->replaceUsesOfWith(From: FromV->Val, To: ToV->Val); |
112 | } |
113 | |
114 | #ifndef NDEBUG |
115 | 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 | |