LLVM  10.0.0svn
ARCOptAddrMode.cpp
Go to the documentation of this file.
1 //===- ARCOptAddrMode.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
10 /// This pass folds LD/ST + ADD pairs into Pre/Post-increment form of
11 /// load/store instructions.
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARC.h"
15 #define GET_INSTRMAP_INFO
16 #include "ARCInstrInfo.h"
17 #include "ARCTargetMachine.h"
24 #include "llvm/IR/Function.h"
25 #include "llvm/Support/Debug.h"
27 
28 using namespace llvm;
29 
30 #define OPTADDRMODE_DESC "ARC load/store address mode"
31 #define OPTADDRMODE_NAME "arc-addr-mode"
32 #define DEBUG_TYPE "arc-addr-mode"
33 
34 namespace llvm {
37 } // end namespace llvm
38 
39 namespace {
40 class ARCOptAddrMode : public MachineFunctionPass {
41 public:
42  static char ID;
43 
44  ARCOptAddrMode() : MachineFunctionPass(ID) {}
45 
46  StringRef getPassName() const override { return OPTADDRMODE_DESC; }
47 
48  void getAnalysisUsage(AnalysisUsage &AU) const override {
49  AU.setPreservesCFG();
53  }
54 
55  bool runOnMachineFunction(MachineFunction &MF) override;
56 
57 private:
58  const ARCSubtarget *AST = nullptr;
59  const ARCInstrInfo *AII = nullptr;
60  MachineRegisterInfo *MRI = nullptr;
61  MachineDominatorTree *MDT = nullptr;
62 
63  // Tries to combine \p Ldst with increment of its base register to form
64  // single post-increment instruction.
65  MachineInstr *tryToCombine(MachineInstr &Ldst);
66 
67  // Returns true if result of \p Add is not used before \p Ldst
68  bool noUseOfAddBeforeLoadOrStore(const MachineInstr *Add,
69  const MachineInstr *Ldst);
70 
71  // Returns true if load/store instruction \p Ldst can be hoisted up to
72  // instruction \p To
73  bool canHoistLoadStoreTo(MachineInstr *Ldst, MachineInstr *To);
74 
75  // Returns true if load/store instruction \p Ldst can be sunk down
76  // to instruction \p To
77  bool canSinkLoadStoreTo(MachineInstr *Ldst, MachineInstr *To);
78 
79  // Check if instructions \p Ldst and \p Add can be moved to become adjacent
80  // If they can return instruction which need not to move.
81  // If \p Uses is not null, fill it with instructions after \p Ldst which use
82  // \p Ldst's base register
83  MachineInstr *canJoinInstructions(MachineInstr *Ldst, MachineInstr *Add,
85 
86  // Returns true if all instruction in \p Uses array can be adjusted
87  // to accomodate increment of register \p BaseReg by \p Incr
88  bool canFixPastUses(const ArrayRef<MachineInstr *> &Uses,
89  MachineOperand &Incr, unsigned BaseReg);
90 
91  // Update all instructions in \p Uses to accomodate increment
92  // of \p BaseReg by \p Offset
93  void fixPastUses(ArrayRef<MachineInstr *> Uses, unsigned BaseReg,
94  int64_t Offset);
95 
96  // Change instruction \p Ldst to postincrement form.
97  // \p NewBase is register to hold update base value
98  // \p NewOffset is instruction's new offset
99  void changeToAddrMode(MachineInstr &Ldst, unsigned NewOpcode,
100  unsigned NewBase, MachineOperand &NewOffset);
101 
102  bool processBasicBlock(MachineBasicBlock &MBB);
103 };
104 
105 } // end anonymous namespace
106 
107 char ARCOptAddrMode::ID = 0;
109  false)
112  false)
113 
114 // Return true if \p Off can be used as immediate offset
115 // operand of load/store instruction (S9 literal)
116 static bool isValidLoadStoreOffset(int64_t Off) { return isInt<9>(Off); }
117 
118 // Return true if \p Off can be used as immediate operand of
119 // ADD/SUB instruction (U6 literal)
120 static bool isValidIncrementOffset(int64_t Off) { return isUInt<6>(Off); }
121 
122 static bool isAddConstantOp(const MachineInstr &MI, int64_t &Amount) {
123  int64_t Sign = 1;
124  switch (MI.getOpcode()) {
125  case ARC::SUB_rru6:
126  Sign = -1;
128  case ARC::ADD_rru6:
129  assert(MI.getOperand(2).isImm() && "Expected immediate operand");
130  Amount = Sign * MI.getOperand(2).getImm();
131  return true;
132  default:
133  return false;
134  }
135 }
136 
137 // Return true if \p MI dominates of uses of virtual register \p VReg
138 static bool dominatesAllUsesOf(const MachineInstr *MI, unsigned VReg,
141 
142  assert(Register::isVirtualRegister(VReg) && "Expected virtual register!");
143 
144  for (auto it = MRI->use_nodbg_begin(VReg), end = MRI->use_nodbg_end();
145  it != end; ++it) {
146  MachineInstr *User = it->getParent();
147  if (User->isPHI()) {
148  unsigned BBOperandIdx = User->getOperandNo(&*it) + 1;
149  MachineBasicBlock *MBB = User->getOperand(BBOperandIdx).getMBB();
150  if (MBB->empty()) {
151  const MachineBasicBlock *InstBB = MI->getParent();
152  assert(InstBB != MBB && "Instruction found in empty MBB");
153  if (!MDT->dominates(InstBB, MBB))
154  return false;
155  continue;
156  }
157  User = &*MBB->rbegin();
158  }
159 
160  if (!MDT->dominates(MI, User))
161  return false;
162  }
163  return true;
164 }
165 
166 // Return true if \p MI is load/store instruction with immediate offset
167 // which can be adjusted by \p Disp
169  const MachineInstr &MI,
170  int64_t Disp) {
171  unsigned BasePos, OffPos;
172  if (!TII->getBaseAndOffsetPosition(MI, BasePos, OffPos))
173  return false;
174  const MachineOperand &MO = MI.getOperand(OffPos);
175  if (!MO.isImm())
176  return false;
177  int64_t Offset = MO.getImm() + Disp;
178  return isValidLoadStoreOffset(Offset);
179 }
180 
181 bool ARCOptAddrMode::noUseOfAddBeforeLoadOrStore(const MachineInstr *Add,
182  const MachineInstr *Ldst) {
183  Register R = Add->getOperand(0).getReg();
184  return dominatesAllUsesOf(Ldst, R, MDT, MRI);
185 }
186 
187 MachineInstr *ARCOptAddrMode::tryToCombine(MachineInstr &Ldst) {
188  assert((Ldst.mayLoad() || Ldst.mayStore()) && "LD/ST instruction expected");
189 
190  unsigned BasePos, OffsetPos;
191 
192  LLVM_DEBUG(dbgs() << "[ABAW] tryToCombine " << Ldst);
193  if (!AII->getBaseAndOffsetPosition(Ldst, BasePos, OffsetPos)) {
194  LLVM_DEBUG(dbgs() << "[ABAW] Not a recognized load/store\n");
195  return nullptr;
196  }
197 
198  MachineOperand &Base = Ldst.getOperand(BasePos);
199  MachineOperand &Offset = Ldst.getOperand(OffsetPos);
200 
201  assert(Base.isReg() && "Base operand must be register");
202  if (!Offset.isImm()) {
203  LLVM_DEBUG(dbgs() << "[ABAW] Offset is not immediate\n");
204  return nullptr;
205  }
206 
207  Register B = Base.getReg();
209  LLVM_DEBUG(dbgs() << "[ABAW] Base is not VReg\n");
210  return nullptr;
211  }
212 
213  // TODO: try to generate address preincrement
214  if (Offset.getImm() != 0) {
215  LLVM_DEBUG(dbgs() << "[ABAW] Non-zero offset\n");
216  return nullptr;
217  }
218 
219  for (auto &Add : MRI->use_nodbg_instructions(B)) {
220  int64_t Incr;
221  if (!isAddConstantOp(Add, Incr))
222  continue;
223  if (!isValidLoadStoreOffset(Incr))
224  continue;
225 
227  MachineInstr *MoveTo = canJoinInstructions(&Ldst, &Add, &Uses);
228 
229  if (!MoveTo)
230  continue;
231 
232  if (!canFixPastUses(Uses, Add.getOperand(2), B))
233  continue;
234 
235  LLVM_DEBUG(MachineInstr *First = &Ldst; MachineInstr *Last = &Add;
236  if (MDT->dominates(Last, First)) std::swap(First, Last);
237  dbgs() << "[ABAW] Instructions " << *First << " and " << *Last
238  << " combined\n";
239 
240  );
241 
242  MachineInstr *Result = Ldst.getNextNode();
243  if (MoveTo == &Add) {
244  Ldst.removeFromParent();
245  Add.getParent()->insertAfter(Add.getIterator(), &Ldst);
246  }
247  if (Result == &Add)
248  Result = Result->getNextNode();
249 
250  fixPastUses(Uses, B, Incr);
251 
252  int NewOpcode = ARC::getPostIncOpcode(Ldst.getOpcode());
253  assert(NewOpcode > 0 && "No postincrement form found");
254  unsigned NewBaseReg = Add.getOperand(0).getReg();
255  changeToAddrMode(Ldst, NewOpcode, NewBaseReg, Add.getOperand(2));
256  Add.eraseFromParent();
257 
258  return Result;
259  }
260  return nullptr;
261 }
262 
263 MachineInstr *
264 ARCOptAddrMode::canJoinInstructions(MachineInstr *Ldst, MachineInstr *Add,
266  assert(Ldst && Add && "NULL instruction passed");
267 
268  MachineInstr *First = Add;
269  MachineInstr *Last = Ldst;
270  if (MDT->dominates(Ldst, Add))
271  std::swap(First, Last);
272  else if (!MDT->dominates(Add, Ldst))
273  return nullptr;
274 
275  LLVM_DEBUG(dbgs() << "canJoinInstructions: " << *First << *Last);
276 
277  unsigned BasePos, OffPos;
278 
279  if (!AII->getBaseAndOffsetPosition(*Ldst, BasePos, OffPos)) {
280  LLVM_DEBUG(
281  dbgs()
282  << "[canJoinInstructions] Cannot determine base/offset position\n");
283  return nullptr;
284  }
285 
286  Register BaseReg = Ldst->getOperand(BasePos).getReg();
287 
288  // prohibit this:
289  // v1 = add v0, c
290  // st v1, [v0, 0]
291  // and this
292  // st v0, [v0, 0]
293  // v1 = add v0, c
294  if (Ldst->mayStore() && Ldst->getOperand(0).isReg()) {
295  Register StReg = Ldst->getOperand(0).getReg();
296  if (Add->getOperand(0).getReg() == StReg || BaseReg == StReg) {
297  LLVM_DEBUG(dbgs() << "[canJoinInstructions] Store uses result of Add\n");
298  return nullptr;
299  }
300  }
301 
302  SmallVector<MachineInstr *, 4> UsesAfterLdst;
303  SmallVector<MachineInstr *, 4> UsesAfterAdd;
304  for (MachineInstr &MI : MRI->use_nodbg_instructions(BaseReg)) {
305  if (&MI == Ldst || &MI == Add)
306  continue;
307  if (&MI != Add && MDT->dominates(Ldst, &MI))
308  UsesAfterLdst.push_back(&MI);
309  else if (!MDT->dominates(&MI, Ldst))
310  return nullptr;
311  if (MDT->dominates(Add, &MI))
312  UsesAfterAdd.push_back(&MI);
313  }
314 
315  MachineInstr *Result = nullptr;
316 
317  if (First == Add) {
318  // n = add b, i
319  // ...
320  // x = ld [b, o] or x = ld [n, o]
321 
322  if (noUseOfAddBeforeLoadOrStore(First, Last)) {
323  Result = Last;
324  LLVM_DEBUG(dbgs() << "[canJoinInstructions] Can sink Add down to Ldst\n");
325  } else if (canHoistLoadStoreTo(Ldst, Add)) {
326  Result = First;
327  LLVM_DEBUG(dbgs() << "[canJoinInstructions] Can hoist Ldst to Add\n");
328  }
329  } else {
330  // x = ld [b, o]
331  // ...
332  // n = add b, i
333  Result = First;
334  LLVM_DEBUG(dbgs() << "[canJoinInstructions] Can hoist Add to Ldst\n");
335  }
336  if (Result && Uses)
337  *Uses = (Result == Ldst) ? UsesAfterLdst : UsesAfterAdd;
338  return Result;
339 }
340 
341 bool ARCOptAddrMode::canFixPastUses(const ArrayRef<MachineInstr *> &Uses,
342  MachineOperand &Incr, unsigned BaseReg) {
343 
344  assert(Incr.isImm() && "Expected immediate increment");
345  int64_t NewOffset = Incr.getImm();
346  for (MachineInstr *MI : Uses) {
347  int64_t Dummy;
348  if (isAddConstantOp(*MI, Dummy)) {
349  if (isValidIncrementOffset(Dummy + NewOffset))
350  continue;
351  return false;
352  }
353  if (isLoadStoreThatCanHandleDisplacement(AII, *MI, -NewOffset))
354  continue;
355  LLVM_DEBUG(dbgs() << "Instruction cannot handle displacement " << -NewOffset
356  << ": " << *MI);
357  return false;
358  }
359  return true;
360 }
361 
362 void ARCOptAddrMode::fixPastUses(ArrayRef<MachineInstr *> Uses,
363  unsigned NewBase, int64_t NewOffset) {
364 
365  for (MachineInstr *MI : Uses) {
366  int64_t Amount;
367  unsigned BasePos, OffPos;
368  if (isAddConstantOp(*MI, Amount)) {
369  NewOffset += Amount;
370  assert(isValidIncrementOffset(NewOffset) &&
371  "New offset won't fit into ADD instr");
372  BasePos = 1;
373  OffPos = 2;
374  } else if (AII->getBaseAndOffsetPosition(*MI, BasePos, OffPos)) {
375  MachineOperand &MO = MI->getOperand(OffPos);
376  assert(MO.isImm() && "expected immediate operand");
377  NewOffset += MO.getImm();
378  assert(isValidLoadStoreOffset(NewOffset) &&
379  "New offset won't fit into LD/ST");
380  } else
381  llvm_unreachable("unexpected instruction");
382 
383  MI->getOperand(BasePos).setReg(NewBase);
384  MI->getOperand(OffPos).setImm(NewOffset);
385  }
386 }
387 
388 bool ARCOptAddrMode::canHoistLoadStoreTo(MachineInstr *Ldst, MachineInstr *To) {
389  if (Ldst->getParent() != To->getParent())
390  return false;
392  End(Ldst->getParent()->end());
393 
394  bool IsStore = Ldst->mayStore();
395  for (; MI != ME && MI != End; ++MI) {
396  if (MI->isDebugValue())
397  continue;
398  if (MI->mayStore() || MI->isCall() || MI->isInlineAsm() ||
399  MI->hasUnmodeledSideEffects())
400  return false;
401  if (IsStore && MI->mayLoad())
402  return false;
403  }
404 
405  for (auto &O : Ldst->explicit_operands()) {
406  if (!O.isReg() || !O.isUse())
407  continue;
408  MachineInstr *OpDef = MRI->getVRegDef(O.getReg());
409  if (!OpDef || !MDT->dominates(OpDef, To))
410  return false;
411  }
412  return true;
413 }
414 
415 bool ARCOptAddrMode::canSinkLoadStoreTo(MachineInstr *Ldst, MachineInstr *To) {
416  // Can only sink load/store within same BB
417  if (Ldst->getParent() != To->getParent())
418  return false;
420  End(Ldst->getParent()->end());
421 
422  bool IsStore = Ldst->mayStore();
423  bool IsLoad = Ldst->mayLoad();
424 
425  Register ValReg = IsLoad ? Ldst->getOperand(0).getReg() : Register();
426  for (; MI != ME && MI != End; ++MI) {
427  if (MI->isDebugValue())
428  continue;
429  if (MI->mayStore() || MI->isCall() || MI->isInlineAsm() ||
430  MI->hasUnmodeledSideEffects())
431  return false;
432  if (IsStore && MI->mayLoad())
433  return false;
434  if (ValReg && MI->readsVirtualRegister(ValReg))
435  return false;
436  }
437  return true;
438 }
439 
440 void ARCOptAddrMode::changeToAddrMode(MachineInstr &Ldst, unsigned NewOpcode,
441  unsigned NewBase,
442  MachineOperand &NewOffset) {
443  bool IsStore = Ldst.mayStore();
444  unsigned BasePos, OffPos;
445  MachineOperand Src = MachineOperand::CreateImm(0xDEADBEEF);
446  AII->getBaseAndOffsetPosition(Ldst, BasePos, OffPos);
447 
448  Register BaseReg = Ldst.getOperand(BasePos).getReg();
449 
450  Ldst.RemoveOperand(OffPos);
451  Ldst.RemoveOperand(BasePos);
452 
453  if (IsStore) {
454  Src = Ldst.getOperand(BasePos - 1);
455  Ldst.RemoveOperand(BasePos - 1);
456  }
457 
458  Ldst.setDesc(AST->getInstrInfo()->get(NewOpcode));
459  Ldst.addOperand(MachineOperand::CreateReg(NewBase, true));
460  if (IsStore)
461  Ldst.addOperand(Src);
462  Ldst.addOperand(MachineOperand::CreateReg(BaseReg, false));
463  Ldst.addOperand(NewOffset);
464  LLVM_DEBUG(dbgs() << "[ABAW] New Ldst: " << Ldst);
465 }
466 
467 bool ARCOptAddrMode::processBasicBlock(MachineBasicBlock &MBB) {
468  bool Changed = false;
469  for (auto MI = MBB.begin(), ME = MBB.end(); MI != ME; ++MI) {
470  if (MI->isDebugValue())
471  continue;
472  if (!MI->mayLoad() && !MI->mayStore())
473  continue;
474  if (ARC::getPostIncOpcode(MI->getOpcode()) < 0)
475  continue;
476  MachineInstr *Res = tryToCombine(*MI);
477  if (Res) {
478  Changed = true;
479  // Res points to the next instruction. Rewind to process it
480  MI = std::prev(Res->getIterator());
481  }
482  }
483  return Changed;
484 }
485 
486 bool ARCOptAddrMode::runOnMachineFunction(MachineFunction &MF) {
487  if (skipFunction(MF.getFunction()))
488  return false;
489 
490  AST = &MF.getSubtarget<ARCSubtarget>();
491  AII = AST->getInstrInfo();
492  MRI = &MF.getRegInfo();
493  MDT = &getAnalysis<MachineDominatorTree>();
494 
495  bool Changed = false;
496  for (auto &MBB : MF)
497  Changed |= processBasicBlock(MBB);
498  return Changed;
499 }
500 
501 //===----------------------------------------------------------------------===//
502 // Public Constructor Functions
503 //===----------------------------------------------------------------------===//
504 
505 FunctionPass *llvm::createARCOptAddrMode() { return new ARCOptAddrMode(); }
#define OPTADDRMODE_NAME
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:233
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
MachineBasicBlock * getMBB() const
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition: ilist_node.h:288
This class represents lattice values for constants.
Definition: AllocatorList.h:23
iterator_range< mop_iterator > explicit_operands()
Definition: MachineInstr.h:483
void push_back(const T &Elt)
Definition: SmallVector.h:211
unsigned getOperandNo(const_mop_iterator I) const
Returns the number of the operand iterator I points to.
Definition: MachineInstr.h:527
static bool isStackSlot(unsigned Reg)
isStackSlot - Sometimes it is useful the be able to store a non-negative frame index in a variable th...
Definition: Register.h:45
iterator insertAfter(iterator I, MachineInstr *MI)
Insert MI into the instruction list after I.
#define OPTADDRMODE_DESC
static bool isLoadStoreThatCanHandleDisplacement(const TargetInstrInfo *TII, const MachineInstr &MI, int64_t Disp)
use_nodbg_iterator use_nodbg_begin(unsigned RegNo) const
bool isPHI() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static false bool isValidLoadStoreOffset(int64_t Off)
static use_nodbg_iterator use_nodbg_end()
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
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:411
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
virtual bool getBaseAndOffsetPosition(const MachineInstr &MI, unsigned &BasePos, unsigned &OffsetPos) const
Return true if the instruction contains a base register and offset.
reverse_iterator rbegin()
const ARCInstrInfo * getInstrInfo() const override
Definition: ARCSubtarget.h:48
TargetInstrInfo - Interface to description of machine instruction set.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
Definition: MachineInstr.h:844
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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.
FunctionPass * createARCOptAddrMode()
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
self_iterator getIterator()
Definition: ilist_node.h:81
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
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
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
Promote Memory to Register
Definition: Mem2Reg.cpp:109
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:301
int64_t getImm() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
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:940
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:256
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:64
INITIALIZE_PASS_BEGIN(ARCOptAddrMode, OPTADDRMODE_NAME, OPTADDRMODE_DESC, false, false) INITIALIZE_PASS_END(ARCOptAddrMode
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
static bool isAddConstantOp(const MachineInstr &MI, int64_t &Amount)
static MachineOperand CreateImm(int64_t Val)
static bool isValidIncrementOffset(int64_t Off)
MachineInstr * removeFromParent()
Unlink &#39;this&#39; from the containing basic block, and return it without deleting it. ...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
Definition: MachineInstr.h:831
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:69
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:273
void initializeARCOptAddrModePass(PassRegistry &)
static bool dominatesAllUsesOf(const MachineInstr *MI, unsigned VReg, MachineDominatorTree *MDT, MachineRegisterInfo *MRI)
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
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:416
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19