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"
26#include "llvm/Support/Debug.h"
28
29using namespace llvm;
30
31#define OPTADDRMODE_DESC "ARC load/store address mode"
32#define OPTADDRMODE_NAME "arc-addr-mode"
33#define DEBUG_TYPE "arc-addr-mode"
34
35namespace llvm {
36
37#define DUMP_BEFORE(Mode) (((Mode) & 0x0001) != 0)
38#define DUMP_AFTER(Mode) (((Mode) & 0x0002) != 0)
39#define VIEW_BEFORE(Mode) (((Mode) & 0x0004) != 0)
40#define VIEW_AFTER(Mode) (((Mode) & 0x0008) != 0)
41#define KILL_PASS(Mode) (((Mode) & 0x0010) != 0)
42
44} // end namespace llvm
45
46namespace {
47class ARCOptAddrMode : public MachineFunctionPass {
48public:
49 static char ID;
50
51 ARCOptAddrMode() : MachineFunctionPass(ID) {}
52
53 StringRef getPassName() const override { return OPTADDRMODE_DESC; }
54
55 void getAnalysisUsage(AnalysisUsage &AU) const override {
56 AU.setPreservesCFG();
58 AU.addRequired<MachineDominatorTreeWrapperPass>();
59 }
60
61 bool runOnMachineFunction(MachineFunction &MF) override;
62
63private:
64 const ARCSubtarget *AST = nullptr;
65 const ARCInstrInfo *AII = nullptr;
66 MachineRegisterInfo *MRI = nullptr;
67 MachineDominatorTree *MDT = nullptr;
68
69 // Tries to combine \p Ldst with increment of its base register to form
70 // single post-increment instruction.
71 MachineInstr *tryToCombine(MachineInstr &Ldst);
72
73 // Returns true if result of \p Add is not used before \p Ldst
74 bool noUseOfAddBeforeLoadOrStore(const MachineInstr *Add,
75 const MachineInstr *Ldst);
76
77 // Returns true if load/store instruction \p Ldst can be hoisted up to
78 // instruction \p To
79 bool canHoistLoadStoreTo(MachineInstr *Ldst, MachineInstr *To);
80
81 // // Returns true if load/store instruction \p Ldst can be sunk down
82 // // to instruction \p To
83 // bool canSinkLoadStoreTo(MachineInstr *Ldst, MachineInstr *To);
84
85 // Check if instructions \p Ldst and \p Add can be moved to become adjacent
86 // If they can return instruction which need not to move.
87 // If \p Uses is not null, fill it with instructions after \p Ldst which use
88 // \p Ldst's base register
89 MachineInstr *canJoinInstructions(MachineInstr *Ldst, MachineInstr *Add,
90 SmallVectorImpl<MachineInstr *> *Uses);
91
92 // Returns true if all instruction in \p Uses array can be adjusted
93 // to accomodate increment of register \p BaseReg by \p Incr
94 bool canFixPastUses(const ArrayRef<MachineInstr *> &Uses,
95 MachineOperand &Incr, unsigned BaseReg);
96
97 // Update all instructions in \p Uses to accomodate increment
98 // of \p BaseReg by \p Offset
99 void fixPastUses(ArrayRef<MachineInstr *> Uses, unsigned BaseReg,
100 int64_t Offset);
101
102 // Change instruction \p Ldst to postincrement form.
103 // \p NewBase is register to hold update base value
104 // \p NewOffset is instruction's new offset
105 void changeToAddrMode(MachineInstr &Ldst, unsigned NewOpcode,
106 unsigned NewBase, MachineOperand &NewOffset);
107
108 bool processBasicBlock(MachineBasicBlock &MBB);
109};
110
111} // end anonymous namespace
112
113char ARCOptAddrMode::ID = 0;
114
115// Return true if \p Off can be used as immediate offset
116// operand of load/store instruction (S9 literal)
117static bool isValidLoadStoreOffset(int64_t Off) { return isInt<9>(Off); }
118
119// Return true if \p Off can be used as immediate operand of
120// ADD/SUB instruction (U6 literal)
121static bool isValidIncrementOffset(int64_t Off) { return isUInt<6>(Off); }
122
123static bool isAddConstantOp(const MachineInstr &MI, int64_t &Amount) {
124 int64_t Sign = 1;
125 switch (MI.getOpcode()) {
126 case ARC::SUB_rru6:
127 Sign = -1;
128 [[fallthrough]];
129 case ARC::ADD_rru6:
130 assert(MI.getOperand(2).isImm() && "Expected immediate operand");
131 Amount = Sign * MI.getOperand(2).getImm();
132 return true;
133 default:
134 return false;
135 }
136}
137
138// Return true if \p MI dominates of uses of virtual register \p VReg
139static bool dominatesAllUsesOf(const MachineInstr *MI, unsigned VReg,
142
143 assert(Register::isVirtualRegister(VReg) && "Expected virtual register!");
144
145 for (const MachineOperand &Use : MRI->use_nodbg_operands(VReg)) {
146 const MachineInstr *User = Use.getParent();
147 if (User->isPHI()) {
148 unsigned BBOperandIdx = Use.getOperandNo() + 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;
179}
180
181bool 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
187MachineInstr *ARCOptAddrMode::tryToCombine(MachineInstr &Ldst) {
188 assert(Ldst.mayLoadOrStore() && "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();
208 if (!Register::isVirtualRegister(B)) {
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
226 SmallVector<MachineInstr *, 8> Uses;
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
263MachineInstr *
264ARCOptAddrMode::canJoinInstructions(MachineInstr *Ldst, MachineInstr *Add,
265 SmallVectorImpl<MachineInstr *> *Uses) {
266 assert(Ldst && Add && "NULL instruction passed");
267
268 MachineInstr *First = Add;
269 MachineInstr *Last = Ldst;
270 if (MDT->dominates(Ldst, Add))
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)) {
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
341bool 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
362void 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
388bool 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;
419// MachineBasicBlock::const_iterator MI(Ldst), ME(To),
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
440void 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
467bool 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
486bool ARCOptAddrMode::runOnMachineFunction(MachineFunction &MF) {
487 AST = &MF.getSubtarget<ARCSubtarget>();
488 unsigned Mode = AST->getCLOpts().kill_addr_mode;
489 if (skipFunction(MF.getFunction()) || KILL_PASS(Mode))
490 return false;
491
492#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
493 if (DUMP_BEFORE(Mode))
494 MF.dump();
495#endif
496 if (VIEW_BEFORE(Mode))
497 MF.viewCFG();
498
499 AII = AST->getInstrInfo();
500 MRI = &MF.getRegInfo();
501 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
502
503 bool Changed = false;
504 for (auto &MBB : MF)
506
507#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
508 if (DUMP_AFTER(Mode))
509 MF.dump();
510#endif
511 if (VIEW_AFTER(Mode))
512 MF.viewCFG();
513 return Changed;
514}
515
516//===----------------------------------------------------------------------===//
517// Public Constructor Functions
518//===----------------------------------------------------------------------===//
519
520FunctionPass *llvm::createARCOptAddrMode() { return new ARCOptAddrMode(); }
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 KILL_PASS(Mode)
#define VIEW_AFTER(Mode)
#define DUMP_AFTER(Mode)
#define DUMP_BEFORE(Mode)
#define OPTADDRMODE_DESC
static bool isAddConstantOp(const MachineInstr &MI, int64_t &Amount)
static bool isValidLoadStoreOffset(int64_t Off)
#define VIEW_BEFORE(Mode)
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
MachineRegisterInfo & MRI
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
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 ARCOptions & getCLOpts() const
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:280
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
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_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
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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
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()
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880