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