LLVM 20.0.0git
Tracker.h
Go to the documentation of this file.
1//===- Tracker.h ------------------------------------------------*- C++ -*-===//
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// This file is the component of SandboxIR that tracks all changes made to its
10// state, such that we can revert the state when needed.
11//
12// Tracking changes
13// ----------------
14// The user needs to call `Tracker::save()` to enable tracking changes
15// made to SandboxIR. From that point on, any change made to SandboxIR, will
16// automatically create a change tracking object and register it with the
17// tracker. IR-change objects are subclasses of `IRChangeBase` and get
18// registered with the `Tracker::track()` function. The change objects
19// are saved in the order they are registered with the tracker and are stored in
20// the `Tracker::Changes` vector. All of this is done transparently to
21// the user.
22//
23// Reverting changes
24// -----------------
25// Calling `Tracker::revert()` will restore the state saved when
26// `Tracker::save()` was called. Internally this goes through the
27// change objects in `Tracker::Changes` in reverse order, calling their
28// `IRChangeBase::revert()` function one by one.
29//
30// Accepting changes
31// -----------------
32// The user needs to either revert or accept changes before the tracker object
33// is destroyed. This is enforced in the tracker's destructor.
34// This is the job of `Tracker::accept()`. Internally this will go
35// through the change objects in `Tracker::Changes` in order, calling
36// `IRChangeBase::accept()`.
37//
38//===----------------------------------------------------------------------===//
39
40#ifndef LLVM_SANDBOXIR_TRACKER_H
41#define LLVM_SANDBOXIR_TRACKER_H
42
45#include "llvm/IR/IRBuilder.h"
46#include "llvm/IR/Instruction.h"
47#include "llvm/IR/Module.h"
48#include "llvm/SandboxIR/Use.h"
49#include "llvm/Support/Debug.h"
50#include <memory>
51#include <regex>
52
53namespace llvm::sandboxir {
54
55class BasicBlock;
56class Instruction;
57class Tracker;
58
59/// The base class for IR Change classes.
61protected:
63
64public:
66 /// This runs when changes get reverted.
67 virtual void revert() = 0;
68 /// This runs when changes get accepted.
69 virtual void accept() = 0;
70 virtual ~IRChangeBase() = default;
71#ifndef NDEBUG
72 /// \Returns the index of this change by iterating over all changes in the
73 /// tracker. This is only used for debugging.
74 unsigned getIdx() const;
75 void dumpCommon(raw_ostream &OS) const { OS << getIdx() << ". "; }
76 virtual void dump(raw_ostream &OS) const = 0;
77 LLVM_DUMP_METHOD virtual void dump() const = 0;
79 C.dump(OS);
80 return OS;
81 }
82#endif
83};
84
85/// Tracks the change of the source Value of a sandboxir::Use.
86class UseSet : public IRChangeBase {
87 Use U;
88 Value *OrigV = nullptr;
89
90public:
92 : IRChangeBase(Tracker), U(U), OrigV(U.get()) {}
93 void revert() final { U.set(OrigV); }
94 void accept() final {}
95#ifndef NDEBUG
96 void dump(raw_ostream &OS) const final {
98 OS << "UseSet";
99 }
100 LLVM_DUMP_METHOD void dump() const final;
101#endif
102};
103
104/// Tracks swapping a Use with another Use.
105class UseSwap : public IRChangeBase {
106 Use ThisUse;
107 Use OtherUse;
108
109public:
110 UseSwap(const Use &ThisUse, const Use &OtherUse, Tracker &Tracker)
111 : IRChangeBase(Tracker), ThisUse(ThisUse), OtherUse(OtherUse) {
112 assert(ThisUse.getUser() == OtherUse.getUser() && "Expected same user!");
113 }
114 void revert() final { ThisUse.swap(OtherUse); }
115 void accept() final {}
116#ifndef NDEBUG
117 void dump(raw_ostream &OS) const final {
118 dumpCommon(OS);
119 OS << "UseSwap";
120 }
121 LLVM_DUMP_METHOD void dump() const final;
122#endif
123};
124
126 /// Contains all the data we need to restore an "erased" (i.e., detached)
127 /// instruction: the instruction itself and its operands in order.
128 struct InstrAndOperands {
129 /// The operands that got dropped.
131 /// The instruction that got "erased".
132 llvm::Instruction *LLVMI;
133 };
134 /// The instruction data is in reverse program order, which helps create the
135 /// original program order during revert().
137 /// This is either the next Instruction in the stream, or the parent
138 /// BasicBlock if at the end of the BB.
140 /// We take ownership of the "erased" instruction.
141 std::unique_ptr<sandboxir::Value> ErasedIPtr;
142
143public:
144 EraseFromParent(std::unique_ptr<sandboxir::Value> &&IPtr, Tracker &Tracker);
145 void revert() final;
146 void accept() final;
147#ifndef NDEBUG
148 void dump(raw_ostream &OS) const final {
149 dumpCommon(OS);
150 OS << "EraseFromParent";
151 }
152 LLVM_DUMP_METHOD void dump() const final;
154 C.dump(OS);
155 return OS;
156 }
157#endif
158};
159
161 /// The instruction that is about to get removed.
162 Instruction *RemovedI = nullptr;
163 /// This is either the next instr, or the parent BB if at the end of the BB.
165
166public:
168 void revert() final;
169 void accept() final {};
170 Instruction *getInstruction() const { return RemovedI; }
171#ifndef NDEBUG
172 void dump(raw_ostream &OS) const final {
173 dumpCommon(OS);
174 OS << "RemoveFromParent";
175 }
176 LLVM_DUMP_METHOD void dump() const final;
177#endif // NDEBUG
178};
179
180class MoveInstr : public IRChangeBase {
181 /// The instruction that moved.
182 Instruction *MovedI;
183 /// This is either the next instruction in the block, or the parent BB if at
184 /// the end of the BB.
186
187public:
189 void revert() final;
190 void accept() final {}
191#ifndef NDEBUG
192 void dump(raw_ostream &OS) const final {
193 dumpCommon(OS);
194 OS << "MoveInstr";
195 }
196 LLVM_DUMP_METHOD void dump() const final;
197#endif // NDEBUG
198};
199
200/// The tracker collects all the change objects and implements the main API for
201/// saving / reverting / accepting.
202class Tracker {
203public:
204 enum class TrackerState {
205 Disabled, ///> Tracking is disabled
206 Record, ///> Tracking changes
207 };
208
209private:
210 /// The list of changes that are being tracked.
212#ifndef NDEBUG
213 friend unsigned IRChangeBase::getIdx() const; // For accessing `Changes`.
214#endif
215 /// The current state of the tracker.
217 Context &Ctx;
218
219public:
220#ifndef NDEBUG
221 /// Helps catch bugs where we are creating new change objects while in the
222 /// middle of creating other change objects.
224#endif // NDEBUG
225
226 explicit Tracker(Context &Ctx) : Ctx(Ctx) {}
227 ~Tracker();
228 Context &getContext() const { return Ctx; }
229 /// Record \p Change and take ownership. This is the main function used to
230 /// track Sandbox IR changes.
231 void track(std::unique_ptr<IRChangeBase> &&Change);
232 /// \Returns true if the tracker is recording changes.
233 bool isTracking() const { return State == TrackerState::Record; }
234 /// \Returns the current state of the tracker.
235 TrackerState getState() const { return State; }
236 /// Turns on IR tracking.
237 void save();
238 /// Stops tracking and accept changes.
239 void accept();
240 /// Stops tracking and reverts to saved state.
241 void revert();
242
243#ifndef NDEBUG
244 void dump(raw_ostream &OS) const;
245 LLVM_DUMP_METHOD void dump() const;
247 Tracker.dump(OS);
248 return OS;
249 }
250#endif // NDEBUG
251};
252
253} // namespace llvm::sandboxir
254
255#endif // LLVM_SANDBOXIR_TRACKER_H
aarch64 promote const
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:537
#define I(x, y, z)
Definition: MD5.cpp:58
mir Rename Register Operands
Module.h This file contains the declarations for the Module class.
This file defines the PointerUnion class, which is a discriminated union of pointer types.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallVector class.
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
Definition: PointerUnion.h:118
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
void dump(raw_ostream &OS) const final
Definition: Tracker.h:148
void accept() final
This runs when changes get accepted.
Definition: Tracker.cpp:74
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:102
void revert() final
This runs when changes get reverted.
Definition: Tracker.cpp:79
The base class for IR Change classes.
Definition: Tracker.h:60
virtual void revert()=0
This runs when changes get reverted.
void dumpCommon(raw_ostream &OS) const
Definition: Tracker.h:75
virtual LLVM_DUMP_METHOD void dump() const =0
unsigned getIdx() const
\Returns the index of this change by iterating over all changes in the tracker.
Definition: Tracker.cpp:28
friend raw_ostream & operator<<(raw_ostream &OS, const IRChangeBase &C)
Definition: Tracker.h:78
virtual ~IRChangeBase()=default
virtual void accept()=0
This runs when changes get accepted.
virtual void dump(raw_ostream &OS) const =0
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
Definition: SandboxIR.h:496
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:150
void accept() final
This runs when changes get accepted.
Definition: Tracker.h:190
void revert() final
This runs when changes get reverted.
Definition: Tracker.cpp:140
void dump(raw_ostream &OS) const final
Definition: Tracker.h:192
void dump(raw_ostream &OS) const final
Definition: Tracker.h:172
void revert() final
This runs when changes get reverted.
Definition: Tracker.cpp:116
Instruction * getInstruction() const
Definition: Tracker.h:170
void accept() final
This runs when changes get accepted.
Definition: Tracker.h:169
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:126
The tracker collects all the change objects and implements the main API for saving / reverting / acce...
Definition: Tracker.h:202
@ Record
ā€¨Tracking is disabled
void revert()
Stops tracking and reverts to saved state.
Definition: Tracker.cpp:167
TrackerState getState() const
\Returns the current state of the tracker.
Definition: Tracker.h:235
friend raw_ostream & operator<<(raw_ostream &OS, const Tracker &Tracker)
Definition: Tracker.h:246
void dump(raw_ostream &OS) const
Definition: Tracker.cpp:184
bool isTracking() const
\Returns true if the tracker is recording changes.
Definition: Tracker.h:233
void save()
Turns on IR tracking.
Definition: Tracker.cpp:165
Tracker(Context &Ctx)
Definition: Tracker.h:226
bool InMiddleOfCreatingChange
Helps catch bugs where we are creating new change objects while in the middle of creating other chang...
Definition: Tracker.h:223
Context & getContext() const
Definition: Tracker.h:228
void track(std::unique_ptr< IRChangeBase > &&Change)
Record Change and take ownership.
Definition: Tracker.cpp:156
void accept()
Stops tracking and accept changes.
Definition: Tracker.cpp:175
LLVM_DUMP_METHOD void dump() const
Definition: Tracker.cpp:190
Tracks the change of the source Value of a sandboxir::Use.
Definition: Tracker.h:86
UseSet(const Use &U, Tracker &Tracker)
Definition: Tracker.h:91
void dump(raw_ostream &OS) const final
Definition: Tracker.h:96
void accept() final
This runs when changes get accepted.
Definition: Tracker.h:94
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:34
void revert() final
This runs when changes get reverted.
Definition: Tracker.h:93
Tracks swapping a Use with another Use.
Definition: Tracker.h:105
void revert() final
This runs when changes get reverted.
Definition: Tracker.h:114
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:39
void accept() final
This runs when changes get accepted.
Definition: Tracker.h:115
void dump(raw_ostream &OS) const final
Definition: Tracker.h:117
UseSwap(const Use &ThisUse, const Use &OtherUse, Tracker &Tracker)
Definition: Tracker.h:110
Represents a Def-use/Use-def edge in SandboxIR.
Definition: Use.h:29
void swap(Use &OtherUse)
Definition: SandboxIR.cpp:23
class User * getUser() const
Definition: Use.h:48
A SandboxIR Value has users. This is the base class.
Definition: SandboxIR.h:141
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition: ISDOpcodes.h:71
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)