LLVM 23.0.0git
Rematerializer.h
Go to the documentation of this file.
1//=====-- Rematerializer.h - MIR rematerialization support ------*- 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/// \file
10/// MIR-level target-independent rematerialization helpers.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CODEGEN_REMATERIALIZER_H
15#define LLVM_CODEGEN_REMATERIALIZER_H
16
17#include "llvm/ADT/MapVector.h"
18#include "llvm/ADT/STLExtras.h"
25#include <iterator>
26
27namespace llvm {
28
29/// MIR-level target-independent rematerializer. Provides an API to identify and
30/// rematerialize registers within a machine function.
31///
32/// At the moment this supports rematerializing registers that meet all of the
33/// following constraints.
34/// 1. The register is virtual and has a single defining instruction.
35/// 2. The single defining instruction is deemed rematerializable by the TII and
36/// doesn't have any physical register use that is both non-constant and
37/// non-ignorable.
38/// 3. The register has at least one non-debug use that is inside or at a region
39/// boundary (see below for what we consider to be a region).
40///
41/// Rematerializable registers (represented by \ref Rematerializer::Reg) form a
42/// DAG of their own, with every register having incoming edges from all
43/// rematerializable registers which are read by the instruction defining it. It
44/// is possible to rematerialize registers with unrematerializable dependencies;
45/// however the latter are not considered part of this DAG since their
46/// position/identity never change and therefore do not require the same level
47/// of tracking.
48///
49/// Each register has a "dependency DAG" which is defined as the subset of nodes
50/// in the overall DAG that have at least one path to the register, which is
51/// called the "root" register in this context. Semantically, these nodes are
52/// the registers which are involved into the computation of the root register
53/// i.e., all of its transitive dependencies. We use the term "root" because all
54/// paths within the dependency DAG of a register terminate at it; however,
55/// there may be multiple paths between a non-root node and the root node, so a
56/// dependency DAG is not always a tree.
57///
58/// The API uses dense unsigned integers starting at 0 to reference
59/// rematerializable registers. These indices are immutable i.e., even when
60/// registers are deleted their respective integer handle remain valid. Method
61/// which perform actual rematerializations should however be assumed to
62/// invalidate addresses to \ref Rematerializer::Reg objects.
63///
64/// The rematerializer tracks def/use points of registers based on regions.
65/// These are alike the regions the machine scheduler works on. A region is
66/// simply a pair on MBB iterators encoding a range of machine instructions. The
67/// first iterator (beginning of the region) is inclusive whereas the second
68/// iterator (end of the region) is exclusive and can either point to a MBB's
69/// end sentinel or an actual MI (not necessarily a terminator). Regions must be
70/// non-empty, cannot overlap, and cannot contain terminators. However, they do
71/// not have to cover the whole function.
72///
73/// The API uses dense unsigned integers starting at 0 to reference regions.
74/// These map directly to the indices of the corresponding regions in the region
75/// vector passed during construction.
76///
77/// The rematerializer supports rematerializing arbitrary complex DAGs of
78/// registers to regions where these registers are used, with the option of
79/// re-using non-root registers or their previous rematerializations instead of
80/// rematerializing them again.
81///
82/// Throughout its lifetime, the rematerializer tracks new registers it creates
83/// (which are rematerializable by construction) and their relations to other
84/// registers. It performs DAG updates immediately on rematerialization but
85/// defers/batches all necessary live interval updates to reduce the number of
86/// expensive LIS queries when successively rematerializing many registers. \ref
87/// Rematerializer::updateLiveIntervals performs all currently batched live
88/// interval updates.
89///
90/// In its nomenclature, the rematerializer differentiates between "original
91/// registers" (registers that were present when it analyzed the function) and
92/// rematerializations of these original registers. Rematerializations have an
93/// "origin" which is the index of the original regiser they were rematerialized
94/// from (transitivity applies; a rematerialization and all of its own
95/// rematerializations have the same origin). Semantically, only original
96/// registers have rematerializations.
98public:
99 /// Index type for rematerializable registers.
101
102 /// A rematerializable register defined by a single machine instruction.
103 ///
104 /// A rematerializable register has a set of dependencies, which correspond
105 /// to the unique read register operands of its defining instruction.
106 /// They are identified by their machine operand index, and can themselves be
107 /// rematerializable. Operand indices corresponding to unrematerializable
108 /// dependencies are managed by and queried from the rematerializer.
109 ///
110 /// A rematerializable register also has an arbitrary number of users in an
111 /// arbitrary number of regions, potentially including its own defining
112 /// region. When rematerializations lead to operand changes in users, a
113 /// register may find itself without any user left, at which point the
114 /// rematerializer deletes it (setting its defining MI to nullptr).
115 struct Reg {
116 /// Single MI defining the rematerializable register.
118 /// Defining region of \p DefMI.
119 unsigned DefRegion;
120 /// The rematerializable register's lane bitmask.
122
124 /// Uses of the register, mapped by region.
126
127 /// A read register operand of \p DefMI that is rematerializable (according
128 /// to the rematerializer).
129 struct Dependency {
130 /// The register's machine operand index in \p DefMI.
131 unsigned MOIdx;
132 /// The corresponding register's index in the rematerializer.
134
137 };
138 /// This register's rematerializable dependencies, one per unique
139 /// rematerializable register operand.
141
142 /// Returns the rematerializable register from its defining instruction.
144 assert(DefMI && "defining instruction was deleted");
145 assert(DefMI->getOperand(0).isDef() && "not a register def");
146 return DefMI->getOperand(0).getReg();
147 }
148
149 bool hasUsersInDefRegion() const {
150 return !Uses.empty() && Uses.contains(DefRegion);
151 }
152
154 if (Uses.empty())
155 return false;
156 return Uses.size() > 1 || Uses.begin()->first != DefRegion;
157 }
158
159 /// Returns the first and last user of the register in region \p UseRegion.
160 /// If the register has no user in the region, returns a pair of nullptr's.
161 LLVM_ABI std::pair<MachineInstr *, MachineInstr *>
162 getRegionUseBounds(unsigned UseRegion, const LiveIntervals &LIS) const;
163
164 bool isAlive() const { return DefMI; }
165
166 private:
167 void addUser(MachineInstr *MI, unsigned Region);
168 void addUsers(const RegionUsers &NewUsers, unsigned Region);
169 void eraseUser(MachineInstr *MI, unsigned Region);
170
171 friend Rematerializer;
172 };
173
174 /// Rematerializer listener. Defines overridable hooks that allow to catch
175 /// specific events inside the rematerializer. All hooks do nothing by
176 /// default. Listeners can be added or removed at any time during the
177 /// rematerializer's lifetime.
179 public:
181
182 /// Called just after register \p NewRegIdx is created (following a
183 /// rematerialization). At this point the rematerialization exists in the \p
184 /// Remater state and the MIR but does not yet have any user.
185 virtual void rematerializerNoteRegCreated(const Rematerializer &Remater,
186 RegisterIdx NewRegIdx) {}
187
188 /// Called juste before register \p RegIdx is deleted from the MIR. At this
189 /// point the register still exists in the MIR but no longer has any user.
190 virtual void rematerializerNoteRegDeleted(const Rematerializer &Remater,
191 RegisterIdx RegIdx) {}
192
193 virtual ~Listener() = default;
194
195 private:
196 virtual void anchor();
197 };
198
199 /// Error value for register indices.
200 static constexpr unsigned NoReg = ~0;
201
202 /// A region's boundaries i.e. a pair of instruction bundle iterators. The
203 /// lower boundary is inclusive, the upper boundary is exclusive.
205 std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>;
206
208
209 /// Simply initializes some internal state, does not identify
210 /// rematerialization candidates.
213 LiveIntervals &LIS);
214
215 /// Goes through the whole MF and identifies all rematerializable registers.
216 /// Returns whether there is any rematerializable register in regions.
217 LLVM_ABI bool analyze();
218
219 /// Adds a new listener to the rematerializer.
220 void addListener(Listener *Listen) {
221 assert(Listen && "null listener");
222 if (!Listeners.insert(Listen).second)
223 llvm_unreachable("duplicate listener");
224 }
225
226 /// Removes a listener from the rematerializer.
227 void removeListener(Listener *Listen) {
228 if (!Listeners.erase(Listen))
229 llvm_unreachable("unknown listener");
230 }
231
232 /// Removes all listeners from the rematerializer.
233 void clearListeners() { Listeners.clear(); }
234
235 const Reg &getReg(RegisterIdx RegIdx) const {
236 assert(RegIdx < Regs.size() && "out of bounds");
237 return Regs[RegIdx];
238 };
239 ArrayRef<Reg> getRegs() const { return Regs; };
240 unsigned getNumRegs() const { return Regs.size(); };
241
242 const RegionBoundaries &getRegion(RegisterIdx RegionIdx) const {
243 assert(RegionIdx < Regions.size() && "out of bounds");
244 return Regions[RegionIdx];
245 }
246 unsigned getNumRegions() const { return Regions.size(); }
247
248 /// Whether register \p RegIdx is an original register.
249 bool isOriginalRegister(RegisterIdx RegIdx) const {
250 return !isRematerializedRegister(RegIdx);
251 }
252 /// Whether register \p RegIdx is a rematerialization of some original
253 /// register.
255 assert(RegIdx < Regs.size() && "out of bounds");
256 return RegIdx >= UnrematableOprds.size();
257 }
258 /// Returns the origin index of rematerializable register \p RegIdx.
260 assert(isRematerializedRegister(RematRegIdx) && "not a rematerialization");
261 return Origins[RematRegIdx - UnrematableOprds.size()];
262 }
263 /// If \p RegIdx is a rematerialization, returns its origin's index. If it is
264 /// an original register's index, returns the same index.
266 if (isRematerializedRegister(RegIdx))
267 return getOriginOf(RegIdx);
268 return RegIdx;
269 }
270 /// Returns operand indices corresponding to unrematerializable operands for
271 /// any register \p RegIdx.
273 return UnrematableOprds[getOriginOrSelf(RegIdx)];
274 }
275
276 /// If \p MI's first operand defines a register and that register is a
277 /// rematerializable register tracked by the rematerializer, returns its
278 /// index in the \ref Regs vector. Otherwise returns \ref
279 /// Rematerializer::NoReg.
281
282 /// When rematerializating a register (called the "root" register in this
283 /// context) to a given position, we must decide what to do with all its
284 /// rematerializable dependencies (for unrematerializable dependencies, we
285 /// have no choice but to re-use the same register). For each rematerializable
286 /// dependency we can either
287 /// 1. rematerialize it along with the register,
288 /// 2. re-use it as-is, or
289 /// 3. re-use a pre-existing rematerialization of it.
290 /// In case 1, the same decision needs to be made for all of the dependency's
291 /// dependencies. In cases 2 and 3, the dependency's dependencies need not be
292 /// examined.
293 ///
294 /// This struct allows to encode decisions of types (2) and (3) when
295 /// rematerialization of all of the root's dependency DAG is undesirable.
296 /// During rematerialization, registers in the root's dependency DAG which
297 /// have a path to the root made up exclusively of non-re-used registers will
298 /// be rematerialized along with the root.
300 /// Keys and values are rematerializable register indices.
301 ///
302 /// Before rematerialization, this only contains entries for non-root
303 /// registers of the root's dependency DAG which should not be
304 /// rematerialized i.e., for which an existing register should be used
305 /// instead. These map each such non-root register to either the same
306 /// register (case 2, \ref DependencyReuseInfo::reuse) or to a
307 /// rematerialization of the key register (case 3, \ref
308 /// DependencyReuseInfo::useRemat).
309 ///
310 /// After rematerialization, this contains additional entries for non-root
311 /// registers of the root's dependency DAG that needed to be rematerialized
312 /// along the root. These map each such non-root register to their
313 /// corresponding new rematerialization that is used in the rematerialized
314 /// root's dependency DAG. It follows that the difference in map size before
315 /// and after rematerialization indicates the number of non-root registers
316 /// that were rematerialized along the root.
318
320 DependencyMap.insert({DepIdx, DepIdx});
321 return *this;
322 }
324 DependencyMap.insert({DepIdx, DepRematIdx});
325 return *this;
326 }
328 DependencyMap.clear();
329 return *this;
330 }
331 };
332
333 /// Rematerializes register \p RootIdx just before its first user inside
334 /// region \p UseRegion (or at the end of the region if it has no user),
335 /// transfers all its users in the region to the new register, and returns the
336 /// latter's index. The root's dependency DAG is rematerialized or re-used
337 /// according to \p DRI.
338 ///
339 /// When the method returns, \p DRI contains additional entries for non-root
340 /// registers of the root's dependency DAG that needed to be rematerialized
341 /// along the root. References to \ref Rematerializer::Reg should be
342 /// considered invalidated by calls to this method.
344 unsigned UseRegion,
345 DependencyReuseInfo &DRI);
346
347 /// Rematerializes register \p RootIdx before position \p InsertPos in \p
348 /// UseRegion and returns the new register's index. The root's dependency DAG
349 /// is rematerialized or re-used according to \p DRI.
350 ///
351 /// When the method returns, \p DRI contains additional entries for non-root
352 /// registers of the root's dependency DAG that needed to be rematerialized
353 /// along the root. References to \ref Rematerializer::Reg should be
354 /// considered invalidated by calls to this method.
356 unsigned UseRegion,
358 DependencyReuseInfo &DRI);
359
360 /// Rematerializes register \p RegIdx before \p InsertPos in \p UseRegion,
361 /// adding the new rematerializable register to the backing vector \ref Regs
362 /// and returning its index inside the vector. Sets the new register's
363 /// rematerializable dependencies to \p Dependencies (these are assumed to
364 /// already exist in the MIR) and its unrematerializable dependencies to the
365 /// same as \p RegIdx. The new register initially has no user. Since the
366 /// method appends to \ref Regs, references to elements within it should be
367 /// considered invalidated across calls to this method unless the vector can
368 /// be guaranteed to have enough space for an extra element.
370 rematerializeReg(RegisterIdx RegIdx, unsigned UseRegion,
372 SmallVectorImpl<Reg::Dependency> &&Dependencies);
373
374 /// Re-creates a previously deleted register \p RegIdx before \p InsertPos in
375 /// \p DefRegion. \p DefReg must be the original virtual register that \p
376 /// RegIdx used to define. Sets the new register's rematerializable
377 /// dependencies to \p Dependencies (these are assumed to already exist in the
378 /// MIR).
379 LLVM_ABI void recreateReg(RegisterIdx RegIdx, unsigned DefRegion,
381 Register DefReg,
382 SmallVectorImpl<Reg::Dependency> &&Dependencies);
383
384 /// Transfers all users of register \p FromRegIdx in region \p UseRegion to \p
385 /// ToRegIdx, the latter of which must be a rematerialization of the former or
386 /// have the same origin register. Users in \p UseRegion must be reachable
387 /// from \p ToRegIdx.
389 RegisterIdx ToRegIdx, unsigned UseRegion);
390
391 /// Transfers user \p UserMI in region \p UserRegion from register \p
392 /// FromRegIdx to \p ToRegIdx, the latter of which must be a rematerialization
393 /// of the former or have the same origin register. \p UserMI must be a direct
394 /// user of \p FromRegIdx. \p UserMI must be reachable from \p ToRegIdx.
395 LLVM_ABI void transferUser(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx,
396 unsigned UserRegion, MachineInstr &UserMI);
397
398 /// Transfers all users of register \p FromRegIdx to register \p ToRegIdx, the
399 /// latter of which must be a rematerialization of the former or have the same
400 /// origin register. Users of \p FromRegIdx must be reachable from \p
401 /// ToRegIdx.
402 LLVM_ABI void transferAllUsers(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx);
403
404 /// Recomputes all live intervals that have changed as a result of previous
405 /// rematerializations.
407
408 /// Determines whether (sub-)register operand \p MO has the same value at
409 /// all \p Uses as at \p MO. This implies that it is also available at all \p
410 /// Uses according to its current live interval.
413
414 /// Finds the closest rematerialization of register \p RegIdx in region \p
415 /// Region that exists before slot \p Before. If no such rematerialization
416 /// exists, returns \ref Rematerializer::NoReg.
418 SlotIndex Before) const;
419
423 bool SkipRegions = false) const;
427 std::optional<unsigned> UseRegion = std::nullopt) const;
428
429private:
432 LiveIntervals &LIS;
433 const TargetInstrInfo &TII;
434 const TargetRegisterInfo &TRI;
436
437 void noteRegCreated(RegisterIdx RegIdx) const {
438 for (Listener *Listen : Listeners)
439 Listen->rematerializerNoteRegCreated(*this, RegIdx);
440 }
441
442 void noteRegDeleted(RegisterIdx RegIdx) const {
443 for (Listener *Listen : Listeners)
444 Listen->rematerializerNoteRegDeleted(*this, RegIdx);
445 }
446
447 /// Rematerializable registers identified since the rematerializer's creation,
448 /// both dead and alive, originals and rematerializations. No register is ever
449 /// deleted. Indices inside this vector serve as handles for rematerializable
450 /// registers.
451 SmallVector<Reg> Regs;
452 /// For each original register, stores indices of its read register operands
453 /// which are unrematerializable. This doesn't change after the initial
454 /// collection period, so the size of the vector indicates the number of
455 /// original registers.
456 SmallVector<SmallVector<unsigned, 2>> UnrematableOprds;
457 /// Indicates the original register index of each rematerialization, in the
458 /// order in which they are created. The size of the vector indicates the
459 /// total number of rematerializations ever created, including those that were
460 /// deleted.
462 /// Maps original register indices to their currently alive
463 /// rematerializations. In practice most registers don't have
464 /// rematerializations so this is represented as a map to lower memory cost.
465 DenseMap<RegisterIdx, RematsOf> Rematerializations;
466
467 /// Registers mapped to the index of their corresponding rematerialization
468 /// data in the \ref Regs vector. This includes registers that no longer exist
469 /// in the MIR.
470 DenseMap<Register, RegisterIdx> RegToIdx;
471 /// Parent block of each region, in order.
473 /// Set of registers whose live-range may have changed during past
474 /// rematerializations.
475 DenseSet<RegisterIdx> LISUpdates;
476
477 /// Common post-processing step after creating a new register \p RematRegIdx
478 /// at \p InsertPos based on register \p ModelRegIdx.
479 void postRematerialization(RegisterIdx ModelRegIdx, RegisterIdx RematRegIdx,
481
482 /// During the analysis phase, creates a \ref Rematerializer::Reg object for
483 /// virtual register \p VirtRegIdx if it is rematerializable. \p MIRegion maps
484 /// all MIs to their parent region. Set bits in \p SeenRegs indicate virtual
485 /// register indices that have already been visited.
486 void
487 addRegIfRematerializable(unsigned VirtRegIdx,
488 const DenseMap<MachineInstr *, unsigned> &MIRegion,
489 BitVector &SeenRegs);
490
491 /// Determines whether \p MI is considered rematerializable. This further
492 /// restricts constraints imposed by the TII on rematerializable instructions,
493 /// requiring for example that the defined register is virtual and only
494 /// defined once.
495 bool isMIRematerializable(const MachineInstr &MI) const;
496
497 /// Implementation of \ref Rematerializer::transferUser that doesn't update
498 /// register users.
499 void transferUserImpl(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx,
500 MachineInstr &UserMI);
501
502 /// Deletes register \p RootIdx if it no longer has any user. If the register
503 /// is deleted, recursively deletes any of its transitive rematerializable
504 /// dependencies that no longer have users as a result.
505 void deleteRegIfUnused(RegisterIdx RootIdx);
506
507 /// Deletes rematerializable register \p RegIdx from the DAG and relevant
508 /// internal state.
509 void deleteReg(RegisterIdx RegIdx);
510};
511
512/// Rematerializer listener with the ability to re-create deleted registers and
513/// rollback rematerializations. Starts recording register deletions and
514/// rematerializations as soon as it is attached to the rematerializer.
516public:
517 Rollbacker() = default;
518
519 /// Re-creates all deleted registers and rolls back all rematerializations
520 /// that were recorded.
521 void rollback(Rematerializer &Remater);
522
524 RegisterIdx RegIdx) override;
525
527 RegisterIdx RegIdx) override;
528
529private:
530 struct RollbackInfo {
531 /// Original register.
532 Register DefReg;
533 /// Original defining region.
534 unsigned DefRegion;
535 /// Original dependencies.
537 /// Position to re-create the register before in case of rollback. This
538 /// becomes invalid if it originally points to an MI that is deleted later
539 /// as a consequence of other rematerializations. In such cases \ref
540 /// NextRegIdx is guaranteed to be an actual register index from which the
541 /// rollback logic will determine a valid insert position before which to
542 /// re-create this register.
544 /// If \ref InsertPos points to an MI defining a rematerializable register,
545 /// stores its index. Otherwise equals \ref Rematerializer::NoReg.
546 RegisterIdx NextRegIdx;
547
548 LLVM_ABI RollbackInfo(const Rematerializer &Remater, RegisterIdx RegIdx);
549 };
550
551 /// Original registers that have been deleted, in order of deletion.
553 /// Registers which have been rematerialized (from original index to
554 /// rematerialized index).
556 /// Used to block further recording of events whenver we are actively rolling
557 /// back.
558 bool RollingBack = false;
559};
560
561} // namespace llvm
562
563#endif // LLVM_CODEGEN_REMATERIALIZER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ABI
Definition Compiler.h:213
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Register const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
Rematerializer::RegisterIdx RegisterIdx
Remove Loads Into Fake Uses
This file contains some templates that are useful if you are working with the STL at all.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
MachineInstrBundleIterator< MachineInstr > iterator
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:38
Simple wrapper around std::function<void(raw_ostream&)>.
Definition Printable.h:38
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Rematerializer listener.
virtual void rematerializerNoteRegCreated(const Rematerializer &Remater, RegisterIdx NewRegIdx)
Called just after register NewRegIdx is created (following a rematerialization).
virtual void rematerializerNoteRegDeleted(const Rematerializer &Remater, RegisterIdx RegIdx)
Called juste before register RegIdx is deleted from the MIR.
Rematerializer::RegisterIdx RegisterIdx
MIR-level target-independent rematerializer.
LLVM_ABI Printable printDependencyDAG(RegisterIdx RootIdx) const
void clearListeners()
Removes all listeners from the rematerializer.
RegisterIdx getOriginOrSelf(RegisterIdx RegIdx) const
If RegIdx is a rematerialization, returns its origin's index.
bool isOriginalRegister(RegisterIdx RegIdx) const
Whether register RegIdx is an original register.
static constexpr unsigned NoReg
Error value for register indices.
LLVM_ABI Printable printID(RegisterIdx RegIdx) const
LLVM_ABI RegisterIdx rematerializeReg(RegisterIdx RegIdx, unsigned UseRegion, MachineBasicBlock::iterator InsertPos, SmallVectorImpl< Reg::Dependency > &&Dependencies)
Rematerializes register RegIdx before InsertPos in UseRegion, adding the new rematerializable registe...
ArrayRef< Reg > getRegs() const
LLVM_ABI RegisterIdx rematerializeToPos(RegisterIdx RootIdx, unsigned UseRegion, MachineBasicBlock::iterator InsertPos, DependencyReuseInfo &DRI)
Rematerializes register RootIdx before position InsertPos in UseRegion and returns the new register's...
unsigned getNumRegs() const
SmallDenseSet< RegisterIdx, 4 > RematsOf
RegisterIdx getOriginOf(RegisterIdx RematRegIdx) const
Returns the origin index of rematerializable register RegIdx.
const Reg & getReg(RegisterIdx RegIdx) const
LLVM_ABI void updateLiveIntervals()
Recomputes all live intervals that have changed as a result of previous rematerializations.
LLVM_ABI RegisterIdx rematerializeToRegion(RegisterIdx RootIdx, unsigned UseRegion, DependencyReuseInfo &DRI)
Rematerializes register RootIdx just before its first user inside region UseRegion (or at the end of ...
std::pair< MachineBasicBlock::iterator, MachineBasicBlock::iterator > RegionBoundaries
A region's boundaries i.e.
LLVM_ABI RegisterIdx getDefRegIdx(const MachineInstr &MI) const
If MI's first operand defines a register and that register is a rematerializable register tracked by ...
const RegionBoundaries & getRegion(RegisterIdx RegionIdx) const
unsigned RegisterIdx
Index type for rematerializable registers.
LLVM_ABI bool isMOIdenticalAtUses(MachineOperand &MO, ArrayRef< SlotIndex > Uses) const
Determines whether (sub-)register operand MO has the same value at all Uses as at MO.
LLVM_ABI void transferRegionUsers(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx, unsigned UseRegion)
Transfers all users of register FromRegIdx in region UseRegion to ToRegIdx, the latter of which must ...
unsigned getNumRegions() const
LLVM_ABI Rematerializer(MachineFunction &MF, SmallVectorImpl< RegionBoundaries > &Regions, LiveIntervals &LIS)
Simply initializes some internal state, does not identify rematerialization candidates.
LLVM_ABI void transferUser(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx, unsigned UserRegion, MachineInstr &UserMI)
Transfers user UserMI in region UserRegion from register FromRegIdx to ToRegIdx, the latter of which ...
ArrayRef< unsigned > getUnrematableOprds(RegisterIdx RegIdx) const
Returns operand indices corresponding to unrematerializable operands for any register RegIdx.
LLVM_ABI void transferAllUsers(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx)
Transfers all users of register FromRegIdx to register ToRegIdx, the latter of which must be a remate...
bool isRematerializedRegister(RegisterIdx RegIdx) const
Whether register RegIdx is a rematerialization of some original register.
LLVM_ABI void recreateReg(RegisterIdx RegIdx, unsigned DefRegion, MachineBasicBlock::iterator InsertPos, Register DefReg, SmallVectorImpl< Reg::Dependency > &&Dependencies)
Re-creates a previously deleted register RegIdx before InsertPos in DefRegion.
LLVM_ABI Printable printRematReg(RegisterIdx RegIdx, bool SkipRegions=false) const
LLVM_ABI Printable printRegUsers(RegisterIdx RegIdx) const
LLVM_ABI Printable printUser(const MachineInstr *MI, std::optional< unsigned > UseRegion=std::nullopt) const
void removeListener(Listener *Listen)
Removes a listener from the rematerializer.
LLVM_ABI RegisterIdx findRematInRegion(RegisterIdx RegIdx, unsigned Region, SlotIndex Before) const
Finds the closest rematerialization of register RegIdx in region Region that exists before slot Befor...
void addListener(Listener *Listen)
Adds a new listener to the rematerializer.
LLVM_ABI bool analyze()
Goes through the whole MF and identifies all rematerializable registers.
void rollback(Rematerializer &Remater)
Re-creates all deleted registers and rolls back all rematerializations that were recorded.
Rollbacker()=default
void rematerializerNoteRegCreated(const Rematerializer &Remater, RegisterIdx RegIdx) override
Called just after register NewRegIdx is created (following a rematerialization).
void rematerializerNoteRegDeleted(const Rematerializer &Remater, RegisterIdx RegIdx) override
Called juste before register RegIdx is deleted from the MIR.
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:66
Implements a dense probed hash-table based set with some number of buckets stored inline.
Definition DenseSet.h:301
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
When rematerializating a register (called the "root" register in this context) to a given position,...
DependencyReuseInfo & reuse(RegisterIdx DepIdx)
SmallDenseMap< RegisterIdx, RegisterIdx, 4 > DependencyMap
Keys and values are rematerializable register indices.
DependencyReuseInfo & useRemat(RegisterIdx DepIdx, RegisterIdx DepRematIdx)
unsigned MOIdx
The register's machine operand index in DefMI.
Dependency(unsigned MOIdx, RegisterIdx RegIdx)
RegisterIdx RegIdx
The corresponding register's index in the rematerializer.
A rematerializable register defined by a single machine instruction.
MachineInstr * DefMI
Single MI defining the rematerializable register.
SmallVector< Dependency, 2 > Dependencies
This register's rematerializable dependencies, one per unique rematerializable register operand.
LaneBitmask Mask
The rematerializable register's lane bitmask.
LLVM_ABI std::pair< MachineInstr *, MachineInstr * > getRegionUseBounds(unsigned UseRegion, const LiveIntervals &LIS) const
Returns the first and last user of the register in region UseRegion.
bool hasUsersOutsideDefRegion() const
unsigned DefRegion
Defining region of DefMI.
SmallDenseMap< unsigned, RegionUsers, 2 > Uses
Uses of the register, mapped by region.
Register getDefReg() const
Returns the rematerializable register from its defining instruction.
SmallDenseSet< MachineInstr *, 4 > RegionUsers