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/STLExtras.h"
24#include <iterator>
25
26namespace llvm {
27
28/// MIR-level target-independent rematerializer. Provides an API to identify and
29/// rematerialize registers within a machine function.
30///
31/// At the moment this supports rematerializing registers that meet all of the
32/// following constraints.
33/// 1. The register is virtual and has a single defining instruction.
34/// 2. The single defining instruction is deemed rematerializable by the TII and
35/// doesn't have any physical register use that is both non-constant and
36/// non-ignorable.
37/// 3. The register has at least one non-debug use that is inside or at a region
38/// boundary (see below for what we consider to be a region).
39///
40/// Rematerializable registers (represented by \ref Rematerializer::Reg) form a
41/// DAG of their own, with every register having incoming edges from all
42/// rematerializable registers which are read by the instruction defining it. It
43/// is possible to rematerialize registers with unrematerializable dependencies;
44/// however the latter are not considered part of this DAG since their
45/// position/identity never change and therefore do not require the same level
46/// of tracking.
47///
48/// Each register has a "dependency DAG" which is defined as the subset of nodes
49/// in the overall DAG that have at least one path to the register, which is
50/// called the "root" register in this context. Semantically, these nodes are
51/// the registers which are involved into the computation of the root register
52/// i.e., all of its transitive dependencies. We use the term "root" because all
53/// paths within the dependency DAG of a register terminate at it; however,
54/// there may be multiple paths between a non-root node and the root node, so a
55/// dependency DAG is not always a tree.
56///
57/// The API uses dense unsigned integers starting at 0 to reference
58/// rematerializable registers. These indices are immutable i.e., even when
59/// registers are deleted their respective integer handle remain valid. Method
60/// which perform actual rematerializations should however be assumed to
61/// invalidate addresses to \ref Rematerializer::Reg objects.
62///
63/// The rematerializer tracks def/use points of registers based on regions.
64/// These are alike the regions the machine scheduler works on. A region is
65/// simply a pair on MBB iterators encoding a range of machine instructions. The
66/// first iterator (beginning of the region) is inclusive whereas the second
67/// iterator (end of the region) is exclusive and can either point to a MBB's
68/// end sentinel or an actual MI (not necessarily a terminator). Regions must be
69/// non-empty, cannot overlap, and cannot contain terminators. However, they do
70/// not have to cover the whole function.
71///
72/// The API uses dense unsigned integers starting at 0 to reference regions.
73/// These map directly to the indices of the corresponding regions in the region
74/// vector passed during construction.
75///
76/// The rematerializer supports rematerializing arbitrary complex DAGs of
77/// registers to regions where these registers are used, with the option of
78/// re-using non-root registers or their previous rematerializations instead of
79/// rematerializing them again. It also optionally supports rolling back
80/// previous rematerializations (set during analysis phase, see \ref
81/// Rematerializer::analyze) to restore the MIR state to what it was
82/// pre-rematerialization. When enabled, machine instructions defining
83/// rematerializable registers that no longer have any uses following previous
84/// rematerializations will not be deleted from the MIR; their opcode will
85/// instead be set to a DEBUG_VALUE and their read register operands set to the
86/// null register. This maintains their position in the MIR and keeps the
87/// original register alive for potential rollback while allowing other
88/// passes/analyzes (e.g., machine scheduler, live-interval analysis) to ignore
89/// them. \ref Rematerializer::commitRematerializations actually deletes those
90/// instructions when rollback is deemed unnecessary.
91///
92/// Throughout its lifetime, the rematerializer tracks new registers it creates
93/// (which are rematerializable by construction) and their relations to other
94/// registers. It performs DAG updates immediately on rematerialization but
95/// defers/batches all necessary live interval updates to reduce the number of
96/// expensive LIS queries when successively rematerializing many registers. \ref
97/// Rematerializer::updateLiveIntervals performs all currently batched live
98/// interval updates.
99///
100/// In its nomenclature, the rematerializer differentiates between "original
101/// registers" (registers that were present when it analyzed the function) and
102/// rematerializations of these original registers. Rematerializations have an
103/// "origin" which is the index of the original regiser they were rematerialized
104/// from (transitivity applies; a rematerialization and all of its own
105/// rematerializations have the same origin). Semantically, only original
106/// registers have rematerializations.
108public:
109 /// Index type for rematerializable registers.
111
112 /// A rematerializable register defined by a single machine instruction.
113 ///
114 /// A rematerializable register has a set of dependencies, which correspond
115 /// to the unique read register operands of its defining instruction.
116 /// They are identified by their machine operand index, and can themselves be
117 /// rematerializable. Operand indices corresponding to unrematerializable
118 /// dependencies are managed by and queried from the rematerializer.
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 marks it for deletion. Its defining instruction either
125 /// becomes nullptr (without rollback support) or its opcode is set to
126 /// TargetOpcode::DBG_VALUE (with rollback support) until \ref
127 /// Rematerializer::commitRematerializations is called.
128 struct Reg {
129 /// Single MI defining the rematerializable register.
131 /// Defining region of \p DefMI.
132 unsigned DefRegion;
133 /// The rematerializable register's lane bitmask.
135
137 /// Uses of the register, mapped by region.
139
140 /// A read register operand of \p DefMI that is rematerializable (according
141 /// to the rematerializer).
142 struct Dependency {
143 /// The register's machine operand index in \p DefMI.
144 unsigned MOIdx;
145 /// The corresponding register's index in the rematerializer.
147
150 };
151 /// This register's rematerializable dependencies, one per unique
152 /// rematerializable register operand.
154
155 /// Returns the rematerializable register from its defining instruction.
156 inline Register getDefReg() const {
157 assert(DefMI && "defining instruction was deleted");
158 assert(DefMI->getOperand(0).isDef() && "not a register def");
159 return DefMI->getOperand(0).getReg();
160 }
161
162 bool hasUsersInDefRegion() const {
163 return !Uses.empty() && Uses.contains(DefRegion);
164 }
165
167 if (Uses.empty())
168 return false;
169 return Uses.size() > 1 || Uses.begin()->first != DefRegion;
170 }
171
172 /// Returns the first and last user of the register in region \p UseRegion.
173 /// If the register has no user in the region, returns a pair of nullptr's.
174 std::pair<MachineInstr *, MachineInstr *>
175 getRegionUseBounds(unsigned UseRegion, const LiveIntervals &LIS) const;
176
177 bool isAlive() const {
178 return DefMI && DefMI->getOpcode() != TargetOpcode::DBG_VALUE;
179 }
180
181 private:
182 void addUser(MachineInstr *MI, unsigned Region);
183 void addUsers(const RegionUsers &NewUsers, unsigned Region);
184 void eraseUser(MachineInstr *MI, unsigned Region);
185
186 friend Rematerializer;
187 };
188
189 /// Error value for register indices.
190 static constexpr unsigned NoReg = ~0;
191
192 /// A region's boundaries i.e. a pair of instruction bundle iterators. The
193 /// lower boundary is inclusive, the upper boundary is exclusive.
195 std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>;
196
197 /// Simply initializes some internal state, does not identify
198 /// rematerialization candidates.
201 LiveIntervals &LIS);
202
203 /// Goes through the whole MF and identifies all rematerializable registers.
204 /// When \p SupportRollback is set, rematerializations of original registers
205 /// can be rolled back and original registers are maintained in the IR even
206 /// when they longer have any users. Returns whether there is any
207 /// rematerializable register in regions.
208 bool analyze(bool SupportRollback);
209
210 inline const Reg &getReg(RegisterIdx RegIdx) const {
211 assert(RegIdx < Regs.size() && "out of bounds");
212 return Regs[RegIdx];
213 };
214 inline ArrayRef<Reg> getRegs() const { return Regs; };
215 inline unsigned getNumRegs() const { return Regs.size(); };
216
217 inline const RegionBoundaries &getRegion(RegisterIdx RegionIdx) {
218 assert(RegionIdx < Regions.size() && "out of bounds");
219 return Regions[RegionIdx];
220 }
221 inline unsigned getNumRegions() const { return Regions.size(); }
222
223 /// Whether register \p RegIdx is a rematerialization of some original
224 /// register.
225 inline bool isRematerializedRegister(RegisterIdx RegIdx) const {
226 assert(RegIdx < Regs.size() && "out of bounds");
227 return RegIdx >= UnrematableOprds.size();
228 }
229 /// Returns the origin index of rematerializable register \p RegIdx.
230 inline RegisterIdx getOriginOf(RegisterIdx RematRegIdx) const {
231 assert(isRematerializedRegister(RematRegIdx) && "not a rematerialization");
232 return Origins[RematRegIdx - UnrematableOprds.size()];
233 }
234 /// If \p RegIdx is a rematerialization, returns its origin's index. If it is
235 /// an original register's index, returns the same index.
237 if (isRematerializedRegister(RegIdx))
238 return getOriginOf(RegIdx);
239 return RegIdx;
240 }
241 /// Returns operand indices corresponding to unrematerializable operands for
242 /// any register \p RegIdx.
243 inline ArrayRef<unsigned> getUnrematableOprds(unsigned RegIdx) const {
244 return UnrematableOprds[getOriginOrSelf(RegIdx)];
245 }
246
247 /// When rematerializating a register (called the "root" register in this
248 /// context) to a given position, we must decide what to do with all its
249 /// rematerializable dependencies (for unrematerializable dependencies, we
250 /// have no choice but to re-use the same register). For each rematerializable
251 /// dependency we can either
252 /// 1. rematerialize it along with the register,
253 /// 2. re-use it as-is, or
254 /// 3. re-use a pre-existing rematerialization of it.
255 /// In case 1, the same decision needs to be made for all of the dependency's
256 /// dependencies. In cases 2 and 3, the dependency's dependencies need not be
257 /// examined.
258 ///
259 /// This struct allows to encode decisions of types (2) and (3) when
260 /// rematerialization of all of the root's dependency DAG is undesirable.
261 /// During rematerialization, registers in the root's dependency DAG which
262 /// have a path to the root made up exclusively of non-re-used registers will
263 /// be rematerialized along with the root.
265 /// Keys and values are rematerializable register indices.
266 ///
267 /// Before rematerialization, this only contains entries for non-root
268 /// registers of the root's dependency DAG which should not be
269 /// rematerialized i.e., for which an existing register should be used
270 /// instead. These map each such non-root register to either the same
271 /// register (case 2, \ref DependencyReuseInfo::reuse) or to a
272 /// rematerialization of the key register (case 3, \ref
273 /// DependencyReuseInfo::useRemat).
274 ///
275 /// After rematerialization, this contains additional entries for non-root
276 /// registers of the root's dependency DAG that needed to be rematerialized
277 /// along the root. These map each such non-root register to their
278 /// corresponding new rematerialization that is used in the rematerialized
279 /// root's dependency DAG. It follows that the difference in map size before
280 /// and after rematerialization indicates the number of non-root registers
281 /// that were rematerialized along the root.
283
285 DependencyMap.insert({DepIdx, DepIdx});
286 return *this;
287 }
289 DependencyMap.insert({DepIdx, DepRematIdx});
290 return *this;
291 }
293 DependencyMap.clear();
294 return *this;
295 }
296 };
297
298 /// Rematerializes register \p RootIdx just before its first user inside
299 /// region \p UseRegion, transfers all its users in the region to the new
300 /// register, and returns the latter's index. The root's dependency DAG is
301 /// rematerialized or re-used according to \p DRI.
302 ///
303 /// When the method returns, \p DRI contains additional entries for non-root
304 /// registers of the root's dependency DAG that needed to be rematerialized
305 /// along the root. References to \ref Rematerializer::Reg should be
306 /// considered invalidated by calls to this method.
307 RegisterIdx rematerializeToRegion(RegisterIdx RootIdx, unsigned UseRegion,
308 DependencyReuseInfo &DRI);
309
310 /// Rematerializes register \p RootIdx before position \p InsertPos and
311 /// returns the new register's index. The root's dependency DAG is
312 /// rematerialized or re-used according to \p DRI.
313 ///
314 /// When the method returns, \p DRI contains additional entries for non-root
315 /// registers of the root's dependency DAG that needed to be rematerialized
316 /// along the root. References to \ref Rematerializer::Reg should be
317 /// considered invalidated by calls to this method.
320 DependencyReuseInfo &DRI);
321
322 /// Rolls back all rematerializations of original register \p RootIdx,
323 /// transfering all their users back to it and permanently deleting them from
324 /// the MIR. The root register is revived if it was fully rematerialized (this
325 /// requires that rollback support was set at that time). Transitive
326 /// dependencies of the root register that were fully rematerialized are
327 /// re-vived at their original positions; this requires that rollback support
328 /// was set when they were rematerialized.
329 void rollbackRematsOf(RegisterIdx RootIdx);
330
331 /// Rolls back register \p RematIdx (which must be a rematerialization)
332 /// transfering all its users back to its origin. The latter is revived if it
333 /// was fully rematerialized (this requires that rollback support was set at
334 /// that time).
335 void rollback(RegisterIdx RematIdx);
336
337 /// Revives original register \p RootIdx at its original position in the MIR
338 /// if it was fully rematerialized with rollback support set. Transitive
339 /// dependencies of the root register that were fully rematerialized are
340 /// revived at their original positions; this requires that rollback support
341 /// was set when they were themselves rematerialized.
342 void reviveRegIfDead(RegisterIdx RootIdx);
343
344 /// Transfers all users of register \p FromRegIdx in region \p UseRegion to \p
345 /// ToRegIdx, the latter of which must be a rematerialization of the former or
346 /// have the same origin register. Users in \p UseRegion must be reachable
347 /// from \p ToRegIdx.
348 void transferRegionUsers(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx,
349 unsigned UseRegion);
350
351 /// Transfers user \p UserMI from register \p FromRegIdx to \p ToRegIdx,
352 /// the latter of which must be a rematerialization of the former or have the
353 /// same origin register. \p UserMI must be a direct user of \p FromRegIdx. \p
354 /// UserMI must be reachable from \p ToRegIdx.
355 void transferUser(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx,
356 MachineInstr &UserMI);
357
358 /// Recomputes all live intervals that have changed as a result of previous
359 /// rematerializations/rollbacks.
360 void updateLiveIntervals();
361
362 /// Deletes unused rematerialized registers that were left in the MIR to
363 /// support rollback.
365
366 /// Determines whether (sub-)register operand \p MO has the same value at
367 /// all \p Uses as at \p MO. This implies that it is also available at all \p
368 /// Uses according to its current live interval.
370
371 /// Finds the closest rematerialization of register \p RegIdx in region \p
372 /// Region that exists before slot \p Before. If no such rematerialization
373 /// exists, returns \ref Rematerializer::NoReg.
375 SlotIndex Before) const;
376
378 Printable printID(RegisterIdx RegIdx) const;
379 Printable printRematReg(RegisterIdx RegIdx, bool SkipRegions = false) const;
380 Printable printRegUsers(RegisterIdx RegIdx) const;
381 Printable printUser(const MachineInstr *MI) const;
382
383private:
386 LiveIntervals &LIS;
387 const TargetInstrInfo &TII;
388 const TargetRegisterInfo &TRI;
389
390 /// Rematerializable registers identified since the rematerializer's creation,
391 /// both dead and alive, originals and rematerializations. No register is ever
392 /// deleted. Indices inside this vector serve as handles for rematerializable
393 /// registers.
394 SmallVector<Reg> Regs;
395 /// For each original register, stores indices of its read register operands
396 /// which are unrematerializable. This doesn't change after the initial
397 /// collection period, so the size of the vector indicates the number of
398 /// original registers.
399 SmallVector<SmallVector<unsigned, 2>> UnrematableOprds;
400 /// Indicates the original register index of each rematerialization, in the
401 /// order in which they are created. The size of the vector indicates the
402 /// total number of rematerializations ever created, including those that were
403 /// deleted or rolled back.
405 using RematsOf = SmallDenseSet<RegisterIdx, 4>;
406 /// Maps original register indices to their currently alive
407 /// rematerializations. In practice most registers don't have
408 /// rematerializations so this is represented as a map to lower memory cost.
409 DenseMap<RegisterIdx, RematsOf> Rematerializations;
410
411 /// Registers mapped to the index of their corresponding rematerialization
412 /// data in the \ref Regs vector. This includes registers that no longer exist
413 /// in the MIR.
415 /// Maps all MIs to their parent region. Region terminators are considered
416 /// part of the region they terminate.
418 /// Set of registers whose live-range may have changed during past
419 /// rematerializations/rollbacks.
420 DenseSet<RegisterIdx> LISUpdates;
421 /// Keys are fully rematerialized registers whose rematerializations are
422 /// currently rollback-able. Values map register machine operand indices to
423 /// their original register.
425 /// Whether all rematerializations of registers identified during the last
426 /// analysis phase will be rollback-able.
427 bool SupportRollback = false;
428
429 /// During the analysis phase, creates a \ref Rematerializer::Reg object for
430 /// virtual register \p VirtRegIdx if it
431 void addRegIfRematerializable(unsigned VirtRegIdx, BitVector &SeenRegs);
432
433 /// Determines whether \p MI is considered rematerializable. This further
434 /// restricts constraints imposed by the TII on rematerializable instructions,
435 /// requiring for example that the defined register is virtual and only
436 /// defined once.
437 bool isMIRematerializable(const MachineInstr &MI) const;
438
439 /// Rematerializes register \p RegIdx at \p InsertPos, adding the new
440 /// rematerializable register to the backing vector \ref Regs and returning
441 /// its index inside the vector. Sets the new registers' rematerializable
442 /// dependencies to \p Dependencies (these are assumed to already exist in the
443 /// MIR) and its unrematerializable dependencies to the same as \p RegIdx. The
444 /// new register initially has no user. Since the method appends to \ref Regs,
445 /// references to elements within it should be considered invalidated across
446 /// calls to this method unless the vector can be guaranteed to have enough
447 /// space for an extra element.
448 RegisterIdx rematerializeReg(RegisterIdx RegIdx,
450 SmallVectorImpl<Reg::Dependency> &&Dependencies);
451
452 /// Implementation of \ref Rematerializer::transferUser that doesn't update
453 /// register users.
454 void transferUserImpl(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx,
455 MachineInstr &UserMI);
456
457 /// Deletes register \p RootIdx if it no longer has any user. If the register
458 /// is deleted, recursively deletes any of its transitive rematerializable
459 /// dependencies that no longer have users as a result.
460 void deleteRegIfUnused(RegisterIdx RootIdx);
461
462 /// Deletes rematerializable register \p RegIdx from the DAG and relevant
463 /// internal state.
464 void deleteReg(RegisterIdx RegIdx);
465
466 /// If \p MI's first operand defines a register and that register is a
467 /// rematerializable register tracked by the rematerializer, returns its
468 /// index in the \ref Regs vector. Otherwise returns \ref
469 /// Rematerializer::NoReg.
470 RegisterIdx getDefRegIdx(const MachineInstr &MI) const;
471};
472
473} // namespace llvm
474
475#endif // LLVM_CODEGEN_REMATERIALIZER_H
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Register const TargetRegisterInfo * TRI
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Implements a dense probed hash-table based set.
Definition DenseSet.h:279
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,...
Simple wrapper around std::function<void(raw_ostream&)>.
Definition Printable.h:38
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Printable printDependencyDAG(RegisterIdx RootIdx) const
RegisterIdx getOriginOrSelf(RegisterIdx RegIdx) const
If RegIdx is a rematerialization, returns its origin's index.
static constexpr unsigned NoReg
Error value for register indices.
Printable printID(RegisterIdx RegIdx) const
ArrayRef< Reg > getRegs() const
void rollbackRematsOf(RegisterIdx RootIdx)
Rolls back all rematerializations of original register RootIdx, transfering all their users back to i...
unsigned getNumRegs() const
RegisterIdx rematerializeToPos(RegisterIdx RootIdx, MachineBasicBlock::iterator InsertPos, DependencyReuseInfo &DRI)
Rematerializes register RootIdx before position InsertPos and returns the new register's index.
void transferUser(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx, MachineInstr &UserMI)
Transfers user UserMI from register FromRegIdx to ToRegIdx, the latter of which must be a remateriali...
RegisterIdx getOriginOf(RegisterIdx RematRegIdx) const
Returns the origin index of rematerializable register RegIdx.
const Reg & getReg(RegisterIdx RegIdx) const
void updateLiveIntervals()
Recomputes all live intervals that have changed as a result of previous rematerializations/rollbacks.
RegisterIdx rematerializeToRegion(RegisterIdx RootIdx, unsigned UseRegion, DependencyReuseInfo &DRI)
Rematerializes register RootIdx just before its first user inside region UseRegion,...
std::pair< MachineBasicBlock::iterator, MachineBasicBlock::iterator > RegionBoundaries
A region's boundaries i.e.
bool analyze(bool SupportRollback)
Goes through the whole MF and identifies all rematerializable registers.
void rollback(RegisterIdx RematIdx)
Rolls back register RematIdx (which must be a rematerialization) transfering all its users back to it...
unsigned RegisterIdx
Index type for rematerializable registers.
void reviveRegIfDead(RegisterIdx RootIdx)
Revives original register RootIdx at its original position in the MIR if it was fully rematerialized ...
bool isMOIdenticalAtUses(MachineOperand &MO, ArrayRef< SlotIndex > Uses) const
Determines whether (sub-)register operand MO has the same value at all Uses as at MO.
void transferRegionUsers(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx, unsigned UseRegion)
Transfers all users of register FromRegIdx in region UseRegion to ToRegIdx, the latter of which must ...
void commitRematerializations()
Deletes unused rematerialized registers that were left in the MIR to support rollback.
unsigned getNumRegions() const
Rematerializer(MachineFunction &MF, SmallVectorImpl< RegionBoundaries > &Regions, LiveIntervals &LIS)
Simply initializes some internal state, does not identify rematerialization candidates.
ArrayRef< unsigned > getUnrematableOprds(unsigned RegIdx) const
Returns operand indices corresponding to unrematerializable operands for any register RegIdx.
const RegionBoundaries & getRegion(RegisterIdx RegionIdx)
Printable printUser(const MachineInstr *MI) const
bool isRematerializedRegister(RegisterIdx RegIdx) const
Whether register RegIdx is a rematerialization of some original register.
Printable printRematReg(RegisterIdx RegIdx, bool SkipRegions=false) const
Printable printRegUsers(RegisterIdx RegIdx) const
RegisterIdx findRematInRegion(RegisterIdx RegIdx, unsigned Region, SlotIndex Before) const
Finds the closest rematerialization of register RegIdx in region Region that exists before slot Befor...
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:291
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...
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
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.
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