LLVM 19.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
105 /// Contains all the data we need to restore an "erased" (i.e., detached)
106 /// instruction: the instruction itself and its operands in order.
107 struct InstrAndOperands {
108 /// The operands that got dropped.
110 /// The instruction that got "erased".
111 llvm::Instruction *LLVMI;
112 };
113 /// The instruction data is in reverse program order, which helps create the
114 /// original program order during revert().
116 /// This is either the next Instruction in the stream, or the parent
117 /// BasicBlock if at the end of the BB.
119 /// We take ownership of the "erased" instruction.
120 std::unique_ptr<sandboxir::Value> ErasedIPtr;
121
122public:
123 EraseFromParent(std::unique_ptr<sandboxir::Value> &&IPtr, Tracker &Tracker);
124 void revert() final;
125 void accept() final;
126#ifndef NDEBUG
127 void dump(raw_ostream &OS) const final {
128 dumpCommon(OS);
129 OS << "EraseFromParent";
130 }
131 LLVM_DUMP_METHOD void dump() const final;
133 C.dump(OS);
134 return OS;
135 }
136#endif
137};
138
140 /// The instruction that is about to get removed.
141 Instruction *RemovedI = nullptr;
142 /// This is either the next instr, or the parent BB if at the end of the BB.
144
145public:
147 void revert() final;
148 void accept() final {};
149 Instruction *getInstruction() const { return RemovedI; }
150#ifndef NDEBUG
151 void dump(raw_ostream &OS) const final {
152 dumpCommon(OS);
153 OS << "RemoveFromParent";
154 }
155 LLVM_DUMP_METHOD void dump() const final;
156#endif // NDEBUG
157};
158
159class MoveInstr : public IRChangeBase {
160 /// The instruction that moved.
161 Instruction *MovedI;
162 /// This is either the next instruction in the block, or the parent BB if at
163 /// the end of the BB.
165
166public:
168 void revert() final;
169 void accept() final {}
170#ifndef NDEBUG
171 void dump(raw_ostream &OS) const final {
172 dumpCommon(OS);
173 OS << "MoveInstr";
174 }
175 LLVM_DUMP_METHOD void dump() const final;
176#endif // NDEBUG
177};
178
179/// The tracker collects all the change objects and implements the main API for
180/// saving / reverting / accepting.
181class Tracker {
182public:
183 enum class TrackerState {
184 Disabled, ///> Tracking is disabled
185 Record, ///> Tracking changes
186 };
187
188private:
189 /// The list of changes that are being tracked.
191#ifndef NDEBUG
192 friend unsigned IRChangeBase::getIdx() const; // For accessing `Changes`.
193#endif
194 /// The current state of the tracker.
196 Context &Ctx;
197
198public:
199#ifndef NDEBUG
200 /// Helps catch bugs where we are creating new change objects while in the
201 /// middle of creating other change objects.
203#endif // NDEBUG
204
205 explicit Tracker(Context &Ctx) : Ctx(Ctx) {}
206 ~Tracker();
207 Context &getContext() const { return Ctx; }
208 /// Record \p Change and take ownership. This is the main function used to
209 /// track Sandbox IR changes.
210 void track(std::unique_ptr<IRChangeBase> &&Change);
211 /// \Returns true if the tracker is recording changes.
212 bool isTracking() const { return State == TrackerState::Record; }
213 /// \Returns the current state of the tracker.
214 TrackerState getState() const { return State; }
215 /// Turns on IR tracking.
216 void save();
217 /// Stops tracking and accept changes.
218 void accept();
219 /// Stops tracking and reverts to saved state.
220 void revert();
221
222#ifndef NDEBUG
223 void dump(raw_ostream &OS) const;
224 LLVM_DUMP_METHOD void dump() const;
226 Tracker.dump(OS);
227 return OS;
228 }
229#endif // NDEBUG
230};
231
232} // namespace llvm::sandboxir
233
234#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.
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:127
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
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:478
LLVM_DUMP_METHOD void dump() const final
Definition: Tracker.cpp:145
void accept() final
This runs when changes get accepted.
Definition: Tracker.h:169
void revert() final
This runs when changes get reverted.
Definition: Tracker.cpp:135
void dump(raw_ostream &OS) const final
Definition: Tracker.h:171
void dump(raw_ostream &OS) const final
Definition: Tracker.h:151
void revert() final
This runs when changes get reverted.
Definition: Tracker.cpp:111
Instruction * getInstruction() const
Definition: Tracker.h:149
void accept() final
This runs when changes get accepted.
Definition: Tracker.h:148
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
TrackerState getState() const
\Returns the current state of the tracker.
Definition: Tracker.h:214
friend raw_ostream & operator<<(raw_ostream &OS, const Tracker &Tracker)
Definition: Tracker.h:225
void dump(raw_ostream &OS) const
Definition: Tracker.cpp:179
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
Tracker(Context &Ctx)
Definition: Tracker.h:205
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
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
Represents a Def-use/Use-def edge in SandboxIR.
Definition: Use.h:29
A SandboxIR Value has users. This is the base class.
Definition: SandboxIR.h:137
@ 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)