LLVM 24.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
24
25namespace llvm {
26
27/// MIR-level target-independent rematerializer. Provides an API to identify and
28/// rematerialize registers within a machine function.
29///
30/// At the moment this supports rematerializing registers that meet all of the
31/// following constraints.
32/// 1. The register is virtual and has a single defining instruction.
33/// 2. The single defining instruction is deemed rematerializable by the TII and
34/// doesn't have any physical register use that is both non-constant and
35/// non-ignorable.
36/// 3. The register has at least one non-debug use that is inside or at a region
37/// boundary (see below for what we consider to be a region).
38///
39/// Rematerializable registers (represented by \ref Rematerializer::Reg) form a
40/// DAG of their own, with every register having incoming edges from all
41/// rematerializable registers which are read by the instruction defining it. It
42/// is possible to rematerialize registers with unrematerializable dependencies;
43/// however the latter are not considered part of this DAG since their
44/// position/identity never change and therefore do not require the same level
45/// of tracking.
46///
47/// Each register has a "dependency DAG" which is defined as the subset of nodes
48/// in the overall DAG that have at least one path to the register, which is
49/// called the "root" register in this context. Semantically, these nodes are
50/// the registers which are involved into the computation of the root register
51/// i.e., all of its transitive dependencies. We use the term "root" because all
52/// paths within the dependency DAG of a register terminate at it; however,
53/// there may be multiple paths between a non-root node and the root node, so a
54/// dependency DAG is not always a tree.
55///
56/// The API uses dense unsigned integers starting at 0 to reference
57/// rematerializable registers. These indices are immutable i.e., even when
58/// registers are deleted their respective integer handle remain valid. Method
59/// which perform actual rematerializations should however be assumed to
60/// invalidate addresses to \ref Rematerializer::Reg objects.
61///
62/// The rematerializer tracks def/use points of registers based on regions.
63/// These are alike the regions the machine scheduler works on. A region is
64/// simply a pair on MBB iterators encoding a range of machine instructions. The
65/// first iterator (beginning of the region) is inclusive whereas the second
66/// iterator (end of the region) is exclusive and can either point to a MBB's
67/// end sentinel or an actual MI (not necessarily a terminator). Regions must be
68/// non-empty, cannot overlap, and cannot contain terminators. However, they do
69/// not have to cover the whole function.
70///
71/// The API uses dense unsigned integers starting at 0 to reference regions.
72/// These map directly to the indices of the corresponding regions in the region
73/// vector passed during construction.
74///
75/// The rematerializer supports rematerializing arbitrary complex DAGs of
76/// registers to regions where these registers are used, with the option of
77/// re-using non-root registers or their previous rematerializations instead of
78/// rematerializing them again.
79///
80/// Throughout its lifetime, the rematerializer tracks new registers it creates
81/// (which are rematerializable by construction) and their relations to other
82/// registers. It performs DAG and live interval updates immediately on
83/// rematerialization and/or user transfer. Importantly, missing dead flags on
84/// partial definitions of unrematerializable registers can yield dead
85/// definitions when rematerializing their users. They are deleted to preserve
86/// live interval validity. These deletions can cascade to other
87/// (un)rematerializable registers that also become dead as a result.
88///
89/// In its nomenclature, the rematerializer differentiates between "original
90/// registers" (registers that were present when it analyzed the function) and
91/// rematerializations of these original registers. Rematerializations have an
92/// "origin" which is the index of the original regiser they were rematerialized
93/// from (transitivity applies; a rematerialization and all of its own
94/// rematerializations have the same origin). Semantically, only original
95/// registers have rematerializations.
97public:
98 /// Index type for rematerializable registers.
100
101 /// A rematerializable register defined by a single machine instruction.
102 ///
103 /// A rematerializable register has a set of dependencies, which correspond
104 /// to the unique read register operands of its defining instruction and which
105 /// can themselves be rematerializable. Operand indices corresponding to
106 /// unrematerializable dependencies are managed by and queried from the
107 /// rematerializer, whereas rematerializable ones are part of this struct and
108 /// identified through their register index.
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 /// This register's rematerializable dependencies, one per unique
127 /// rematerializable register operand.
129
130 /// Returns the rematerializable register from its defining instruction.
132 assert(DefMI && "defining instruction was deleted");
133 assert(DefMI->getOperand(0).isDef() && "not a register def");
134 return DefMI->getOperand(0).getReg();
135 }
136
137 bool hasUsersInDefRegion() const {
138 return !Uses.empty() && Uses.contains(DefRegion);
139 }
140
142 if (Uses.empty())
143 return false;
144 return Uses.size() > 1 || Uses.begin()->first != DefRegion;
145 }
146
147 /// Returns the first and last user of the register in region \p UseRegion.
148 /// If the register has no user in the region, returns a pair of nullptr's.
149 LLVM_ABI std::pair<MachineInstr *, MachineInstr *>
150 getRegionUseBounds(unsigned UseRegion, const LiveIntervals &LIS) const;
151
152 bool isAlive() const { return DefMI; }
153
154 private:
155 void addUser(MachineInstr *MI, unsigned Region);
156 void addUsers(const RegionUsers &NewUsers, unsigned Region);
157 void eraseUser(MachineInstr *MI, unsigned Region);
158
159 friend Rematerializer;
160 };
161
162 /// Rematerializer listener. Defines overridable hooks that allow to catch
163 /// specific events inside the rematerializer. All hooks do nothing by
164 /// default. Listeners can be added or removed at any time during the
165 /// rematerializer's lifetime.
167 public:
169
170 /// Called just after register \p NewRegIdx is created (following a
171 /// rematerialization). At this point the rematerialization exists in the \p
172 /// Remater state and the MIR but does not yet have any user.
173 virtual void rematerializerNoteRegCreated(const Rematerializer &Remater,
174 RegisterIdx NewRegIdx) {}
175
176 /// Called just before register \p RegIdx is deleted from the MIR. At this
177 /// point the register still exists in the MIR but no longer has any user.
178 virtual void
181
182 /// Called just before unrematerializable instruction \p MI is deleted from
183 /// the MIR because it has become a dead definition.
184 virtual void
187
188 virtual ~Listener() = default;
189
190 private:
191 virtual void anchor();
192 };
193
194 /// Error value for register indices.
195 static constexpr unsigned NoReg = ~0;
196
197 /// A region's boundaries i.e. a pair of instruction bundle iterators. The
198 /// lower boundary is inclusive, the upper boundary is exclusive.
200 std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>;
201
203
204 /// Simply initializes some internal state, does not identify
205 /// rematerialization candidates.
208 LiveIntervals &LIS);
209
210 /// Goes through the whole MF and identifies all rematerializable registers.
211 /// Returns whether there is any rematerializable register in regions.
212 LLVM_ABI bool analyze();
213
214 /// Adds a new listener to the rematerializer.
215 void addListener(Listener *Listen) {
216 assert(Listen && "null listener");
217 if (!Listeners.insert(Listen).second)
218 llvm_unreachable("duplicate listener");
219 }
220
221 /// Removes a listener from the rematerializer.
222 void removeListener(Listener *Listen) {
223 if (!Listeners.erase(Listen))
224 llvm_unreachable("unknown listener");
225 }
226
227 /// Removes all listeners from the rematerializer.
228 void clearListeners() { Listeners.clear(); }
229
230 const Reg &getReg(RegisterIdx RegIdx) const {
231 assert(RegIdx < Regs.size() && "out of bounds");
232 return Regs[RegIdx];
233 };
234 ArrayRef<Reg> getRegs() const { return Regs; };
235 unsigned getNumRegs() const { return Regs.size(); };
236
237 /// Determines whether register \p RegIdx fully disappeared from the MIR. This
238 /// may happen when it was only used by instructions which became dead during
239 /// the rematerializer's lifetime.
240 bool isPermanentlyDead(RegisterIdx RegIdx) const {
241 RegisterIdx OrigIdx = getOriginOrSelf(RegIdx);
242 return !getReg(OrigIdx).isAlive() && !Rematerializations.contains(OrigIdx);
243 }
244
245 const RegionBoundaries &getRegion(RegisterIdx RegionIdx) const {
246 assert(RegionIdx < Regions.size() && "out of bounds");
247 return Regions[RegionIdx];
248 }
249 unsigned getNumRegions() const { return Regions.size(); }
250
251 /// Whether register \p RegIdx is an original register.
252 bool isOriginalRegister(RegisterIdx RegIdx) const {
253 return !isRematerializedRegister(RegIdx);
254 }
255 /// Whether register \p RegIdx is a rematerialization of some original
256 /// register.
258 assert(RegIdx < Regs.size() && "out of bounds");
259 return RegIdx >= UnrematableDeps.size();
260 }
261 /// Returns the origin index of rematerializable register \p RegIdx.
263 assert(isRematerializedRegister(RematRegIdx) && "not a rematerialization");
264 return Origins[RematRegIdx - UnrematableDeps.size()];
265 }
266 /// If \p RegIdx is a rematerialization, returns its origin's index. If it is
267 /// an original register's index, returns the same index.
269 if (isRematerializedRegister(RegIdx))
270 return getOriginOf(RegIdx);
271 return RegIdx;
272 }
273 /// Returns unreamaterializable read lanes of register operands for
274 /// register \p RegIdx.
277 return UnrematableDeps[getOriginOrSelf(RegIdx)];
278 }
279
280 /// If \p MI's first operand defines a register and that register is a
281 /// rematerializable register tracked by the rematerializer, returns its
282 /// index in the \ref Regs vector. Otherwise returns \ref
283 /// Rematerializer::NoReg.
285
286 /// When rematerializating a register (called the "root" register in this
287 /// context) to a given position, we must decide what to do with all its
288 /// rematerializable dependencies (for unrematerializable dependencies, we
289 /// have no choice but to re-use the same register). For each rematerializable
290 /// dependency we can either
291 /// 1. rematerialize it along with the register,
292 /// 2. re-use it as-is, or
293 /// 3. re-use a pre-existing rematerialization of it.
294 /// In case 1, the same decision needs to be made for all of the dependency's
295 /// dependencies. In cases 2 and 3, the dependency's dependencies need not be
296 /// examined.
297 ///
298 /// This struct allows to encode decisions of types (2) and (3) when
299 /// rematerialization of all of the root's dependency DAG is undesirable.
300 /// During rematerialization, registers in the root's dependency DAG which
301 /// have a path to the root made up exclusively of non-re-used registers will
302 /// be rematerialized along with the root.
304 /// Keys and values are rematerializable register indices.
305 ///
306 /// Before rematerialization, this only contains entries for non-root
307 /// registers of the root's dependency DAG which should not be
308 /// rematerialized i.e., for which an existing register should be used
309 /// instead. These map each such non-root register to either the same
310 /// register (case 2, \ref DependencyReuseInfo::reuse) or to a
311 /// rematerialization of the key register (case 3, \ref
312 /// DependencyReuseInfo::useRemat).
313 ///
314 /// After rematerialization, this contains additional entries for non-root
315 /// registers of the root's dependency DAG that needed to be rematerialized
316 /// along the root. These map each such non-root register to their
317 /// corresponding new rematerialization that is used in the rematerialized
318 /// root's dependency DAG. It follows that the difference in map size before
319 /// and after rematerialization indicates the number of non-root registers
320 /// that were rematerialized along the root.
322
324 DependencyMap.insert({DepIdx, DepIdx});
325 return *this;
326 }
328 DependencyMap.insert({DepIdx, DepRematIdx});
329 return *this;
330 }
332 DependencyMap.clear();
333 return *this;
334 }
335 };
336
337 /// Rematerializes register \p RootIdx just before its first user inside
338 /// region \p UseRegion (or at the end of the region if it has no user),
339 /// transfers all its users in the region to the new register, and returns the
340 /// latter's index. The root's dependency DAG is rematerialized or re-used
341 /// according to \p DRI.
342 ///
343 /// When the method returns, \p DRI contains additional entries for non-root
344 /// registers of the root's dependency DAG that needed to be rematerialized
345 /// along the root. References to \ref Rematerializer::Reg should be
346 /// considered invalidated by calls to this method.
348 unsigned UseRegion,
349 DependencyReuseInfo &DRI);
350
351 /// Rematerializes register \p RootIdx before position \p InsertPos in \p
352 /// UseRegion and returns the new register's index. The root's dependency DAG
353 /// is rematerialized or re-used according to \p DRI.
354 ///
355 /// When the method returns, \p DRI contains additional entries for non-root
356 /// registers of the root's dependency DAG that needed to be rematerialized
357 /// along the root. References to \ref Rematerializer::Reg should be
358 /// considered invalidated by calls to this method.
360 unsigned UseRegion,
362 DependencyReuseInfo &DRI);
363
364 /// Rematerializes register \p RegIdx before \p InsertPos in \p UseRegion,
365 /// adding the new rematerializable register to the backing vector \ref Regs
366 /// and returning its index inside the vector. Sets the new register's
367 /// rematerializable dependencies to \p Dependencies (these are assumed to
368 /// already exist in the MIR) and its unrematerializable dependencies to the
369 /// same as \p RegIdx. The new register initially has no user. Since the
370 /// method appends to \ref Regs, references to elements within it should be
371 /// considered invalidated across calls to this method unless the vector can
372 /// be guaranteed to have enough space for an extra element.
374 rematerializeReg(RegisterIdx RegIdx, unsigned UseRegion,
376 SmallVectorImpl<RegisterIdx> &&Dependencies);
377
378 /// Re-creates a previously deleted register \p RegIdx before \p InsertPos,
379 /// which must be in the register's original defining region. \p DefReg must
380 /// be the original virtual register that \p RegIdx used to define.
381 /// Dependencies are assumed to already exist in the MIR.
382 LLVM_ABI void recreateReg(RegisterIdx RegIdx,
384 Register DefReg);
385
386 /// Transfers all users of register \p FromRegIdx in region \p UseRegion to \p
387 /// ToRegIdx, the latter of which must be a rematerialization of the former or
388 /// have the same origin register. Users in \p UseRegion must be reachable
389 /// from \p ToRegIdx.
391 RegisterIdx ToRegIdx, unsigned UseRegion);
392
393 /// Transfers user \p UserMI in region \p UserRegion from register \p
394 /// FromRegIdx to \p ToRegIdx, the latter of which must be a rematerialization
395 /// of the former or have the same origin register. \p UserMI must be a direct
396 /// user of \p FromRegIdx. \p UserMI must be reachable from \p ToRegIdx.
397 LLVM_ABI void transferUser(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx,
398 unsigned UserRegion, MachineInstr &UserMI);
399
400 /// Transfers all users of register \p FromRegIdx to register \p ToRegIdx, the
401 /// latter of which must be a rematerialization of the former or have the same
402 /// origin register. Users of \p FromRegIdx must be reachable from \p
403 /// ToRegIdx.
404 LLVM_ABI void transferAllUsers(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx);
405
406 /// Determines whether (sub-)register operand \p MO has the same value at
407 /// all \p Uses as at \p MO. This implies that it is also available at all \p
408 /// Uses according to its current live interval.
411
412 /// Determines whether lanes \p Mask of register \p Reg habe the same value at
413 /// all \p Uses as at \p RefSlot. This implies that it is also available at
414 /// all \p Uses according to its current live interval.
416 SlotIndex RefSlot,
418
419 /// Finds the closest rematerialization of register \p RegIdx in region \p
420 /// Region that exists before slot \p Before. If no such rematerialization
421 /// exists, returns \ref Rematerializer::NoReg.
423 SlotIndex Before) const;
424
428 bool SkipRegions = false) const;
432 std::optional<unsigned> UseRegion = std::nullopt) const;
433
434private:
435 struct DeadDefDelegate : LiveRangeEdit::Delegate {
436 Rematerializer &Remater;
437 DeadDefDelegate(Rematerializer &Remater) : Remater(Remater) {}
438 void LRE_WillEraseInstruction(MachineInstr *MI) override;
439 };
440
441 SmallVectorImpl<RegionBoundaries> &Regions;
442 MachineRegisterInfo &MRI;
443 LiveIntervals &LIS;
444 const TargetInstrInfo &TII;
445 const TargetRegisterInfo &TRI;
446 SmallPtrSet<Listener *, 1> Listeners;
447
448 void noteRegCreated(RegisterIdx RegIdx) const {
449 for (Listener *Listen : Listeners)
450 Listen->rematerializerNoteRegCreated(*this, RegIdx);
451 }
452
453 void noteRegWillBeDeleted(RegisterIdx RegIdx) const {
454 for (Listener *Listen : Listeners)
455 Listen->rematerializerNoteRegWillBeDeleted(*this, RegIdx);
456 }
457
458 void noteMIWillBeDeleted(MachineInstr &MI) const {
459 for (Listener *Listen : Listeners)
460 Listen->rematerializerNoteMIWillBeDeleted(*this, MI);
461 }
462
463 /// Rematerializable registers identified since the rematerializer's creation,
464 /// both dead and alive, originals and rematerializations. No register is ever
465 /// deleted. Indices inside this vector serve as handles for rematerializable
466 /// registers.
467 SmallVector<Reg> Regs;
468 /// For each original register, stores unrematerializable read lanes of
469 /// register operands. This doesn't change after the initial collection
470 /// period, so the size of the vector indicates the number of original
471 /// registers.
473 /// Indicates the original register index of each rematerialization, in the
474 /// order in which they are created. The size of the vector indicates the
475 /// total number of rematerializations ever created, including those that were
476 /// deleted.
478 /// Maps original register indices to their currently alive
479 /// rematerializations. In practice most registers don't have
480 /// rematerializations so this is represented as a map to lower memory cost.
481 DenseMap<RegisterIdx, RematsOf> Rematerializations;
482
483 /// Registers mapped to the index of their corresponding rematerialization
484 /// data in the \ref Regs vector. This includes registers that no longer exist
485 /// in the MIR.
486 DenseMap<Register, RegisterIdx> RegToIdx;
487 /// Parent block of each region, in order.
489
490 /// Common post-processing step after creating a new register \p RematRegIdx
491 /// based on register \p ModelRegIdx.
492 void postRematerialization(RegisterIdx ModelRegIdx, RegisterIdx RematRegIdx);
493
494 /// Common pre-processing step before deleting a register \p DeleteRegIdx. The
495 /// register's defining instruction must still be alive.
496 void preDeletion(RegisterIdx DeleteRegIdx);
497
498 /// Extends \p LI over \p Mask to be live at \p UdeIdx.
499 void extendInterval(LiveInterval &LI, LaneBitmask Mask,
500 SlotIndex UseIdx) const;
501
502 /// Extends the live interval of rematerializable register \p RegIdx to be
503 /// live at the register slot of all MIs in \p NewUsers. Creates and/or
504 /// refines the interval's sub-ranges as needed. Updates the register's
505 /// defining instruction's dead flag as needed.
506 void extendToNewUsers(RegisterIdx RegIdx,
507 ArrayRef<MachineInstr *> NewUsers) const;
508
509 /// Shrinks the live interval of rematerializable register \p RegIdx to its
510 /// current uses. If the register has no users, deletes it along with
511 /// registers in its dependency DAG that no longer have users as a result.
512 void shrinkToUses(RegisterIdx RegIdx);
513
514 /// Shrinks the live interval of unrematerializable register \p Reg to its
515 /// current uses. The interval is split if necessary, creating new
516 /// unrematerializable registers and updating register dependencies as needed.
517 void shrinkToUsesUnremat(Register Reg);
518
519 /// During the analysis phase, creates a \ref Rematerializer::Reg object for
520 /// virtual register \p VirtRegIdx if it is rematerializable. \p MIRegion maps
521 /// all MIs to their parent region. Set bits in \p SeenRegs indicate virtual
522 /// register indices that have already been visited.
523 void
524 addRegIfRematerializable(unsigned VirtRegIdx,
525 const DenseMap<MachineInstr *, unsigned> &MIRegion,
526 BitVector &SeenRegs);
527
528 /// Determines whether \p MI is considered rematerializable. This further
529 /// restricts constraints imposed by the TII on rematerializable instructions,
530 /// requiring for example that the defined register is virtual and only
531 /// defined once.
532 bool isMIRematerializable(const MachineInstr &MI) const;
533
534 /// Implementation of \ref Rematerializer::transferUser that doesn't update
535 /// register users.
536 void transferUserImpl(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx,
537 MachineInstr &UserMI);
538
539 /// Deletes register \p RootIdx, which must not have any users left. If the
540 /// register is deleted, recursively deletes any of its transitive
541 /// rematerializable dependencies that no longer have users as a result. In
542 /// case of recursive deletion, all of a register's users are always deleted
543 /// before the register itself.
544 void deleteReg(RegisterIdx RootIdx);
545};
546
547/// Rematerializer listener with the ability to re-create deleted registers and
548/// rollback rematerializations. Starts recording register deletions and
549/// rematerializations as soon as it is attached to the rematerializer.
551public:
552 Rollbacker() = default;
553
554 /// Re-creates all deleted registers and rolls back all rematerializations
555 /// that were recorded.
556 void rollback(Rematerializer &Remater);
557
559 RegisterIdx RegIdx) override;
560
562 RegisterIdx RegIdx) override;
563
565 MachineInstr &MI) override;
566
567private:
568 struct DeadReg {
569 /// Register index.
570 RegisterIdx Idx;
571 /// Original register.
572 Register DefReg;
573 /// Original definition of the register. The underlying MI no longer exist
574 /// at rollback time, but may be referenced as re-creation position for
575 /// previously deleted registers.
577
578 LLVM_ABI DeadReg(RegisterIdx Idx, const Rematerializer &Remater)
579 : Idx(Idx), DefReg(Remater.getReg(Idx).getDefReg()),
580 DefMI(Remater.getReg(Idx).DefMI) {}
581 };
582
583 /// An insertion position in the MIR, either a MachineInstr* to insert before
584 /// or a MachineBasicBlock* to insert at the end of.
585 using InsertBeforePos = PointerUnion<MachineInstr *, MachineBasicBlock *>;
586
587 /// Original registers that have been deleted, in order of deletion.
588 SmallVector<DeadReg> DeadRegs;
589 /// Re-creation positions for all original registers that have been deleted,
590 /// in register deletion order. A position is either a MachineInstr* that
591 /// existed in the MIR at the time the rollbacker was attached to the
592 /// rematerializer, or a MachineBasicBlock*.
593 SmallVector<InsertBeforePos> Positions;
594 /// Maps all re-creation positions that exist in \ref Positions to the indices
595 /// of elements holding that position in the vector.
596 DenseMap<InsertBeforePos, SmallDenseSet<unsigned, 1>> PosToIdx;
597 /// Registers which have been rematerialized (from original index to
598 /// rematerialized index).
599 DenseMap<RegisterIdx, Rematerializer::RematsOf> Rematerializations;
600 /// Used to block further recording of events whenver we are actively rolling
601 /// back.
602 bool RollingBack = false;
603
604 InsertBeforePos makePos(MachineBasicBlock::iterator It,
605 MachineBasicBlock *MBB) const {
606 if (It == MBB->end())
607 return InsertBeforePos(MBB);
608 return InsertBeforePos(&*It);
609 }
610
611 /// Whether \p MI would be deleted if we were to rollback later. These are MIs
612 /// defining rematerializable registers whose creation has been recorded by
613 /// the rollbacker.
614 bool isRollbackableMI(const MachineInstr &MI,
615 const Rematerializer &Remater) const;
616
617 /// Switches all positions that point to \p MI to \p It in the \ref Positions
618 /// vector, and updates \ref PosToIdx accordingly. This is used when it
619 /// becomes known that \p MI is about to be permanently deleted from the MIR
620 /// and thus becomes an invalid re-creation position.
621 void invalidatePosition(MachineInstr *MI, MachineBasicBlock::iterator It);
622};
623
624} // namespace llvm
625
626#endif // LLVM_CODEGEN_REMATERIALIZER_H
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
#define LLVM_ABI
Definition Compiler.h:215
IRTranslator LLVM IR MI
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
This file defines the PointerUnion class, which is a discriminated union of pointer types.
Rematerializer::RegisterIdx RegisterIdx
Remove Loads Into Fake Uses
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Callback methods for LiveRangeEdit owners.
MachineInstrBundleIterator< MachineInstr > iterator
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
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 rematerializerNoteMIWillBeDeleted(const Rematerializer &Remater, MachineInstr &MI)
Called just before unrematerializable instruction MI is deleted from the MIR because it has become a ...
virtual void rematerializerNoteRegCreated(const Rematerializer &Remater, RegisterIdx NewRegIdx)
Called just after register NewRegIdx is created (following a rematerialization).
Rematerializer::RegisterIdx RegisterIdx
virtual void rematerializerNoteRegWillBeDeleted(const Rematerializer &Remater, RegisterIdx RegIdx)
Called just before register RegIdx is deleted from the MIR.
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
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 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
bool isPermanentlyDead(RegisterIdx RegIdx) const
Determines whether register RegIdx fully disappeared from the MIR.
unsigned RegisterIdx
Index type for rematerializable registers.
LLVM_ABI void recreateReg(RegisterIdx RegIdx, MachineBasicBlock::iterator InsertPos, Register DefReg)
Re-creates a previously deleted register RegIdx before InsertPos, which must be in the register's ori...
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.
ArrayRef< std::pair< Register, LaneBitmask > > getUnrematableDeps(RegisterIdx RegIdx) const
Returns unreamaterializable read lanes of register operands for register RegIdx.
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 ...
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...
LLVM_ABI bool isRegIdenticalAtUses(Register Reg, LaneBitmask Mask, SlotIndex RefSlot, ArrayRef< SlotIndex > Uses) const
Determines whether lanes Mask of register Reg habe the same value at all Uses as at RefSlot.
bool isRematerializedRegister(RegisterIdx RegIdx) const
Whether register RegIdx is a rematerialization of some original register.
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
LLVM_ABI RegisterIdx rematerializeReg(RegisterIdx RegIdx, unsigned UseRegion, MachineBasicBlock::iterator InsertPos, SmallVectorImpl< RegisterIdx > &&Dependencies)
Rematerializes register RegIdx before InsertPos in UseRegion, adding the new rematerializable registe...
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.
void rematerializerNoteRegWillBeDeleted(const Rematerializer &Remater, RegisterIdx RegIdx) override
Called just before register RegIdx is deleted from the MIR.
void rematerializerNoteMIWillBeDeleted(const Rematerializer &Remater, MachineInstr &MI) override
Called just before unrematerializable instruction MI is deleted from the MIR because it has become a ...
Rollbacker()=default
void rematerializerNoteRegCreated(const Rematerializer &Remater, RegisterIdx RegIdx) override
Called just after register NewRegIdx is created (following a rematerialization).
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:293
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.
#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...
ArrayRef(const T &OneElt) -> ArrayRef< T >
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)
A rematerializable register defined by a single machine instruction.
MachineInstr * DefMI
Single MI defining the rematerializable register.
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.
SmallVector< RegisterIdx, 2 > Dependencies
This register's rematerializable dependencies, one per unique rematerializable register operand.
SmallDenseSet< MachineInstr *, 4 > RegionUsers