LLVM 20.0.0git
Tracker.cpp
Go to the documentation of this file.
1//===- Tracker.cpp --------------------------------------------------------===//
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
10#include "llvm/ADT/STLExtras.h"
11#include "llvm/IR/BasicBlock.h"
12#include "llvm/IR/Instruction.h"
14#include <sstream>
15
16using namespace llvm::sandboxir;
17
18#ifndef NDEBUG
19void UseSet::dump() const {
20 dump(dbgs());
21 dbgs() << "\n";
22}
23
24void UseSwap::dump() const {
25 dump(dbgs());
26 dbgs() << "\n";
27}
28#endif // NDEBUG
29
31 : PHI(PHI), RemovedIdx(RemovedIdx) {
32 RemovedV = PHI->getIncomingValue(RemovedIdx);
33 RemovedBB = PHI->getIncomingBlock(RemovedIdx);
34}
35
37 // Special case: if the PHI is now empty, as we don't need to care about the
38 // order of the incoming values.
39 unsigned NumIncoming = PHI->getNumIncomingValues();
40 if (NumIncoming == 0) {
41 PHI->addIncoming(RemovedV, RemovedBB);
42 return;
43 }
44 // Shift all incoming values by one starting from the end until `Idx`.
45 // Start by adding a copy of the last incoming values.
46 unsigned LastIdx = NumIncoming - 1;
47 PHI->addIncoming(PHI->getIncomingValue(LastIdx),
48 PHI->getIncomingBlock(LastIdx));
49 for (unsigned Idx = LastIdx; Idx > RemovedIdx; --Idx) {
50 auto *PrevV = PHI->getIncomingValue(Idx - 1);
51 auto *PrevBB = PHI->getIncomingBlock(Idx - 1);
52 PHI->setIncomingValue(Idx, PrevV);
53 PHI->setIncomingBlock(Idx, PrevBB);
54 }
55 PHI->setIncomingValue(RemovedIdx, RemovedV);
56 PHI->setIncomingBlock(RemovedIdx, RemovedBB);
57}
58
59#ifndef NDEBUG
61 dump(dbgs());
62 dbgs() << "\n";
63}
64#endif // NDEBUG
65
67 : PHI(PHI), Idx(PHI->getNumIncomingValues()) {}
68
70
71#ifndef NDEBUG
73 dump(dbgs());
74 dbgs() << "\n";
75}
76#endif // NDEBUG
77
79 assert(Changes.empty() && "You must accept or revert changes!");
80}
81
82EraseFromParent::EraseFromParent(std::unique_ptr<sandboxir::Value> &&ErasedIPtr)
83 : ErasedIPtr(std::move(ErasedIPtr)) {
84 auto *I = cast<Instruction>(this->ErasedIPtr.get());
85 auto LLVMInstrs = I->getLLVMInstrs();
86 // Iterate in reverse program order.
87 for (auto *LLVMI : reverse(LLVMInstrs)) {
89 Operands.reserve(LLVMI->getNumOperands());
90 for (auto [OpNum, Use] : enumerate(LLVMI->operands()))
91 Operands.push_back(Use.get());
92 InstrData.push_back({Operands, LLVMI});
93 }
94 assert(is_sorted(InstrData,
95 [](const auto &D0, const auto &D1) {
96 return D0.LLVMI->comesBefore(D1.LLVMI);
97 }) &&
98 "Expected reverse program order!");
99 auto *BotLLVMI = cast<llvm::Instruction>(I->Val);
100 if (BotLLVMI->getNextNode() != nullptr)
101 NextLLVMIOrBB = BotLLVMI->getNextNode();
102 else
103 NextLLVMIOrBB = BotLLVMI->getParent();
104}
105
107 for (const auto &IData : InstrData)
108 IData.LLVMI->deleteValue();
109}
110
112 // Place the bottom-most instruction first.
113 auto [Operands, BotLLVMI] = InstrData[0];
114 if (auto *NextLLVMI = NextLLVMIOrBB.dyn_cast<llvm::Instruction *>()) {
115 BotLLVMI->insertBefore(NextLLVMI);
116 } else {
117 auto *LLVMBB = NextLLVMIOrBB.get<llvm::BasicBlock *>();
118 BotLLVMI->insertInto(LLVMBB, LLVMBB->end());
119 }
120 for (auto [OpNum, Op] : enumerate(Operands))
121 BotLLVMI->setOperand(OpNum, Op);
122
123 // Go over the rest of the instructions and stack them on top.
124 for (auto [Operands, LLVMI] : drop_begin(InstrData)) {
125 LLVMI->insertBefore(BotLLVMI);
126 for (auto [OpNum, Op] : enumerate(Operands))
127 LLVMI->setOperand(OpNum, Op);
128 BotLLVMI = LLVMI;
129 }
130 Tracker.getContext().registerValue(std::move(ErasedIPtr));
131}
132
133#ifndef NDEBUG
135 dump(dbgs());
136 dbgs() << "\n";
137}
138#endif // NDEBUG
139
140RemoveFromParent::RemoveFromParent(Instruction *RemovedI) : RemovedI(RemovedI) {
141 if (auto *NextI = RemovedI->getNextNode())
142 NextInstrOrBB = NextI;
143 else
144 NextInstrOrBB = RemovedI->getParent();
145}
146
148 if (auto *NextI = NextInstrOrBB.dyn_cast<Instruction *>()) {
149 RemovedI->insertBefore(NextI);
150 } else {
151 auto *BB = NextInstrOrBB.get<BasicBlock *>();
152 RemovedI->insertInto(BB, BB->end());
153 }
154}
155
156#ifndef NDEBUG
158 dump(dbgs());
159 dbgs() << "\n";
160}
161#endif
162
163void SwitchRemoveCase::revert(Tracker &Tracker) { Switch->addCase(Val, Dest); }
164
165#ifndef NDEBUG
167 dump(dbgs());
168 dbgs() << "\n";
169}
170#endif // NDEBUG
171
173 auto It = Switch->findCaseValue(Val);
174 Switch->removeCase(It);
175}
176
177#ifndef NDEBUG
179 dump(dbgs());
180 dbgs() << "\n";
181}
182#endif // NDEBUG
183
184MoveInstr::MoveInstr(Instruction *MovedI) : MovedI(MovedI) {
185 if (auto *NextI = MovedI->getNextNode())
186 NextInstrOrBB = NextI;
187 else
188 NextInstrOrBB = MovedI->getParent();
189}
190
192 if (auto *NextI = NextInstrOrBB.dyn_cast<Instruction *>()) {
193 MovedI->moveBefore(NextI);
194 } else {
195 auto *BB = NextInstrOrBB.get<BasicBlock *>();
196 MovedI->moveBefore(*BB, BB->end());
197 }
198}
199
200#ifndef NDEBUG
201void MoveInstr::dump() const {
202 dump(dbgs());
203 dbgs() << "\n";
204}
205#endif
206
208
209InsertIntoBB::InsertIntoBB(Instruction *InsertedI) : InsertedI(InsertedI) {}
210
211#ifndef NDEBUG
212void InsertIntoBB::dump() const {
213 dump(dbgs());
214 dbgs() << "\n";
215}
216#endif
217
219
220#ifndef NDEBUG
222 dump(dbgs());
223 dbgs() << "\n";
224}
225#endif
226
228
230 assert(State == TrackerState::Record && "Forgot to save()!");
232 for (auto &Change : reverse(Changes))
233 Change->revert(*this);
234 Changes.clear();
235}
236
238 assert(State == TrackerState::Record && "Forgot to save()!");
240 for (auto &Change : Changes)
241 Change->accept();
242 Changes.clear();
243}
244
245#ifndef NDEBUG
247 for (auto [Idx, ChangePtr] : enumerate(Changes)) {
248 OS << Idx << ". ";
249 ChangePtr->dump(OS);
250 OS << "\n";
251 }
252}
253void Tracker::dump() const {
254 dump(dbgs());
255 dbgs() << "\n";
256}
257#endif // NDEBUG
Rewrite undef for PHI
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define I(x, y, z)
Definition: MD5.cpp:58
mir Rename Register Operands
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
void insertInto(Function *Parent, BasicBlock *InsertBefore=nullptr)
Insert unlinked basic block into a function.
Definition: BasicBlock.cpp:198
This class represents an Operation in the Expression.
T get() const
Returns the value of the specified pointer type.
Definition: PointerUnion.h:155
T dyn_cast() const
Returns the current pointer if it is of the specified pointer type, otherwise returns null.
Definition: PointerUnion.h:162
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
Contains a list of sandboxir::Instruction's.
Definition: SandboxIR.h:600
Value * registerValue(std::unique_ptr< Value > &&VPtr)
Take ownership of VPtr and store it in LLVMValueToValueMap.
Definition: SandboxIR.cpp:1846
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:221
void revert(Tracker &Tracker) final
This runs when changes get reverted.
Definition: Tracker.cpp:218
void accept() final
This runs when changes get accepted.
Definition: Tracker.cpp:106
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:134
void revert(Tracker &Tracker) final
This runs when changes get reverted.
Definition: Tracker.cpp:111
EraseFromParent(std::unique_ptr< sandboxir::Value > &&IPtr)
Definition: Tracker.cpp:82
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:212
InsertIntoBB(Instruction *InsertedI)
Definition: Tracker.cpp:209
void revert(Tracker &Tracker) final
This runs when changes get reverted.
Definition: Tracker.cpp:207
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
Definition: SandboxIR.h:647
void removeFromParent()
Detach this from its parent BasicBlock without deleting it.
Definition: SandboxIR.cpp:359
void insertInto(BasicBlock *BB, const BBIterator &WhereIt)
Insert this detached instruction into BB at WhereIt.
Definition: SandboxIR.cpp:433
void eraseFromParent()
Detach this Value from its parent and delete it.
Definition: SandboxIR.cpp:367
Instruction * getNextNode() const
\Returns the next sandboxir::Instruction in the block, or nullptr if at the end of the block.
Definition: SandboxIR.cpp:336
void moveBefore(BasicBlock &BB, const BBIterator &WhereIt)
Move this instruction to WhereIt.
Definition: SandboxIR.cpp:391
void insertBefore(Instruction *BeforeI)
Insert this detached instruction before BeforeI.
Definition: SandboxIR.cpp:415
BasicBlock * getParent() const
\Returns the BasicBlock containing this Instruction, or null if it is detached.
Definition: SandboxIR.cpp:455
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:201
MoveInstr(sandboxir::Instruction *I)
Definition: Tracker.cpp:184
void revert(Tracker &Tracker) final
This runs when changes get reverted.
Definition: Tracker.cpp:191
void revert(Tracker &Tracker) final
This runs when changes get reverted.
Definition: Tracker.cpp:69
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:72
void setIncomingBlock(unsigned Idx, BasicBlock *BB)
Definition: SandboxIR.cpp:1123
void setIncomingValue(unsigned Idx, Value *V)
Definition: SandboxIR.cpp:1107
unsigned getNumIncomingValues() const
Definition: SandboxIR.h:2080
void addIncoming(Value *V, BasicBlock *BB)
Definition: SandboxIR.cpp:1134
Value * removeIncomingValue(unsigned Idx)
Definition: SandboxIR.cpp:1141
BasicBlock * getIncomingBlock(unsigned Idx) const
Definition: SandboxIR.cpp:1114
Value * getIncomingValue(unsigned Idx) const
Definition: SandboxIR.cpp:1104
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:60
PHIRemoveIncoming(PHINode *PHI, unsigned RemovedIdx)
Definition: Tracker.cpp:30
void revert(Tracker &Tracker) final
This runs when changes get reverted.
Definition: Tracker.cpp:36
void revert(Tracker &Tracker) final
This runs when changes get reverted.
Definition: Tracker.cpp:147
RemoveFromParent(Instruction *RemovedI)
Definition: Tracker.cpp:140
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:157
void revert(Tracker &Tracker) final
This runs when changes get reverted.
Definition: Tracker.cpp:172
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:178
CaseIt findCaseValue(const ConstantInt *C)
Definition: SandboxIR.h:1533
void addCase(ConstantInt *OnVal, BasicBlock *Dest)
Definition: SandboxIR.cpp:1283
CaseIt removeCase(CaseIt It)
This method removes the specified case and its successor from the switch instruction.
Definition: SandboxIR.cpp:1290
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:166
void revert(Tracker &Tracker) final
This runs when changes get reverted.
Definition: Tracker.cpp:163
The tracker collects all the change objects and implements the main API for saving / reverting / acce...
Definition: Tracker.h:342
@ Record
ā€¨Tracking is disabled
void revert()
Stops tracking and reverts to saved state.
Definition: Tracker.cpp:229
void save()
Turns on IR tracking.
Definition: Tracker.cpp:227
Context & getContext() const
Definition: Tracker.h:365
void accept()
Stops tracking and accept changes.
Definition: Tracker.cpp:237
LLVM_DUMP_METHOD void dump() const
Definition: Tracker.cpp:253
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:19
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:24
Represents a Def-use/Use-def edge in SandboxIR.
Definition: Use.h:32
Value * get() const
Definition: SandboxIR.cpp:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition: STLExtras.h:2431
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:419
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition: STLExtras.h:1909
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1856
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858