LLVM 24.0.0git
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"
27#include "llvm/Support/Debug.h"
29
30using namespace llvm;
31
32#define OPTADDRMODE_DESC "ARC load/store address mode"
33#define OPTADDRMODE_NAME "arc-addr-mode"
34#define DEBUG_TYPE "arc-addr-mode"
35
36namespace llvm {
37
38static cl::opt<unsigned> ArcKillAddrMode("arc-kill-addr-mode", cl::init(0),
40
41#define DUMP_BEFORE() ((ArcKillAddrMode & 0x0001) != 0)
42#define DUMP_AFTER() ((ArcKillAddrMode & 0x0002) != 0)
43#define VIEW_BEFORE() ((ArcKillAddrMode & 0x0004) != 0)
44#define VIEW_AFTER() ((ArcKillAddrMode & 0x0008) != 0)
45#define KILL_PASS() ((ArcKillAddrMode & 0x0010) != 0)
46
48} // end namespace llvm
49
50namespace {
51class ARCOptAddrMode : public MachineFunctionPass {
52public:
53 static char ID;
54
55 ARCOptAddrMode() : MachineFunctionPass(ID) {}
56
57 StringRef getPassName() const override { return OPTADDRMODE_DESC; }
58
59 void getAnalysisUsage(AnalysisUsage &AU) const override {
60 AU.setPreservesCFG();
62 AU.addRequired<MachineDominatorTreeWrapperPass>();
63 }
64
65 bool runOnMachineFunction(MachineFunction &MF) override;
66
67private:
68 const ARCSubtarget *AST = nullptr;
69 const ARCInstrInfo *AII = nullptr;
70 MachineRegisterInfo *MRI = nullptr;
71 MachineDominatorTree *MDT = nullptr;
72
73 // Tries to combine \p Ldst with increment of its base register to form
74 // single post-increment instruction.
75 MachineInstr *tryToCombine(MachineInstr &Ldst);
76
77 // Returns true if result of \p Add is not used before \p Ldst
78 bool noUseOfAddBeforeLoadOrStore(const MachineInstr *Add,
79 const MachineInstr *Ldst);
80
81 // Returns true if load/store instruction \p Ldst can be hoisted up to
82 // instruction \p To
83 bool canHoistLoadStoreTo(MachineInstr *Ldst, MachineInstr *To);
84
85 // // Returns true if load/store instruction \p Ldst can be sunk down
86 // // to instruction \p To
87 // bool canSinkLoadStoreTo(MachineInstr *Ldst, MachineInstr *To);
88
89 // Check if instructions \p Ldst and \p Add can be moved to become adjacent
90 // If they can return instruction which need not to move.
91 // If \p Uses is not null, fill it with instructions after \p Ldst which use
92 // \p Ldst's base register
93 MachineInstr *canJoinInstructions(MachineInstr *Ldst, MachineInstr *Add,
94 SmallVectorImpl<MachineInstr *> *Uses);
95
96 // Returns true if all instruction in \p Uses array can be adjusted
97 // to accomodate increment of register \p BaseReg by \p Incr
98 bool canFixPastUses(const ArrayRef<MachineInstr *> &Uses,
99 MachineOperand &Incr, unsigned BaseReg);
100
101 // Update all instructions in \p Uses to accomodate increment
102 // of \p BaseReg by \p Offset
103 void fixPastUses(ArrayRef<MachineInstr *> Uses, unsigned BaseReg,
104 int64_t Offset);
105
106 // Change instruction \p Ldst to postincrement form.
107 // \p NewBase is register to hold update base value
108 // \p NewOffset is instruction's new offset
109 void changeToAddrMode(MachineInstr &Ldst, unsigned NewOpcode,
110 unsigned NewBase, MachineOperand &NewOffset);
111
112 bool processBasicBlock(MachineBasicBlock &MBB);
113};
114
115} // end anonymous namespace
116
117char ARCOptAddrMode::ID = 0;
118
119// Return true if \p Off can be used as immediate offset
120// operand of load/store instruction (S9 literal)
121static bool isValidLoadStoreOffset(int64_t Off) { return isInt<9>(Off); }
122
123// Return true if \p Off can be used as immediate operand of
124// ADD/SUB instruction (U6 literal)
125static bool isValidIncrementOffset(int64_t Off) { return isUInt<6>(Off); }
126
127static bool isAddConstantOp(const MachineInstr &MI, int64_t &Amount) {
128 int64_t Sign = 1;
129 switch (MI.getOpcode()) {
130 case ARC::SUB_rru6:
131 Sign = -1;
132 [[fallthrough]];
133 case ARC::ADD_rru6:
134 assert(MI.getOperand(2).isImm() && "Expected immediate operand");
135 Amount = Sign * MI.getOperand(2).getImm();
136 return true;
137 default:
138 return false;
139 }
140}
141
142// Return true if \p MI dominates of uses of virtual register \p VReg
143static bool dominatesAllUsesOf(const MachineInstr *MI, unsigned VReg,
145 MachineRegisterInfo *MRI) {
146
147 assert(Register::isVirtualRegister(VReg) && "Expected virtual register!");
148
149 for (const MachineOperand &Use : MRI->use_nodbg_operands(VReg)) {
150 const MachineInstr *User = Use.getParent();
151 if (User->isPHI()) {
152 unsigned BBOperandIdx = Use.getOperandNo() + 1;
153 MachineBasicBlock *MBB = User->getOperand(BBOperandIdx).getMBB();
154 if (MBB->empty()) {
155 const MachineBasicBlock *InstBB = MI->getParent();
156 assert(InstBB != MBB && "Instruction found in empty MBB");
157 if (!MDT->dominates(InstBB, MBB))
158 return false;
159 continue;
160 }
161 User = &*MBB->rbegin();
162 }
163
164 if (!MDT->dominates(MI, User))
165 return false;
166 }
167 return true;
168}
169
170// Return true if \p MI is load/store instruction with immediate offset
171// which can be adjusted by \p Disp
173 const MachineInstr &MI,
174 int64_t Disp) {
175 unsigned BasePos, OffPos;
176 if (!TII->getBaseAndOffsetPosition(MI, BasePos, OffPos))
177 return false;
178 const MachineOperand &MO = MI.getOperand(OffPos);
179 if (!MO.isImm())
180 return false;
181 int64_t Offset = MO.getImm() + Disp;
183}
184
185bool ARCOptAddrMode::noUseOfAddBeforeLoadOrStore(const MachineInstr *Add,
186 const MachineInstr *Ldst) {
187 Register R = Add->getOperand(0).getReg();
188 return dominatesAllUsesOf(Ldst, R, MDT, MRI);
189}
190
191MachineInstr *ARCOptAddrMode::tryToCombine(MachineInstr &Ldst) {
192 assert(Ldst.mayLoadOrStore() && "LD/ST instruction expected");
193
194 unsigned BasePos, OffsetPos;
195
196 LLVM_DEBUG(dbgs() << "[ABAW] tryToCombine " << Ldst);
197 if (!AII->getBaseAndOffsetPosition(Ldst, BasePos, OffsetPos)) {
198 LLVM_DEBUG(dbgs() << "[ABAW] Not a recognized load/store\n");
199 return nullptr;
200 }
201
202 MachineOperand &Base = Ldst.getOperand(BasePos);
203 MachineOperand &Offset = Ldst.getOperand(OffsetPos);
204
205 assert(Base.isReg() && "Base operand must be register");
206 if (!Offset.isImm()) {
207 LLVM_DEBUG(dbgs() << "[ABAW] Offset is not immediate\n");
208 return nullptr;
209 }
210
211 Register B = Base.getReg();
212 if (!Register::isVirtualRegister(B)) {
213 LLVM_DEBUG(dbgs() << "[ABAW] Base is not VReg\n");
214 return nullptr;
215 }
216
217 // TODO: try to generate address preincrement
218 if (Offset.getImm() != 0) {
219 LLVM_DEBUG(dbgs() << "[ABAW] Non-zero offset\n");
220 return nullptr;
221 }
222
223 for (auto &Add : MRI->use_nodbg_instructions(B)) {
224 int64_t Incr;
225 if (!isAddConstantOp(Add, Incr))
226 continue;
227 if (!isValidLoadStoreOffset(Incr))
228 continue;
229
230 SmallVector<MachineInstr *, 8> Uses;
231 MachineInstr *MoveTo = canJoinInstructions(&Ldst, &Add, &Uses);
232
233 if (!MoveTo)
234 continue;
235
236 if (!canFixPastUses(Uses, Add.getOperand(2), B))
237 continue;
238
239 LLVM_DEBUG(MachineInstr *First = &Ldst; MachineInstr *Last = &Add;
240 if (MDT->dominates(Last, First)) std::swap(First, Last);
241 dbgs() << "[ABAW] Instructions " << *First << " and " << *Last
242 << " combined\n";
243
244 );
245
246 MachineInstr *Result = Ldst.getNextNode();
247 if (MoveTo == &Add) {
248 Ldst.removeFromParent();
249 Add.getParent()->insertAfter(Add.getIterator(), &Ldst);
250 }
251 if (Result == &Add)
252 Result = Result->getNextNode();
253
254 fixPastUses(Uses, B, Incr);
255
256 int NewOpcode = ARC::getPostIncOpcode(Ldst.getOpcode());
257 assert(NewOpcode > 0 && "No postincrement form found");
258 unsigned NewBaseReg = Add.getOperand(0).getReg();
259 changeToAddrMode(Ldst, NewOpcode, NewBaseReg, Add.getOperand(2));
260 Add.eraseFromParent();
261
262 return Result;
263 }
264 return nullptr;
265}
266
267MachineInstr *
268ARCOptAddrMode::canJoinInstructions(MachineInstr *Ldst, MachineInstr *Add,
269 SmallVectorImpl<MachineInstr *> *Uses) {
270 assert(Ldst && Add && "NULL instruction passed");
271
272 MachineInstr *First = Add;
273 MachineInstr *Last = Ldst;
274 if (MDT->dominates(Ldst, Add))
276 else if (!MDT->dominates(Add, Ldst))
277 return nullptr;
278
279 LLVM_DEBUG(dbgs() << "canJoinInstructions: " << *First << *Last);
280
281 unsigned BasePos, OffPos;
282
283 if (!AII->getBaseAndOffsetPosition(*Ldst, BasePos, OffPos)) {
285 dbgs()
286 << "[canJoinInstructions] Cannot determine base/offset position\n");
287 return nullptr;
288 }
289
290 Register BaseReg = Ldst->getOperand(BasePos).getReg();
291
292 // prohibit this:
293 // v1 = add v0, c
294 // st v1, [v0, 0]
295 // and this
296 // st v0, [v0, 0]
297 // v1 = add v0, c
298 if (Ldst->mayStore() && Ldst->getOperand(0).isReg()) {
299 Register StReg = Ldst->getOperand(0).getReg();
300 if (Add->getOperand(0).getReg() == StReg || BaseReg == StReg) {
301 LLVM_DEBUG(dbgs() << "[canJoinInstructions] Store uses result of Add\n");
302 return nullptr;
303 }
304 }
305
306 SmallVector<MachineInstr *, 4> UsesAfterLdst;
307 SmallVector<MachineInstr *, 4> UsesAfterAdd;
308 for (MachineInstr &MI : MRI->use_nodbg_instructions(BaseReg)) {
309 if (&MI == Ldst || &MI == Add)
310 continue;
311 if (&MI != Add && MDT->dominates(Ldst, &MI))
312 UsesAfterLdst.push_back(&MI);
313 else if (!MDT->dominates(&MI, Ldst))
314 return nullptr;
315 if (MDT->dominates(Add, &MI))
316 UsesAfterAdd.push_back(&MI);
317 }
318
319 MachineInstr *Result = nullptr;
320
321 if (First == Add) {
322 // n = add b, i
323 // ...
324 // x = ld [b, o] or x = ld [n, o]
325
326 if (noUseOfAddBeforeLoadOrStore(First, Last)) {
327 Result = Last;
328 LLVM_DEBUG(dbgs() << "[canJoinInstructions] Can sink Add down to Ldst\n");
329 } else if (canHoistLoadStoreTo(Ldst, Add)) {
330 Result = First;
331 LLVM_DEBUG(dbgs() << "[canJoinInstructions] Can hoist Ldst to Add\n");
332 }
333 } else {
334 // x = ld [b, o]
335 // ...
336 // n = add b, i
337 Result = First;
338 LLVM_DEBUG(dbgs() << "[canJoinInstructions] Can hoist Add to Ldst\n");
339 }
340 if (Result && Uses)
341 *Uses = (Result == Ldst) ? UsesAfterLdst : UsesAfterAdd;
342 return Result;
343}
344
345bool ARCOptAddrMode::canFixPastUses(const ArrayRef<MachineInstr *> &Uses,
346 MachineOperand &Incr, unsigned BaseReg) {
347
348 assert(Incr.isImm() && "Expected immediate increment");
349 int64_t NewOffset = Incr.getImm();
350 for (MachineInstr *MI : Uses) {
351 int64_t Dummy;
352 if (isAddConstantOp(*MI, Dummy)) {
353 if (isValidIncrementOffset(Dummy + NewOffset))
354 continue;
355 return false;
356 }
357 if (isLoadStoreThatCanHandleDisplacement(AII, *MI, -NewOffset))
358 continue;
359 LLVM_DEBUG(dbgs() << "Instruction cannot handle displacement " << -NewOffset
360 << ": " << *MI);
361 return false;
362 }
363 return true;
364}
365
366void ARCOptAddrMode::fixPastUses(ArrayRef<MachineInstr *> Uses,
367 unsigned NewBase, int64_t NewOffset) {
368
369 for (MachineInstr *MI : Uses) {
370 int64_t Amount;
371 unsigned BasePos, OffPos;
372 if (isAddConstantOp(*MI, Amount)) {
373 NewOffset += Amount;
374 assert(isValidIncrementOffset(NewOffset) &&
375 "New offset won't fit into ADD instr");
376 BasePos = 1;
377 OffPos = 2;
378 } else if (AII->getBaseAndOffsetPosition(*MI, BasePos, OffPos)) {
379 MachineOperand &MO = MI->getOperand(OffPos);
380 assert(MO.isImm() && "expected immediate operand");
381 NewOffset += MO.getImm();
382 assert(isValidLoadStoreOffset(NewOffset) &&
383 "New offset won't fit into LD/ST");
384 } else
385 llvm_unreachable("unexpected instruction");
386
387 MI->getOperand(BasePos).setReg(NewBase);
388 MI->getOperand(OffPos).setImm(NewOffset);
389 }
390}
391
392bool ARCOptAddrMode::canHoistLoadStoreTo(MachineInstr *Ldst, MachineInstr *To) {
393 if (Ldst->getParent() != To->getParent())
394 return false;
396 End(Ldst->getParent()->end());
397
398 bool IsStore = Ldst->mayStore();
399 for (; MI != ME && MI != End; ++MI) {
400 if (MI->isDebugValue())
401 continue;
402 if (MI->mayStore() || MI->isCall() || MI->isInlineAsm() ||
403 MI->hasUnmodeledSideEffects())
404 return false;
405 if (IsStore && MI->mayLoad())
406 return false;
407 }
408
409 for (auto &O : Ldst->explicit_operands()) {
410 if (!O.isReg() || !O.isUse())
411 continue;
412 MachineInstr *OpDef = MRI->getVRegDef(O.getReg());
413 if (!OpDef || !MDT->dominates(OpDef, To))
414 return false;
415 }
416 return true;
417}
418
419// bool ARCOptAddrMode::canSinkLoadStoreTo(MachineInstr *Ldst, MachineInstr *To) {
420// // Can only sink load/store within same BB
421// if (Ldst->getParent() != To->getParent())
422// return false;
423// MachineBasicBlock::const_iterator MI(Ldst), ME(To),
424// End(Ldst->getParent()->end());
425
426// bool IsStore = Ldst->mayStore();
427// bool IsLoad = Ldst->mayLoad();
428
429// Register ValReg = IsLoad ? Ldst->getOperand(0).getReg() : Register();
430// for (; MI != ME && MI != End; ++MI) {
431// if (MI->isDebugValue())
432// continue;
433// if (MI->mayStore() || MI->isCall() || MI->isInlineAsm() ||
434// MI->hasUnmodeledSideEffects())
435// return false;
436// if (IsStore && MI->mayLoad())
437// return false;
438// if (ValReg && MI->readsVirtualRegister(ValReg))
439// return false;
440// }
441// return true;
442// }
443
444void ARCOptAddrMode::changeToAddrMode(MachineInstr &Ldst, unsigned NewOpcode,
445 unsigned NewBase,
446 MachineOperand &NewOffset) {
447 bool IsStore = Ldst.mayStore();
448 unsigned BasePos, OffPos;
449 MachineOperand Src = MachineOperand::CreateImm(0xDEADBEEF);
450 AII->getBaseAndOffsetPosition(Ldst, BasePos, OffPos);
451
452 Register BaseReg = Ldst.getOperand(BasePos).getReg();
453
454 Ldst.removeOperand(OffPos);
455 Ldst.removeOperand(BasePos);
456
457 if (IsStore) {
458 Src = Ldst.getOperand(BasePos - 1);
459 Ldst.removeOperand(BasePos - 1);
460 }
461
462 Ldst.setDesc(AST->getInstrInfo()->get(NewOpcode));
463 Ldst.addOperand(MachineOperand::CreateReg(NewBase, true));
464 if (IsStore)
465 Ldst.addOperand(Src);
466 Ldst.addOperand(MachineOperand::CreateReg(BaseReg, false));
467 Ldst.addOperand(NewOffset);
468 LLVM_DEBUG(dbgs() << "[ABAW] New Ldst: " << Ldst);
469}
470
471bool ARCOptAddrMode::processBasicBlock(MachineBasicBlock &MBB) {
472 bool Changed = false;
473 for (auto MI = MBB.begin(), ME = MBB.end(); MI != ME; ++MI) {
474 if (MI->isDebugValue())
475 continue;
476 if (!MI->mayLoad() && !MI->mayStore())
477 continue;
478 if (ARC::getPostIncOpcode(MI->getOpcode()) < 0)
479 continue;
480 MachineInstr *Res = tryToCombine(*MI);
481 if (Res) {
482 Changed = true;
483 // Res points to the next instruction. Rewind to process it
484 MI = std::prev(Res->getIterator());
485 }
486 }
487 return Changed;
488}
489
490bool ARCOptAddrMode::runOnMachineFunction(MachineFunction &MF) {
491 if (skipFunction(MF.getFunction()) || KILL_PASS())
492 return false;
493
494#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
495 if (DUMP_BEFORE())
496 MF.dump();
497#endif
498 if (VIEW_BEFORE())
499 MF.viewCFG();
500
501 AST = &MF.getSubtarget<ARCSubtarget>();
502 AII = AST->getInstrInfo();
503 MRI = &MF.getRegInfo();
504 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
505
506 bool Changed = false;
507 for (auto &MBB : MF)
509
510#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
511 if (DUMP_AFTER())
512 MF.dump();
513#endif
514 if (VIEW_AFTER())
515 MF.viewCFG();
516 return Changed;
517}
518
519//===----------------------------------------------------------------------===//
520// Public Constructor Functions
521//===----------------------------------------------------------------------===//
522
523FunctionPass *llvm::createARCOptAddrMode() { return new ARCOptAddrMode(); }
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define VIEW_BEFORE()
static bool isLoadStoreThatCanHandleDisplacement(const TargetInstrInfo *TII, const MachineInstr &MI, int64_t Disp)
static bool dominatesAllUsesOf(const MachineInstr *MI, unsigned VReg, MachineDominatorTree *MDT, MachineRegisterInfo *MRI)
static bool isValidIncrementOffset(int64_t Off)
#define DUMP_AFTER()
#define KILL_PASS()
#define OPTADDRMODE_DESC
static bool isAddConstantOp(const MachineInstr &MI, int64_t &Amount)
static bool isValidLoadStoreOffset(int64_t Off)
#define VIEW_AFTER()
#define DUMP_BEFORE()
MachineBasicBlock & MBB
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Promote Memory to Register
Definition Mem2Reg.cpp:110
Remove Loads Into Fake Uses
#define LLVM_DEBUG(...)
Definition Debug.h:119
static bool processBasicBlock(MachineBasicBlock &MBB, BlockStateMap &BlockStates, DirtySuccessorsWorkList &DirtySuccessors, bool IsX86INTR, const TargetInstrInfo *TII)
Loop over all of the instructions in the basic block, inserting vzeroupper instructions before functi...
virtual bool getBaseAndOffsetPosition(const MachineInstr &MI, unsigned &BasePos, unsigned &OffsetPos) const override
const ARCInstrInfo * getInstrInfo() const override
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:278
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
MachineInstrBundleIterator< const MachineInstr > const_iterator
iterator insertAfter(iterator I, MachineInstr *MI)
Insert MI into the instruction list after I.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void dump() const
dump - Print the current MachineFunction to cerr, useful for debugger use.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
void viewCFG() const
viewCFG - This function is meant for use from the debugger.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
LLVM_ABI MachineInstr * removeFromParent()
Unlink 'this' from the containing basic block, and return it without deleting it.
const MachineBasicBlock * getParent() const
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
mop_range explicit_operands()
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
LLVM_ABI void removeOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
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)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:66
void push_back(const T &Elt)
TargetInstrInfo - Interface to description of machine instruction set.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM_ABI unsigned getOperandNo() const
Return the operand # of this use in its User.
Definition Use.cpp:35
Value * getOperand(unsigned i) const
Definition User.h:207
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
static cl::opt< unsigned > ArcKillAddrMode("arc-kill-addr-mode", cl::init(0), cl::ReallyHidden)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
@ Add
Sum of integers.
ArrayRef(const T &OneElt) -> ArrayRef< T >
FunctionPass * createARCOptAddrMode()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880