LLVM  10.0.0svn
RenameIndependentSubregs.cpp
Go to the documentation of this file.
1 //===-- RenameIndependentSubregs.cpp - Live Interval Analysis -------------===//
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 /// Rename independent subregisters looks for virtual registers with
10 /// independently used subregisters and renames them to new virtual registers.
11 /// Example: In the following:
12 /// %0:sub0<read-undef> = ...
13 /// %0:sub1 = ...
14 /// use %0:sub0
15 /// %0:sub0 = ...
16 /// use %0:sub0
17 /// use %0:sub1
18 /// sub0 and sub1 are never used together, and we have two independent sub0
19 /// definitions. This pass will rename to:
20 /// %0:sub0<read-undef> = ...
21 /// %1:sub1<read-undef> = ...
22 /// use %1:sub1
23 /// %2:sub1<read-undef> = ...
24 /// use %2:sub1
25 /// use %0:sub0
26 //
27 //===----------------------------------------------------------------------===//
28 
29 #include "LiveRangeUtils.h"
30 #include "PHIEliminationUtils.h"
36 #include "llvm/CodeGen/Passes.h"
38 
39 using namespace llvm;
40 
41 #define DEBUG_TYPE "rename-independent-subregs"
42 
43 namespace {
44 
45 class RenameIndependentSubregs : public MachineFunctionPass {
46 public:
47  static char ID;
48  RenameIndependentSubregs() : MachineFunctionPass(ID) {}
49 
50  StringRef getPassName() const override {
51  return "Rename Disconnected Subregister Components";
52  }
53 
54  void getAnalysisUsage(AnalysisUsage &AU) const override {
55  AU.setPreservesCFG();
61  }
62 
63  bool runOnMachineFunction(MachineFunction &MF) override;
64 
65 private:
66  struct SubRangeInfo {
69  unsigned Index;
70 
71  SubRangeInfo(LiveIntervals &LIS, LiveInterval::SubRange &SR,
72  unsigned Index)
73  : ConEQ(LIS), SR(&SR), Index(Index) {}
74  };
75 
76  /// Split unrelated subregister components and rename them to new vregs.
77  bool renameComponents(LiveInterval &LI) const;
78 
79  /// Build a vector of SubRange infos and a union find set of
80  /// equivalence classes.
81  /// Returns true if more than 1 equivalence class was found.
82  bool findComponents(IntEqClasses &Classes,
83  SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
84  LiveInterval &LI) const;
85 
86  /// Distribute the LiveInterval segments into the new LiveIntervals
87  /// belonging to their class.
88  void distribute(const IntEqClasses &Classes,
89  const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
90  const SmallVectorImpl<LiveInterval*> &Intervals) const;
91 
92  /// Constructs main liverange and add missing undef+dead flags.
93  void computeMainRangesFixFlags(const IntEqClasses &Classes,
94  const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
95  const SmallVectorImpl<LiveInterval*> &Intervals) const;
96 
97  /// Rewrite Machine Operands to use the new vreg belonging to their class.
98  void rewriteOperands(const IntEqClasses &Classes,
99  const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
100  const SmallVectorImpl<LiveInterval*> &Intervals) const;
101 
102 
103  LiveIntervals *LIS;
105  const TargetInstrInfo *TII;
106 };
107 
108 } // end anonymous namespace
109 
111 
113 
114 INITIALIZE_PASS_BEGIN(RenameIndependentSubregs, DEBUG_TYPE,
115  "Rename Independent Subregisters", false, false)
118 INITIALIZE_PASS_END(RenameIndependentSubregs, DEBUG_TYPE,
119  "Rename Independent Subregisters", false, false)
120 
121 bool RenameIndependentSubregs::renameComponents(LiveInterval &LI) const {
122  // Shortcut: We cannot have split components with a single definition.
123  if (LI.valnos.size() < 2)
124  return false;
125 
126  SmallVector<SubRangeInfo, 4> SubRangeInfos;
127  IntEqClasses Classes;
128  if (!findComponents(Classes, SubRangeInfos, LI))
129  return false;
130 
131  // Create a new VReg for each class.
132  unsigned Reg = LI.reg;
133  const TargetRegisterClass *RegClass = MRI->getRegClass(Reg);
135  Intervals.push_back(&LI);
136  LLVM_DEBUG(dbgs() << printReg(Reg) << ": Found " << Classes.getNumClasses()
137  << " equivalence classes.\n");
138  LLVM_DEBUG(dbgs() << printReg(Reg) << ": Splitting into newly created:");
139  for (unsigned I = 1, NumClasses = Classes.getNumClasses(); I < NumClasses;
140  ++I) {
141  Register NewVReg = MRI->createVirtualRegister(RegClass);
142  LiveInterval &NewLI = LIS->createEmptyInterval(NewVReg);
143  Intervals.push_back(&NewLI);
144  LLVM_DEBUG(dbgs() << ' ' << printReg(NewVReg));
145  }
146  LLVM_DEBUG(dbgs() << '\n');
147 
148  rewriteOperands(Classes, SubRangeInfos, Intervals);
149  distribute(Classes, SubRangeInfos, Intervals);
150  computeMainRangesFixFlags(Classes, SubRangeInfos, Intervals);
151  return true;
152 }
153 
154 bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes,
156  LiveInterval &LI) const {
157  // First step: Create connected components for the VNInfos inside the
158  // subranges and count the global number of such components.
159  unsigned NumComponents = 0;
160  for (LiveInterval::SubRange &SR : LI.subranges()) {
161  SubRangeInfos.push_back(SubRangeInfo(*LIS, SR, NumComponents));
162  ConnectedVNInfoEqClasses &ConEQ = SubRangeInfos.back().ConEQ;
163 
164  unsigned NumSubComponents = ConEQ.Classify(SR);
165  NumComponents += NumSubComponents;
166  }
167  // Shortcut: With only 1 subrange, the normal separate component tests are
168  // enough and we do not need to perform the union-find on the subregister
169  // segments.
170  if (SubRangeInfos.size() < 2)
171  return false;
172 
173  // Next step: Build union-find structure over all subranges and merge classes
174  // across subranges when they are affected by the same MachineOperand.
175  const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
176  Classes.grow(NumComponents);
177  unsigned Reg = LI.reg;
178  for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
179  if (!MO.isDef() && !MO.readsReg())
180  continue;
181  unsigned SubRegIdx = MO.getSubReg();
182  LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
183  unsigned MergedID = ~0u;
184  for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) {
185  const LiveInterval::SubRange &SR = *SRInfo.SR;
186  if ((SR.LaneMask & LaneMask).none())
187  continue;
188  SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
189  Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
190  : Pos.getBaseIndex();
191  const VNInfo *VNI = SR.getVNInfoAt(Pos);
192  if (VNI == nullptr)
193  continue;
194 
195  // Map to local representant ID.
196  unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
197  // Global ID
198  unsigned ID = LocalID + SRInfo.Index;
199  // Merge other sets
200  MergedID = MergedID == ~0u ? ID : Classes.join(MergedID, ID);
201  }
202  }
203 
204  // Early exit if we ended up with a single equivalence class.
205  Classes.compress();
206  unsigned NumClasses = Classes.getNumClasses();
207  return NumClasses > 1;
208 }
209 
210 void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes,
211  const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
212  const SmallVectorImpl<LiveInterval*> &Intervals) const {
213  const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
214  unsigned Reg = Intervals[0]->reg;
215  for (MachineRegisterInfo::reg_nodbg_iterator I = MRI->reg_nodbg_begin(Reg),
216  E = MRI->reg_nodbg_end(); I != E; ) {
217  MachineOperand &MO = *I++;
218  if (!MO.isDef() && !MO.readsReg())
219  continue;
220 
221  auto *MI = MO.getParent();
222  SlotIndex Pos = LIS->getInstructionIndex(*MI);
223  Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
224  : Pos.getBaseIndex();
225  unsigned SubRegIdx = MO.getSubReg();
226  LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
227 
228  unsigned ID = ~0u;
229  for (const SubRangeInfo &SRInfo : SubRangeInfos) {
230  const LiveInterval::SubRange &SR = *SRInfo.SR;
231  if ((SR.LaneMask & LaneMask).none())
232  continue;
233  const VNInfo *VNI = SR.getVNInfoAt(Pos);
234  if (VNI == nullptr)
235  continue;
236 
237  // Map to local representant ID.
238  unsigned LocalID = SRInfo.ConEQ.getEqClass(VNI);
239  // Global ID
240  ID = Classes[LocalID + SRInfo.Index];
241  break;
242  }
243 
244  unsigned VReg = Intervals[ID]->reg;
245  MO.setReg(VReg);
246 
247  if (MO.isTied() && Reg != VReg) {
248  /// Undef use operands are not tracked in the equivalence class,
249  /// but need to be updated if they are tied; take care to only
250  /// update the tied operand.
251  unsigned OperandNo = MI->getOperandNo(&MO);
252  unsigned TiedIdx = MI->findTiedOperandIdx(OperandNo);
253  MI->getOperand(TiedIdx).setReg(VReg);
254 
255  // above substitution breaks the iterator, so restart.
256  I = MRI->reg_nodbg_begin(Reg);
257  }
258  }
259  // TODO: We could attempt to recompute new register classes while visiting
260  // the operands: Some of the split register may be fine with less constraint
261  // classes than the original vreg.
262 }
263 
265  const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
266  const SmallVectorImpl<LiveInterval*> &Intervals) const {
267  unsigned NumClasses = Classes.getNumClasses();
268  SmallVector<unsigned, 8> VNIMapping;
270  BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
271  for (const SubRangeInfo &SRInfo : SubRangeInfos) {
272  LiveInterval::SubRange &SR = *SRInfo.SR;
273  unsigned NumValNos = SR.valnos.size();
274  VNIMapping.clear();
275  VNIMapping.reserve(NumValNos);
276  SubRanges.clear();
277  SubRanges.resize(NumClasses-1, nullptr);
278  for (unsigned I = 0; I < NumValNos; ++I) {
279  const VNInfo &VNI = *SR.valnos[I];
280  unsigned LocalID = SRInfo.ConEQ.getEqClass(&VNI);
281  unsigned ID = Classes[LocalID + SRInfo.Index];
282  VNIMapping.push_back(ID);
283  if (ID > 0 && SubRanges[ID-1] == nullptr)
284  SubRanges[ID-1] = Intervals[ID]->createSubRange(Allocator, SR.LaneMask);
285  }
286  DistributeRange(SR, SubRanges.data(), VNIMapping);
287  }
288 }
289 
290 static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos) {
291  for (const LiveInterval::SubRange &SR : LI.subranges()) {
292  if (SR.liveAt(Pos))
293  return true;
294  }
295  return false;
296 }
297 
298 void RenameIndependentSubregs::computeMainRangesFixFlags(
299  const IntEqClasses &Classes,
300  const SmallVectorImpl<SubRangeInfo> &SubRangeInfos,
301  const SmallVectorImpl<LiveInterval*> &Intervals) const {
302  BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
303  const SlotIndexes &Indexes = *LIS->getSlotIndexes();
304  for (size_t I = 0, E = Intervals.size(); I < E; ++I) {
305  LiveInterval &LI = *Intervals[I];
306  unsigned Reg = LI.reg;
307 
309 
310  // There must be a def (or live-in) before every use. Splitting vregs may
311  // violate this principle as the splitted vreg may not have a definition on
312  // every path. Fix this by creating IMPLICIT_DEF instruction as necessary.
313  for (const LiveInterval::SubRange &SR : LI.subranges()) {
314  // Search for "PHI" value numbers in the subranges. We must find a live
315  // value in each predecessor block, add an IMPLICIT_DEF where it is
316  // missing.
317  for (unsigned I = 0; I < SR.valnos.size(); ++I) {
318  const VNInfo &VNI = *SR.valnos[I];
319  if (VNI.isUnused() || !VNI.isPHIDef())
320  continue;
321 
322  SlotIndex Def = VNI.def;
323  MachineBasicBlock &MBB = *Indexes.getMBBFromIndex(Def);
324  for (MachineBasicBlock *PredMBB : MBB.predecessors()) {
325  SlotIndex PredEnd = Indexes.getMBBEndIdx(PredMBB);
326  if (subRangeLiveAt(LI, PredEnd.getPrevSlot()))
327  continue;
328 
329  MachineBasicBlock::iterator InsertPos =
330  llvm::findPHICopyInsertPoint(PredMBB, &MBB, Reg);
331  const MCInstrDesc &MCDesc = TII->get(TargetOpcode::IMPLICIT_DEF);
332  MachineInstrBuilder ImpDef = BuildMI(*PredMBB, InsertPos,
333  DebugLoc(), MCDesc, Reg);
334  SlotIndex DefIdx = LIS->InsertMachineInstrInMaps(*ImpDef);
335  SlotIndex RegDefIdx = DefIdx.getRegSlot();
336  for (LiveInterval::SubRange &SR : LI.subranges()) {
337  VNInfo *SRVNI = SR.getNextValue(RegDefIdx, Allocator);
338  SR.addSegment(LiveRange::Segment(RegDefIdx, PredEnd, SRVNI));
339  }
340  }
341  }
342  }
343 
344  for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
345  if (!MO.isDef())
346  continue;
347  unsigned SubRegIdx = MO.getSubReg();
348  if (SubRegIdx == 0)
349  continue;
350  // After assigning the new vreg we may not have any other sublanes living
351  // in and out of the instruction anymore. We need to add new dead and
352  // undef flags in these cases.
353  if (!MO.isUndef()) {
354  SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
355  if (!subRangeLiveAt(LI, Pos))
356  MO.setIsUndef();
357  }
358  if (!MO.isDead()) {
359  SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent()).getDeadSlot();
360  if (!subRangeLiveAt(LI, Pos))
361  MO.setIsDead();
362  }
363  }
364 
365  if (I == 0)
366  LI.clear();
367  LIS->constructMainRangeFromSubranges(LI);
368  // A def of a subregister may be a use of other register lanes. Replacing
369  // such a def with a def of a different register will eliminate the use,
370  // and may cause the recorded live range to be larger than the actual
371  // liveness in the program IR.
372  LIS->shrinkToUses(&LI);
373  }
374 }
375 
376 bool RenameIndependentSubregs::runOnMachineFunction(MachineFunction &MF) {
377  // Skip renaming if liveness of subregister is not tracked.
378  MRI = &MF.getRegInfo();
379  if (!MRI->subRegLivenessEnabled())
380  return false;
381 
382  LLVM_DEBUG(dbgs() << "Renaming independent subregister live ranges in "
383  << MF.getName() << '\n');
384 
385  LIS = &getAnalysis<LiveIntervals>();
386  TII = MF.getSubtarget().getInstrInfo();
387 
388  // Iterate over all vregs. Note that we query getNumVirtRegs() the newly
389  // created vregs end up with higher numbers but do not need to be visited as
390  // there can't be any further splitting.
391  bool Changed = false;
392  for (size_t I = 0, E = MRI->getNumVirtRegs(); I < E; ++I) {
393  unsigned Reg = Register::index2VirtReg(I);
394  if (!LIS->hasInterval(Reg))
395  continue;
396  LiveInterval &LI = LIS->getInterval(Reg);
397  if (!LI.hasSubRanges())
398  continue;
399 
400  Changed |= renameComponents(LI);
401  }
402 
403  return Changed;
404 }
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
Definition: LiveInterval.h:77
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
char & RenameIndependentSubregsID
This pass detects subregister lanes in a virtual register that are used independently of other lanes ...
const unsigned reg
Definition: LiveInterval.h:704
void grow(unsigned N)
grow - Increase capacity to hold 0 .
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
Definition: SlotIndexes.h:241
SlotIndex def
The index of the defining instruction.
Definition: LiveInterval.h:60
This class represents lattice values for constants.
Definition: AllocatorList.h:23
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:675
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:178
unsigned Reg
MachineBasicBlock::iterator findPHICopyInsertPoint(MachineBasicBlock *MBB, MachineBasicBlock *SuccMBB, unsigned SrcReg)
findPHICopyInsertPoint - Find a safe place in MBB to insert a copy from SrcReg when following the CFG...
unsigned getSubReg() const
void compress()
compress - Compress equivalence classes by numbering them 0 .
A live range for subregisters.
Definition: LiveInterval.h:682
This represents a simple continuous liveness interval for a value.
Definition: LiveInterval.h:161
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:33
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition: Register.h:83
void reserve(size_type N)
Definition: SmallVector.h:369
VNInfo - Value Number Information.
Definition: LiveInterval.h:52
bool isUnused() const
Returns true if this value is unused.
Definition: LiveInterval.h:80
bool isEarlyClobber() const
void removeEmptySubRanges()
Removes all subranges without any segments (subranges without segments are not considered valid and s...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:50
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
iterator_range< subrange_iterator > subranges()
Definition: LiveInterval.h:760
bool hasSubRanges() const
Returns true if subregister liveness information is available.
Definition: LiveInterval.h:788
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register. ...
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
Returns the basic block which the given index falls in.
Definition: SlotIndexes.h:517
SlotIndexes pass.
Definition: SlotIndexes.h:314
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def...
Definition: SlotIndexes.h:254
void setReg(Register Reg)
Change the register this operand corresponds to.
virtual const TargetInstrInfo * getInstrInfo() const
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
static void DistributeRange(LiveRangeT &LR, LiveRangeT *SplitLRs[], EqClassesT VNIClasses)
Helper function that distributes live range value numbers and the corresponding segments of a master ...
TargetInstrInfo - Interface to description of machine instruction set.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
Definition: LiveInterval.h:408
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity, const unsigned *CurSize, unsigned NewSize[], unsigned Position, bool Grow)
IntervalMapImpl::distribute - Compute a new distribution of node elements after an overflow or underf...
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:140
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
unsigned Classify(const LiveRange &LR)
Classify the values in LR into connected components.
unsigned getNumClasses() const
getNumClasses - Return the number of equivalence classes after compress() was called.
Definition: IntEqClasses.h:71
Rename Independent Subregisters
Represent the analysis usage information of a pass.
iterator_range< pred_iterator > predecessors()
SlotIndex getMBBEndIdx(unsigned Num) const
Returns the last index in the given basic block number.
Definition: SlotIndexes.h:479
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
size_t size() const
Definition: SmallVector.h:52
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
unsigned join(unsigned a, unsigned b)
Join the equivalence classes of a and b.
Basic Register Allocator
#define DEBUG_TYPE
ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a LiveInterval into equivalence cl...
Definition: LiveInterval.h:962
MachineOperand class - Representation of each machine instruction operand.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx. ...
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:301
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
VNInfoList valnos
Definition: LiveInterval.h:199
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
pointer data()
Return a pointer to the vector&#39;s buffer, even if empty().
Definition: SmallVector.h:144
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
SlotIndex getPrevSlot() const
Returns the previous slot in the index list.
Definition: SlotIndexes.h:289
INITIALIZE_PASS_BEGIN(RenameIndependentSubregs, DEBUG_TYPE, "Rename Independent Subregisters", false, false) INITIALIZE_PASS_END(RenameIndependentSubregs
#define I(x, y, z)
Definition: MD5.cpp:58
static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos)
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
#define LLVM_DEBUG(X)
Definition: Debug.h:122
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:83
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
void resize(size_type N)
Definition: SmallVector.h:344