LLVM  12.0.0git
MVEVPTOptimisationsPass.cpp
Go to the documentation of this file.
1 //===-- MVEVPTOptimisationsPass.cpp ---------------------------------------===//
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 This pass does a few optimisations related to MVE VPT blocks before
10 /// register allocation is performed. The goal is to maximize the sizes of the
11 /// blocks that will be created by the MVE VPT Block Insertion pass (which runs
12 /// after register allocation). The first optimisation done by this pass is the
13 /// replacement of "opposite" VCMPs with VPNOTs, so the Block Insertion pass
14 /// can delete them later to create larger VPT blocks.
15 /// The second optimisation replaces re-uses of old VCCR values with VPNOTs when
16 /// inside a block of predicated instructions. This is done to avoid
17 /// spill/reloads of VPR in the middle of a block, which prevents the Block
18 /// Insertion pass from creating large blocks.
19 //
20 //===----------------------------------------------------------------------===//
21 
22 #include "ARM.h"
23 #include "ARMSubtarget.h"
25 #include "Thumb2InstrInfo.h"
26 #include "llvm/ADT/SmallVector.h"
31 #include "llvm/Support/Debug.h"
32 #include <cassert>
33 
34 using namespace llvm;
35 
36 #define DEBUG_TYPE "arm-mve-vpt-opts"
37 
38 namespace {
39 class MVEVPTOptimisations : public MachineFunctionPass {
40 public:
41  static char ID;
42  const Thumb2InstrInfo *TII;
44 
45  MVEVPTOptimisations() : MachineFunctionPass(ID) {}
46 
47  bool runOnMachineFunction(MachineFunction &Fn) override;
48 
49  StringRef getPassName() const override {
50  return "ARM MVE VPT Optimisation Pass";
51  }
52 
53 private:
54  MachineInstr &ReplaceRegisterUseWithVPNOT(MachineBasicBlock &MBB,
55  MachineInstr &Instr,
58  bool ReduceOldVCCRValueUses(MachineBasicBlock &MBB);
59  bool ReplaceVCMPsByVPNOTs(MachineBasicBlock &MBB);
60 };
61 
63 
64 } // end anonymous namespace
65 
66 INITIALIZE_PASS(MVEVPTOptimisations, DEBUG_TYPE,
67  "ARM MVE VPT Optimisations pass", false, false)
68 
69 // Returns true if Opcode is any VCMP Opcode.
70 static bool IsVCMP(unsigned Opcode) { return VCMPOpcodeToVPT(Opcode) != 0; }
71 
72 // Returns true if a VCMP with this Opcode can have its operands swapped.
73 // There is 2 kind of VCMP that can't have their operands swapped: Float VCMPs,
74 // and VCMPr instructions (since the r is always on the right).
75 static bool CanHaveSwappedOperands(unsigned Opcode) {
76  switch (Opcode) {
77  default:
78  return true;
79  case ARM::MVE_VCMPf32:
80  case ARM::MVE_VCMPf16:
81  case ARM::MVE_VCMPf32r:
82  case ARM::MVE_VCMPf16r:
83  case ARM::MVE_VCMPi8r:
84  case ARM::MVE_VCMPi16r:
85  case ARM::MVE_VCMPi32r:
86  case ARM::MVE_VCMPu8r:
87  case ARM::MVE_VCMPu16r:
88  case ARM::MVE_VCMPu32r:
89  case ARM::MVE_VCMPs8r:
90  case ARM::MVE_VCMPs16r:
91  case ARM::MVE_VCMPs32r:
92  return false;
93  }
94 }
95 
96 // Returns the CondCode of a VCMP Instruction.
98  assert(IsVCMP(Instr.getOpcode()) && "Inst must be a VCMP");
99  return ARMCC::CondCodes(Instr.getOperand(3).getImm());
100 }
101 
102 // Returns true if Cond is equivalent to a VPNOT instruction on the result of
103 // Prev. Cond and Prev must be VCMPs.
105  assert(IsVCMP(Cond.getOpcode()) && IsVCMP(Prev.getOpcode()));
106 
107  // Opcodes must match.
108  if (Cond.getOpcode() != Prev.getOpcode())
109  return false;
110 
111  MachineOperand &CondOP1 = Cond.getOperand(1), &CondOP2 = Cond.getOperand(2);
112  MachineOperand &PrevOP1 = Prev.getOperand(1), &PrevOP2 = Prev.getOperand(2);
113 
114  // If the VCMP has the opposite condition with the same operands, we can
115  // replace it with a VPNOT
116  ARMCC::CondCodes ExpectedCode = GetCondCode(Cond);
117  ExpectedCode = ARMCC::getOppositeCondition(ExpectedCode);
118  if (ExpectedCode == GetCondCode(Prev))
119  if (CondOP1.isIdenticalTo(PrevOP1) && CondOP2.isIdenticalTo(PrevOP2))
120  return true;
121  // Check again with operands swapped if possible
122  if (!CanHaveSwappedOperands(Cond.getOpcode()))
123  return false;
124  ExpectedCode = ARMCC::getSwappedCondition(ExpectedCode);
125  return ExpectedCode == GetCondCode(Prev) && CondOP1.isIdenticalTo(PrevOP2) &&
126  CondOP2.isIdenticalTo(PrevOP1);
127 }
128 
129 // Returns true if Instr writes to VCCR.
130 static bool IsWritingToVCCR(MachineInstr &Instr) {
131  if (Instr.getNumOperands() == 0)
132  return false;
133  MachineOperand &Dst = Instr.getOperand(0);
134  if (!Dst.isReg())
135  return false;
136  Register DstReg = Dst.getReg();
137  if (!DstReg.isVirtual())
138  return false;
139  MachineRegisterInfo &RegInfo = Instr.getMF()->getRegInfo();
140  const TargetRegisterClass *RegClass = RegInfo.getRegClassOrNull(DstReg);
141  return RegClass && (RegClass->getID() == ARM::VCCRRegClassID);
142 }
143 
144 // Transforms
145 // <Instr that uses %A ('User' Operand)>
146 // Into
147 // %K = VPNOT %Target
148 // <Instr that uses %K ('User' Operand)>
149 // And returns the newly inserted VPNOT.
150 // This optimization is done in the hopes of preventing spills/reloads of VPR by
151 // reducing the number of VCCR values with overlapping lifetimes.
152 MachineInstr &MVEVPTOptimisations::ReplaceRegisterUseWithVPNOT(
154  Register Target) {
155  Register NewResult = MRI->createVirtualRegister(MRI->getRegClass(Target));
156 
157  MachineInstrBuilder MIBuilder =
158  BuildMI(MBB, &Instr, Instr.getDebugLoc(), TII->get(ARM::MVE_VPNOT))
159  .addDef(NewResult)
160  .addReg(Target);
161  addUnpredicatedMveVpredNOp(MIBuilder);
162 
163  // Make the user use NewResult instead, and clear its kill flag.
164  User.setReg(NewResult);
165  User.setIsKill(false);
166 
167  LLVM_DEBUG(dbgs() << " Inserting VPNOT (for spill prevention): ";
168  MIBuilder.getInstr()->dump());
169 
170  return *MIBuilder.getInstr();
171 }
172 
173 // Moves a VPNOT before its first user if an instruction that uses Reg is found
174 // in-between the VPNOT and its user.
175 // Returns true if there is at least one user of the VPNOT in the block.
178  Register Reg) {
179  assert(Iter->getOpcode() == ARM::MVE_VPNOT && "Not a VPNOT!");
181  "The VPNOT cannot be predicated");
182 
183  MachineInstr &VPNOT = *Iter;
184  Register VPNOTResult = VPNOT.getOperand(0).getReg();
185  Register VPNOTOperand = VPNOT.getOperand(1).getReg();
186 
187  // Whether the VPNOT will need to be moved, and whether we found a user of the
188  // VPNOT.
189  bool MustMove = false, HasUser = false;
190  MachineOperand *VPNOTOperandKiller = nullptr;
191  for (; Iter != MBB.end(); ++Iter) {
192  if (MachineOperand *MO =
193  Iter->findRegisterUseOperand(VPNOTOperand, /*isKill*/ true)) {
194  // If we find the operand that kills the VPNOTOperand's result, save it.
195  VPNOTOperandKiller = MO;
196  }
197 
198  if (Iter->findRegisterUseOperandIdx(Reg) != -1) {
199  MustMove = true;
200  continue;
201  }
202 
203  if (Iter->findRegisterUseOperandIdx(VPNOTResult) == -1)
204  continue;
205 
206  HasUser = true;
207  if (!MustMove)
208  break;
209 
210  // Move the VPNOT right before Iter
211  LLVM_DEBUG(dbgs() << "Moving: "; VPNOT.dump(); dbgs() << " Before: ";
212  Iter->dump());
213  MBB.splice(Iter, &MBB, VPNOT.getIterator());
214  // If we move the instr, and its operand was killed earlier, remove the kill
215  // flag.
216  if (VPNOTOperandKiller)
217  VPNOTOperandKiller->setIsKill(false);
218 
219  break;
220  }
221  return HasUser;
222 }
223 
224 // This optimisation attempts to reduce the number of overlapping lifetimes of
225 // VCCR values by replacing uses of old VCCR values with VPNOTs. For example,
226 // this replaces
227 // %A:vccr = (something)
228 // %B:vccr = VPNOT %A
229 // %Foo = (some op that uses %B)
230 // %Bar = (some op that uses %A)
231 // With
232 // %A:vccr = (something)
233 // %B:vccr = VPNOT %A
234 // %Foo = (some op that uses %B)
235 // %TMP2:vccr = VPNOT %B
236 // %Bar = (some op that uses %A)
237 bool MVEVPTOptimisations::ReduceOldVCCRValueUses(MachineBasicBlock &MBB) {
238  MachineBasicBlock::iterator Iter = MBB.begin(), End = MBB.end();
239  SmallVector<MachineInstr *, 4> DeadInstructions;
240  bool Modified = false;
241 
242  while (Iter != End) {
243  Register VCCRValue, OppositeVCCRValue;
244  // The first loop looks for 2 unpredicated instructions:
245  // %A:vccr = (instr) ; A is stored in VCCRValue
246  // %B:vccr = VPNOT %A ; B is stored in OppositeVCCRValue
247  for (; Iter != End; ++Iter) {
248  // We're only interested in unpredicated instructions that write to VCCR.
249  if (!IsWritingToVCCR(*Iter) ||
251  continue;
252  Register Dst = Iter->getOperand(0).getReg();
253 
254  // If we already have a VCCRValue, and this is a VPNOT on VCCRValue, we've
255  // found what we were looking for.
256  if (VCCRValue && Iter->getOpcode() == ARM::MVE_VPNOT &&
257  Iter->findRegisterUseOperandIdx(VCCRValue) != -1) {
258  // Move the VPNOT closer to its first user if needed, and ignore if it
259  // has no users.
260  if (!MoveVPNOTBeforeFirstUser(MBB, Iter, VCCRValue))
261  continue;
262 
263  OppositeVCCRValue = Dst;
264  ++Iter;
265  break;
266  }
267 
268  // Else, just set VCCRValue.
269  VCCRValue = Dst;
270  }
271 
272  // If the first inner loop didn't find anything, stop here.
273  if (Iter == End)
274  break;
275 
276  assert(VCCRValue && OppositeVCCRValue &&
277  "VCCRValue and OppositeVCCRValue shouldn't be empty if the loop "
278  "stopped before the end of the block!");
279  assert(VCCRValue != OppositeVCCRValue &&
280  "VCCRValue should not be equal to OppositeVCCRValue!");
281 
282  // LastVPNOTResult always contains the same value as OppositeVCCRValue.
283  Register LastVPNOTResult = OppositeVCCRValue;
284 
285  // This second loop tries to optimize the remaining instructions.
286  for (; Iter != End; ++Iter) {
287  bool IsInteresting = false;
288 
289  if (MachineOperand *MO = Iter->findRegisterUseOperand(VCCRValue)) {
290  IsInteresting = true;
291 
292  // - If the instruction is a VPNOT, it can be removed, and we can just
293  // replace its uses with LastVPNOTResult.
294  // - Else, insert a new VPNOT on LastVPNOTResult to recompute VCCRValue.
295  if (Iter->getOpcode() == ARM::MVE_VPNOT) {
296  Register Result = Iter->getOperand(0).getReg();
297 
298  MRI->replaceRegWith(Result, LastVPNOTResult);
299  DeadInstructions.push_back(&*Iter);
300  Modified = true;
301 
302  LLVM_DEBUG(dbgs()
303  << "Replacing all uses of '" << printReg(Result)
304  << "' with '" << printReg(LastVPNOTResult) << "'\n");
305  } else {
306  MachineInstr &VPNOT =
307  ReplaceRegisterUseWithVPNOT(MBB, *Iter, *MO, LastVPNOTResult);
308  Modified = true;
309 
310  LastVPNOTResult = VPNOT.getOperand(0).getReg();
311  std::swap(VCCRValue, OppositeVCCRValue);
312 
313  LLVM_DEBUG(dbgs() << "Replacing use of '" << printReg(VCCRValue)
314  << "' with '" << printReg(LastVPNOTResult)
315  << "' in instr: " << *Iter);
316  }
317  } else {
318  // If the instr uses OppositeVCCRValue, make it use LastVPNOTResult
319  // instead as they contain the same value.
320  if (MachineOperand *MO =
321  Iter->findRegisterUseOperand(OppositeVCCRValue)) {
322  IsInteresting = true;
323 
324  // This is pointless if LastVPNOTResult == OppositeVCCRValue.
325  if (LastVPNOTResult != OppositeVCCRValue) {
326  LLVM_DEBUG(dbgs() << "Replacing usage of '"
327  << printReg(OppositeVCCRValue) << "' with '"
328  << printReg(LastVPNOTResult) << " for instr: ";
329  Iter->dump());
330  MO->setReg(LastVPNOTResult);
331  Modified = true;
332  }
333 
334  MO->setIsKill(false);
335  }
336 
337  // If this is an unpredicated VPNOT on
338  // LastVPNOTResult/OppositeVCCRValue, we can act like we inserted it.
339  if (Iter->getOpcode() == ARM::MVE_VPNOT &&
341  Register VPNOTOperand = Iter->getOperand(1).getReg();
342  if (VPNOTOperand == LastVPNOTResult ||
343  VPNOTOperand == OppositeVCCRValue) {
344  IsInteresting = true;
345 
346  std::swap(VCCRValue, OppositeVCCRValue);
347  LastVPNOTResult = Iter->getOperand(0).getReg();
348  }
349  }
350  }
351 
352  // If this instruction was not interesting, and it writes to VCCR, stop.
353  if (!IsInteresting && IsWritingToVCCR(*Iter))
354  break;
355  }
356  }
357 
358  for (MachineInstr *DeadInstruction : DeadInstructions)
359  DeadInstruction->removeFromParent();
360 
361  return Modified;
362 }
363 
364 // This optimisation replaces VCMPs with VPNOTs when they are equivalent.
365 bool MVEVPTOptimisations::ReplaceVCMPsByVPNOTs(MachineBasicBlock &MBB) {
366  SmallVector<MachineInstr *, 4> DeadInstructions;
367 
368  // The last VCMP that we have seen and that couldn't be replaced.
369  // This is reset when an instruction that writes to VCCR/VPR is found, or when
370  // a VCMP is replaced with a VPNOT.
371  // We'll only replace VCMPs with VPNOTs when this is not null, and when the
372  // current VCMP is the opposite of PrevVCMP.
373  MachineInstr *PrevVCMP = nullptr;
374  // If we find an instruction that kills the result of PrevVCMP, we save the
375  // operand here to remove the kill flag in case we need to use PrevVCMP's
376  // result.
377  MachineOperand *PrevVCMPResultKiller = nullptr;
378 
379  for (MachineInstr &Instr : MBB.instrs()) {
380  if (PrevVCMP) {
381  if (MachineOperand *MO = Instr.findRegisterUseOperand(
382  PrevVCMP->getOperand(0).getReg(), /*isKill*/ true)) {
383  // If we come accross the instr that kills PrevVCMP's result, record it
384  // so we can remove the kill flag later if we need to.
385  PrevVCMPResultKiller = MO;
386  }
387  }
388 
389  // Ignore predicated instructions.
390  if (getVPTInstrPredicate(Instr) != ARMVCC::None)
391  continue;
392 
393  // Only look at VCMPs
394  if (!IsVCMP(Instr.getOpcode())) {
395  // If the instruction writes to VCCR, forget the previous VCMP.
396  if (IsWritingToVCCR(Instr))
397  PrevVCMP = nullptr;
398  continue;
399  }
400 
401  if (!PrevVCMP || !IsVPNOTEquivalent(Instr, *PrevVCMP)) {
402  PrevVCMP = &Instr;
403  continue;
404  }
405 
406  // The register containing the result of the VCMP that we're going to
407  // replace.
408  Register PrevVCMPResultReg = PrevVCMP->getOperand(0).getReg();
409 
410  // Build a VPNOT to replace the VCMP, reusing its operands.
411  MachineInstrBuilder MIBuilder =
412  BuildMI(MBB, &Instr, Instr.getDebugLoc(), TII->get(ARM::MVE_VPNOT))
413  .add(Instr.getOperand(0))
414  .addReg(PrevVCMPResultReg);
415  addUnpredicatedMveVpredNOp(MIBuilder);
416  LLVM_DEBUG(dbgs() << "Inserting VPNOT (to replace VCMP): ";
417  MIBuilder.getInstr()->dump(); dbgs() << " Removed VCMP: ";
418  Instr.dump());
419 
420  // If we found an instruction that uses, and kills PrevVCMP's result,
421  // remove the kill flag.
422  if (PrevVCMPResultKiller)
423  PrevVCMPResultKiller->setIsKill(false);
424 
425  // Finally, mark the old VCMP for removal and reset
426  // PrevVCMP/PrevVCMPResultKiller.
427  DeadInstructions.push_back(&Instr);
428  PrevVCMP = nullptr;
429  PrevVCMPResultKiller = nullptr;
430  }
431 
432  for (MachineInstr *DeadInstruction : DeadInstructions)
433  DeadInstruction->removeFromParent();
434 
435  return !DeadInstructions.empty();
436 }
437 
438 bool MVEVPTOptimisations::runOnMachineFunction(MachineFunction &Fn) {
439  const ARMSubtarget &STI =
440  static_cast<const ARMSubtarget &>(Fn.getSubtarget());
441 
442  if (!STI.isThumb2() || !STI.hasMVEIntegerOps())
443  return false;
444 
445  TII = static_cast<const Thumb2InstrInfo *>(STI.getInstrInfo());
446  MRI = &Fn.getRegInfo();
447 
448  LLVM_DEBUG(dbgs() << "********** ARM MVE VPT Optimisations **********\n"
449  << "********** Function: " << Fn.getName() << '\n');
450 
451  bool Modified = false;
452  for (MachineBasicBlock &MBB : Fn) {
453  Modified |= ReplaceVCMPsByVPNOTs(MBB);
454  Modified |= ReduceOldVCCRValueUses(MBB);
455  }
456 
457  LLVM_DEBUG(dbgs() << "**************************************\n");
458  return Modified;
459 }
460 
461 /// createMVEVPTOptimisationsPass
463  return new MVEVPTOptimisations();
464 }
MachineOperand * findRegisterUseOperand(Register Reg, bool isKill=false, const TargetRegisterInfo *TRI=nullptr)
Wrapper for findRegisterUseOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
void push_back(const T &Elt)
Definition: SmallVector.h:246
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:409
unsigned Reg
static bool IsWritingToVCCR(MachineInstr &Instr)
#define DEBUG_TYPE
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.
MachineBasicBlock & MBB
const ARMBaseInstrInfo * getInstrInfo() const override
Definition: ARMSubtarget.h:539
static bool CanHaveSwappedOperands(unsigned Opcode)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:459
INITIALIZE_PASS(MVEVPTOptimisations, DEBUG_TYPE, "ARM MVE VPT Optimisations pass", false, false) static bool IsVCMP(unsigned Opcode)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:456
static unsigned VCMPOpcodeToVPT(unsigned Opcode)
unsigned getID() const
Return the register class ID number.
const TargetRegisterClass * getRegClassOrNull(Register Reg) const
Return the register class of Reg, or null if Reg has not been assigned a register class yet...
static bool MoveVPNOTBeforeFirstUser(MachineBasicBlock &MBB, MachineBasicBlock::iterator Iter, Register Reg)
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:92
void setReg(Register Reg)
Change the register this operand corresponds to.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
void addUnpredicatedMveVpredNOp(MachineInstrBuilder &MIB)
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
SmallVector< MachineOperand, 4 > Cond
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
FunctionPass * createMVEVPTOptimisationsPass()
createMVEVPTOptimisationsPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
self_iterator getIterator()
Definition: ilist_node.h:81
void setIsKill(bool Val=true)
MachineOperand class - Representation of each machine instruction operand.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly. ...
int64_t getImm() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:962
Target - Wrapper for Target specific information.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
bool isThumb2() const
Definition: ARMSubtarget.h:787
Representation of each machine instruction.
Definition: MachineInstr.h:62
static CondCodes getOppositeCondition(CondCodes CC)
Definition: ARMBaseInfo.h:48
static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC)
getSwappedCondition - assume the flags are set by MI(a,b), return the condition code if we modify the...
Definition: ARMBaseInfo.h:71
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB &#39;Other&#39; at the position From, and insert it into this MBB right before &#39;...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
ARMVCC::VPTCodes getVPTInstrPredicate(const MachineInstr &MI, Register &PredReg)
static bool IsVPNOTEquivalent(MachineInstr &Cond, MachineInstr &Prev)
static ARMCC::CondCodes GetCondCode(MachineInstr &Instr)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool hasMVEIntegerOps() const
Definition: ARMSubtarget.h:600
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
Register getReg() const
getReg - Returns the register number.
#define LLVM_DEBUG(X)
Definition: Debug.h:122
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:466
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19