LLVM 19.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
18IRChangeBase::IRChangeBase(Tracker &Parent) : Parent(Parent) {
19#ifndef NDEBUG
21 "We are in the middle of creating another change!");
22 if (Parent.isTracking())
24#endif // NDEBUG
25}
26
27#ifndef NDEBUG
28unsigned IRChangeBase::getIdx() const {
29 auto It =
30 find_if(Parent.Changes, [this](auto &Ptr) { return Ptr.get() == this; });
31 return It - Parent.Changes.begin();
32}
33
34void UseSet::dump() const {
35 dump(dbgs());
36 dbgs() << "\n";
37}
38#endif // NDEBUG
39
41 assert(Changes.empty() && "You must accept or revert changes!");
42}
43
44EraseFromParent::EraseFromParent(std::unique_ptr<sandboxir::Value> &&ErasedIPtr,
46 : IRChangeBase(Tracker), ErasedIPtr(std::move(ErasedIPtr)) {
47 auto *I = cast<Instruction>(this->ErasedIPtr.get());
48 auto LLVMInstrs = I->getLLVMInstrs();
49 // Iterate in reverse program order.
50 for (auto *LLVMI : reverse(LLVMInstrs)) {
52 Operands.reserve(LLVMI->getNumOperands());
53 for (auto [OpNum, Use] : enumerate(LLVMI->operands()))
54 Operands.push_back(Use.get());
55 InstrData.push_back({Operands, LLVMI});
56 }
57 assert(is_sorted(InstrData,
58 [](const auto &D0, const auto &D1) {
59 return D0.LLVMI->comesBefore(D1.LLVMI);
60 }) &&
61 "Expected reverse program order!");
62 auto *BotLLVMI = cast<llvm::Instruction>(I->Val);
63 if (BotLLVMI->getNextNode() != nullptr)
64 NextLLVMIOrBB = BotLLVMI->getNextNode();
65 else
66 NextLLVMIOrBB = BotLLVMI->getParent();
67}
68
70 for (const auto &IData : InstrData)
71 IData.LLVMI->deleteValue();
72}
73
75 // Place the bottom-most instruction first.
76 auto [Operands, BotLLVMI] = InstrData[0];
77 if (auto *NextLLVMI = NextLLVMIOrBB.dyn_cast<llvm::Instruction *>()) {
78 BotLLVMI->insertBefore(NextLLVMI);
79 } else {
80 auto *LLVMBB = NextLLVMIOrBB.get<llvm::BasicBlock *>();
81 BotLLVMI->insertInto(LLVMBB, LLVMBB->end());
82 }
83 for (auto [OpNum, Op] : enumerate(Operands))
84 BotLLVMI->setOperand(OpNum, Op);
85
86 // Go over the rest of the instructions and stack them on top.
87 for (auto [Operands, LLVMI] : drop_begin(InstrData)) {
88 LLVMI->insertBefore(BotLLVMI);
89 for (auto [OpNum, Op] : enumerate(Operands))
90 LLVMI->setOperand(OpNum, Op);
91 BotLLVMI = LLVMI;
92 }
93 Parent.getContext().registerValue(std::move(ErasedIPtr));
94}
95
96#ifndef NDEBUG
98 dump(dbgs());
99 dbgs() << "\n";
100}
101#endif // NDEBUG
102
104 : IRChangeBase(Tracker), RemovedI(RemovedI) {
105 if (auto *NextI = RemovedI->getNextNode())
106 NextInstrOrBB = NextI;
107 else
108 NextInstrOrBB = RemovedI->getParent();
109}
110
112 if (auto *NextI = NextInstrOrBB.dyn_cast<Instruction *>()) {
113 RemovedI->insertBefore(NextI);
114 } else {
115 auto *BB = NextInstrOrBB.get<BasicBlock *>();
116 RemovedI->insertInto(BB, BB->end());
117 }
118}
119
120#ifndef NDEBUG
122 dump(dbgs());
123 dbgs() << "\n";
124}
125#endif
126
128 : IRChangeBase(Tracker), MovedI(MovedI) {
129 if (auto *NextI = MovedI->getNextNode())
130 NextInstrOrBB = NextI;
131 else
132 NextInstrOrBB = MovedI->getParent();
133}
134
136 if (auto *NextI = NextInstrOrBB.dyn_cast<Instruction *>()) {
137 MovedI->moveBefore(NextI);
138 } else {
139 auto *BB = NextInstrOrBB.get<BasicBlock *>();
140 MovedI->moveBefore(*BB, BB->end());
141 }
142}
143
144#ifndef NDEBUG
145void MoveInstr::dump() const {
146 dump(dbgs());
147 dbgs() << "\n";
148}
149#endif
150
151void Tracker::track(std::unique_ptr<IRChangeBase> &&Change) {
152 assert(State == TrackerState::Record && "The tracker should be tracking!");
153 Changes.push_back(std::move(Change));
154
155#ifndef NDEBUG
157#endif
158}
159
161
163 assert(State == TrackerState::Record && "Forgot to save()!");
165 for (auto &Change : reverse(Changes))
166 Change->revert();
167 Changes.clear();
168}
169
171 assert(State == TrackerState::Record && "Forgot to save()!");
173 for (auto &Change : Changes)
174 Change->accept();
175 Changes.clear();
176}
177
178#ifndef NDEBUG
180 for (const auto &ChangePtr : Changes) {
181 ChangePtr->dump(OS);
182 OS << "\n";
183 }
184}
185void Tracker::dump() const {
186 dump(dbgs());
187 dbgs() << "\n";
188}
189#endif // NDEBUG
#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:640
Value * registerValue(std::unique_ptr< Value > &&VPtr)
Take ownership of VPtr and store it in LLVMValueToValueMap.
Definition: SandboxIR.cpp:580
EraseFromParent(std::unique_ptr< sandboxir::Value > &&IPtr, Tracker &Tracker)
Definition: Tracker.cpp:44
void accept() final
This runs when changes get accepted.
Definition: Tracker.cpp:69
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:97
void revert() final
This runs when changes get reverted.
Definition: Tracker.cpp:74
The base class for IR Change classes.
Definition: Tracker.h:60
IRChangeBase(Tracker &Parent)
Definition: Tracker.cpp:18
unsigned getIdx() const
\Returns the index of this change by iterating over all changes in the tracker.
Definition: Tracker.cpp:28
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
Definition: SandboxIR.h:478
void insertInto(BasicBlock *BB, const BBIterator &WhereIt)
Insert this detached instruction into BB at WhereIt.
Definition: SandboxIR.cpp:411
Instruction * getNextNode() const
\Returns the next sandboxir::Instruction in the block, or nullptr if at the end of the block.
Definition: SandboxIR.cpp:312
void moveBefore(BasicBlock &BB, const BBIterator &WhereIt)
Move this instruction to WhereIt.
Definition: SandboxIR.cpp:370
void insertBefore(Instruction *BeforeI)
Insert this detached instruction before BeforeI.
Definition: SandboxIR.cpp:396
BasicBlock * getParent() const
\Returns the BasicBlock containing this Instruction, or null if it is detached.
Definition: SandboxIR.cpp:428
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:145
void revert() final
This runs when changes get reverted.
Definition: Tracker.cpp:135
MoveInstr(sandboxir::Instruction *I, Tracker &Tracker)
Definition: Tracker.cpp:127
void revert() final
This runs when changes get reverted.
Definition: Tracker.cpp:111
RemoveFromParent(Instruction *RemovedI, Tracker &Tracker)
Definition: Tracker.cpp:103
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:121
The tracker collects all the change objects and implements the main API for saving / reverting / acce...
Definition: Tracker.h:181
@ Record
ā€¨Tracking is disabled
void revert()
Stops tracking and reverts to saved state.
Definition: Tracker.cpp:162
bool isTracking() const
\Returns true if the tracker is recording changes.
Definition: Tracker.h:212
void save()
Turns on IR tracking.
Definition: Tracker.cpp:160
bool InMiddleOfCreatingChange
Helps catch bugs where we are creating new change objects while in the middle of creating other chang...
Definition: Tracker.h:202
Context & getContext() const
Definition: Tracker.h:207
void track(std::unique_ptr< IRChangeBase > &&Change)
Record Change and take ownership.
Definition: Tracker.cpp:151
void accept()
Stops tracking and accept changes.
Definition: Tracker.cpp:170
LLVM_DUMP_METHOD void dump() const
Definition: Tracker.cpp:185
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:34
Represents a Def-use/Use-def edge in SandboxIR.
Definition: Use.h:29
Value * get() const
Definition: SandboxIR.cpp:17
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 are tuples (A,...
Definition: STLExtras.h:2400
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:1902
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:1849
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1749
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858