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
49} // end namespace llvm
50
51namespace {
52class ARCOptAddrMode : public MachineFunctionPass {
53public:
54 static char ID;
55
56 ARCOptAddrMode() : MachineFunctionPass(ID) {}
57
58 StringRef getPassName() const override { return OPTADDRMODE_DESC; }
59
60 void getAnalysisUsage(AnalysisUsage &AU) const override {
61 AU.setPreservesCFG();
63 AU.addRequired<MachineDominatorTreeWrapperPass>();
64 }
65
66 bool runOnMachineFunction(MachineFunction &MF) override;
67
68private:
69 const ARCSubtarget *AST = nullptr;
70 const ARCInstrInfo *AII = nullptr;
71 MachineRegisterInfo *MRI = nullptr;
72 MachineDominatorTree *MDT = nullptr;
73
74 // Tries to combine \p Ldst with increment of its base register to form
75 // single post-increment instruction.
76 MachineInstr *tryToCombine(MachineInstr &Ldst);
77
78 // Returns true if result of \p Add is not used before \p Ldst
79 bool noUseOfAddBeforeLoadOrStore(const MachineInstr *Add,
80 const MachineInstr *Ldst);
81
82 // Returns true if load/store instruction \p Ldst can be hoisted up to
83 // instruction \p To
84 bool canHoistLoadStoreTo(MachineInstr *Ldst, MachineInstr *To);
85
86 // // Returns true if load/store instruction \p Ldst can be sunk down
87 // // to instruction \p To
88 // bool canSinkLoadStoreTo(MachineInstr *Ldst, MachineInstr *To);
89
90 // Check if instructions \p Ldst and \p Add can be moved to become adjacent
91 // If they can return instruction which need not to move.
92 // If \p Uses is not null, fill it with instructions after \p Ldst which use
93 // \p Ldst's base register
94 MachineInstr *canJoinInstructions(MachineInstr *Ldst, MachineInstr *Add,
95 SmallVectorImpl<MachineInstr *> *Uses);
96
97 // Returns true if all instruction in \p Uses array can be adjusted
98 // to accomodate increment of register \p BaseReg by \p Incr
99 bool canFixPastUses(const ArrayRef<MachineInstr *> &Uses,
100 MachineOperand &Incr, unsigned BaseReg);
101
102 // Update all instructions in \p Uses to accomodate increment
103 // of \p BaseReg by \p Offset
104 void fixPastUses(ArrayRef<MachineInstr *> Uses, unsigned BaseReg,
105 int64_t Offset);
106
107 // Change instruction \p Ldst to postincrement form.
108 // \p NewBase is register to hold update base value
109 // \p NewOffset is instruction's new offset
110 void changeToAddrMode(MachineInstr &Ldst, unsigned NewOpcode,
111 unsigned NewBase, MachineOperand &NewOffset);
112
113 bool processBasicBlock(MachineBasicBlock &MBB);
114};
115
116} // end anonymous namespace
117
118char ARCOptAddrMode::ID = 0;
120 false)
123 false)
124
125// Return true if \p Off can be used as immediate offset
126// operand of load/store instruction (S9 literal)
127static bool isValidLoadStoreOffset(int64_t Off) { return isInt<9>(Off); }
128
129// Return true if \p Off can be used as immediate operand of
130// ADD/SUB instruction (U6 literal)
131static bool isValidIncrementOffset(int64_t Off) { return isUInt<6>(Off); }
132
133static bool isAddConstantOp(const MachineInstr &MI, int64_t &Amount) {
134 int64_t Sign = 1;
135 switch (MI.getOpcode()) {
136 case ARC::SUB_rru6:
137 Sign = -1;
138 [[fallthrough]];
139 case ARC::ADD_rru6:
140 assert(MI.getOperand(2).isImm() && "Expected immediate operand");
141 Amount = Sign * MI.getOperand(2).getImm();
142 return true;
143 default:
144 return false;
145 }
146}
147
148// Return true if \p MI dominates of uses of virtual register \p VReg
149static bool dominatesAllUsesOf(const MachineInstr *MI, unsigned VReg,
151 MachineRegisterInfo *MRI) {
152
153 assert(Register::isVirtualRegister(VReg) && "Expected virtual register!");
154
155 for (const MachineOperand &Use : MRI->use_nodbg_operands(VReg)) {
156 const MachineInstr *User = Use.getParent();
157 if (User->isPHI()) {
158 unsigned BBOperandIdx = Use.getOperandNo() + 1;
159 MachineBasicBlock *MBB = User->getOperand(BBOperandIdx).getMBB();
160 if (MBB->empty()) {
161 const MachineBasicBlock *InstBB = MI->getParent();
162 assert(InstBB != MBB && "Instruction found in empty MBB");
163 if (!MDT->dominates(InstBB, MBB))
164 return false;
165 continue;
166 }
167 User = &*MBB->rbegin();
168 }
169
170 if (!MDT->dominates(MI, User))
171 return false;
172 }
173 return true;
174}
175
176// Return true if \p MI is load/store instruction with immediate offset
177// which can be adjusted by \p Disp
179 const MachineInstr &MI,
180 int64_t Disp) {
181 unsigned BasePos, OffPos;
182 if (!TII->getBaseAndOffsetPosition(MI, BasePos, OffPos))
183 return false;
184 const MachineOperand &MO = MI.getOperand(OffPos);
185 if (!MO.isImm())
186 return false;
187 int64_t Offset = MO.getImm() + Disp;
189}
190
191bool ARCOptAddrMode::noUseOfAddBeforeLoadOrStore(const MachineInstr *Add,
192 const MachineInstr *Ldst) {
193 Register R = Add->getOperand(0).getReg();
194 return dominatesAllUsesOf(Ldst, R, MDT, MRI);
195}
196
197MachineInstr *ARCOptAddrMode::tryToCombine(MachineInstr &Ldst) {
198 assert(Ldst.mayLoadOrStore() && "LD/ST instruction expected");
199
200 unsigned BasePos, OffsetPos;
201
202 LLVM_DEBUG(dbgs() << "[ABAW] tryToCombine " << Ldst);
203 if (!AII->getBaseAndOffsetPosition(Ldst, BasePos, OffsetPos)) {
204 LLVM_DEBUG(dbgs() << "[ABAW] Not a recognized load/store\n");
205 return nullptr;
206 }
207
208 MachineOperand &Base = Ldst.getOperand(BasePos);
209 MachineOperand &Offset = Ldst.getOperand(OffsetPos);
210
211 assert(Base.isReg() && "Base operand must be register");
212 if (!Offset.isImm()) {
213 LLVM_DEBUG(dbgs() << "[ABAW] Offset is not immediate\n");
214 return nullptr;
215 }
216
217 Register B = Base.getReg();
218 if (!Register::isVirtualRegister(B)) {
219 LLVM_DEBUG(dbgs() << "[ABAW] Base is not VReg\n");
220 return nullptr;
221 }
222
223 // TODO: try to generate address preincrement
224 if (Offset.getImm() != 0) {
225 LLVM_DEBUG(dbgs() << "[ABAW] Non-zero offset\n");
226 return nullptr;
227 }
228
229 for (auto &Add : MRI->use_nodbg_instructions(B)) {
230 int64_t Incr;
231 if (!isAddConstantOp(Add, Incr))
232 continue;
233 if (!isValidLoadStoreOffset(Incr))
234 continue;
235
236 SmallVector<MachineInstr *, 8> Uses;
237 MachineInstr *MoveTo = canJoinInstructions(&Ldst, &Add, &Uses);
238
239 if (!MoveTo)
240 continue;
241
242 if (!canFixPastUses(Uses, Add.getOperand(2), B))
243 continue;
244
245 LLVM_DEBUG(MachineInstr *First = &Ldst; MachineInstr *Last = &Add;
246 if (MDT->dominates(Last, First)) std::swap(First, Last);
247 dbgs() << "[ABAW] Instructions " << *First << " and " << *Last
248 << " combined\n";
249
250 );
251
252 MachineInstr *Result = Ldst.getNextNode();
253 if (MoveTo == &Add) {
254 Ldst.removeFromParent();
255 Add.getParent()->insertAfter(Add.getIterator(), &Ldst);
256 }
257 if (Result == &Add)
258 Result = Result->getNextNode();
259
260 fixPastUses(Uses, B, Incr);
261
262 int NewOpcode = ARC::getPostIncOpcode(Ldst.getOpcode());
263 assert(NewOpcode > 0 && "No postincrement form found");
264 unsigned NewBaseReg = Add.getOperand(0).getReg();
265 changeToAddrMode(Ldst, NewOpcode, NewBaseReg, Add.getOperand(2));
266 Add.eraseFromParent();
267
268 return Result;
269 }
270 return nullptr;
271}
272
273MachineInstr *
274ARCOptAddrMode::canJoinInstructions(MachineInstr *Ldst, MachineInstr *Add,
275 SmallVectorImpl<MachineInstr *> *Uses) {
276 assert(Ldst && Add && "NULL instruction passed");
277
278 MachineInstr *First = Add;
279 MachineInstr *Last = Ldst;
280 if (MDT->dominates(Ldst, Add))
282 else if (!MDT->dominates(Add, Ldst))
283 return nullptr;
284
285 LLVM_DEBUG(dbgs() << "canJoinInstructions: " << *First << *Last);
286
287 unsigned BasePos, OffPos;
288
289 if (!AII->getBaseAndOffsetPosition(*Ldst, BasePos, OffPos)) {
291 dbgs()
292 << "[canJoinInstructions] Cannot determine base/offset position\n");
293 return nullptr;
294 }
295
296 Register BaseReg = Ldst->getOperand(BasePos).getReg();
297
298 // prohibit this:
299 // v1 = add v0, c
300 // st v1, [v0, 0]
301 // and this
302 // st v0, [v0, 0]
303 // v1 = add v0, c
304 if (Ldst->mayStore() && Ldst->getOperand(0).isReg()) {
305 Register StReg = Ldst->getOperand(0).getReg();
306 if (Add->getOperand(0).getReg() == StReg || BaseReg == StReg) {
307 LLVM_DEBUG(dbgs() << "[canJoinInstructions] Store uses result of Add\n");
308 return nullptr;
309 }
310 }
311
312 SmallVector<MachineInstr *, 4> UsesAfterLdst;
313 SmallVector<MachineInstr *, 4> UsesAfterAdd;
314 for (MachineInstr &MI : MRI->use_nodbg_instructions(BaseReg)) {
315 if (&MI == Ldst || &MI == Add)
316 continue;
317 if (&MI != Add && MDT->dominates(Ldst, &MI))
318 UsesAfterLdst.push_back(&MI);
319 else if (!MDT->dominates(&MI, Ldst))
320 return nullptr;
321 if (MDT->dominates(Add, &MI))
322 UsesAfterAdd.push_back(&MI);
323 }
324
325 MachineInstr *Result = nullptr;
326
327 if (First == Add) {
328 // n = add b, i
329 // ...
330 // x = ld [b, o] or x = ld [n, o]
331
332 if (noUseOfAddBeforeLoadOrStore(First, Last)) {
333 Result = Last;
334 LLVM_DEBUG(dbgs() << "[canJoinInstructions] Can sink Add down to Ldst\n");
335 } else if (canHoistLoadStoreTo(Ldst, Add)) {
336 Result = First;
337 LLVM_DEBUG(dbgs() << "[canJoinInstructions] Can hoist Ldst to Add\n");
338 }
339 } else {
340 // x = ld [b, o]
341 // ...
342 // n = add b, i
343 Result = First;
344 LLVM_DEBUG(dbgs() << "[canJoinInstructions] Can hoist Add to Ldst\n");
345 }
346 if (Result && Uses)
347 *Uses = (Result == Ldst) ? UsesAfterLdst : UsesAfterAdd;
348 return Result;
349}
350
351bool ARCOptAddrMode::canFixPastUses(const ArrayRef<MachineInstr *> &Uses,
352 MachineOperand &Incr, unsigned BaseReg) {
353
354 assert(Incr.isImm() && "Expected immediate increment");
355 int64_t NewOffset = Incr.getImm();
356 for (MachineInstr *MI : Uses) {
357 int64_t Dummy;
358 if (isAddConstantOp(*MI, Dummy)) {
359 if (isValidIncrementOffset(Dummy + NewOffset))
360 continue;
361 return false;
362 }
363 if (isLoadStoreThatCanHandleDisplacement(AII, *MI, -NewOffset))
364 continue;
365 LLVM_DEBUG(dbgs() << "Instruction cannot handle displacement " << -NewOffset
366 << ": " << *MI);
367 return false;
368 }
369 return true;
370}
371
372void ARCOptAddrMode::fixPastUses(ArrayRef<MachineInstr *> Uses,
373 unsigned NewBase, int64_t NewOffset) {
374
375 for (MachineInstr *MI : Uses) {
376 int64_t Amount;
377 unsigned BasePos, OffPos;
378 if (isAddConstantOp(*MI, Amount)) {
379 NewOffset += Amount;
380 assert(isValidIncrementOffset(NewOffset) &&
381 "New offset won't fit into ADD instr");
382 BasePos = 1;
383 OffPos = 2;
384 } else if (AII->getBaseAndOffsetPosition(*MI, BasePos, OffPos)) {
385 MachineOperand &MO = MI->getOperand(OffPos);
386 assert(MO.isImm() && "expected immediate operand");
387 NewOffset += MO.getImm();
388 assert(isValidLoadStoreOffset(NewOffset) &&
389 "New offset won't fit into LD/ST");
390 } else
391 llvm_unreachable("unexpected instruction");
392
393 MI->getOperand(BasePos).setReg(NewBase);
394 MI->getOperand(OffPos).setImm(NewOffset);
395 }
396}
397
398bool ARCOptAddrMode::canHoistLoadStoreTo(MachineInstr *Ldst, MachineInstr *To) {
399 if (Ldst->getParent() != To->getParent())
400 return false;
402 End(Ldst->getParent()->end());
403
404 bool IsStore = Ldst->mayStore();
405 for (; MI != ME && MI != End; ++MI) {
406 if (MI->isDebugValue())
407 continue;
408 if (MI->mayStore() || MI->isCall() || MI->isInlineAsm() ||
409 MI->hasUnmodeledSideEffects())
410 return false;
411 if (IsStore && MI->mayLoad())
412 return false;
413 }
414
415 for (auto &O : Ldst->explicit_operands()) {
416 if (!O.isReg() || !O.isUse())
417 continue;
418 MachineInstr *OpDef = MRI->getVRegDef(O.getReg());
419 if (!OpDef || !MDT->dominates(OpDef, To))
420 return false;
421 }
422 return true;
423}
424
425// bool ARCOptAddrMode::canSinkLoadStoreTo(MachineInstr *Ldst, MachineInstr *To) {
426// // Can only sink load/store within same BB
427// if (Ldst->getParent() != To->getParent())
428// return false;
429// MachineBasicBlock::const_iterator MI(Ldst), ME(To),
430// End(Ldst->getParent()->end());
431
432// bool IsStore = Ldst->mayStore();
433// bool IsLoad = Ldst->mayLoad();
434
435// Register ValReg = IsLoad ? Ldst->getOperand(0).getReg() : Register();
436// for (; MI != ME && MI != End; ++MI) {
437// if (MI->isDebugValue())
438// continue;
439// if (MI->mayStore() || MI->isCall() || MI->isInlineAsm() ||
440// MI->hasUnmodeledSideEffects())
441// return false;
442// if (IsStore && MI->mayLoad())
443// return false;
444// if (ValReg && MI->readsVirtualRegister(ValReg))
445// return false;
446// }
447// return true;
448// }
449
450void ARCOptAddrMode::changeToAddrMode(MachineInstr &Ldst, unsigned NewOpcode,
451 unsigned NewBase,
452 MachineOperand &NewOffset) {
453 bool IsStore = Ldst.mayStore();
454 unsigned BasePos, OffPos;
455 MachineOperand Src = MachineOperand::CreateImm(0xDEADBEEF);
456 AII->getBaseAndOffsetPosition(Ldst, BasePos, OffPos);
457
458 Register BaseReg = Ldst.getOperand(BasePos).getReg();
459
460 Ldst.removeOperand(OffPos);
461 Ldst.removeOperand(BasePos);
462
463 if (IsStore) {
464 Src = Ldst.getOperand(BasePos - 1);
465 Ldst.removeOperand(BasePos - 1);
466 }
467
468 Ldst.setDesc(AST->getInstrInfo()->get(NewOpcode));
469 Ldst.addOperand(MachineOperand::CreateReg(NewBase, true));
470 if (IsStore)
471 Ldst.addOperand(Src);
472 Ldst.addOperand(MachineOperand::CreateReg(BaseReg, false));
473 Ldst.addOperand(NewOffset);
474 LLVM_DEBUG(dbgs() << "[ABAW] New Ldst: " << Ldst);
475}
476
477bool ARCOptAddrMode::processBasicBlock(MachineBasicBlock &MBB) {
478 bool Changed = false;
479 for (auto MI = MBB.begin(), ME = MBB.end(); MI != ME; ++MI) {
480 if (MI->isDebugValue())
481 continue;
482 if (!MI->mayLoad() && !MI->mayStore())
483 continue;
484 if (ARC::getPostIncOpcode(MI->getOpcode()) < 0)
485 continue;
486 MachineInstr *Res = tryToCombine(*MI);
487 if (Res) {
488 Changed = true;
489 // Res points to the next instruction. Rewind to process it
490 MI = std::prev(Res->getIterator());
491 }
492 }
493 return Changed;
494}
495
496bool ARCOptAddrMode::runOnMachineFunction(MachineFunction &MF) {
497 if (skipFunction(MF.getFunction()) || KILL_PASS())
498 return false;
499
500#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
501 if (DUMP_BEFORE())
502 MF.dump();
503#endif
504 if (VIEW_BEFORE())
505 MF.viewCFG();
506
507 AST = &MF.getSubtarget<ARCSubtarget>();
508 AII = AST->getInstrInfo();
509 MRI = &MF.getRegInfo();
510 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
511
512 bool Changed = false;
513 for (auto &MBB : MF)
515
516#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
517 if (DUMP_AFTER())
518 MF.dump();
519#endif
520 if (VIEW_AFTER())
521 MF.viewCFG();
522 return Changed;
523}
524
525//===----------------------------------------------------------------------===//
526// Public Constructor Functions
527//===----------------------------------------------------------------------===//
528
529FunctionPass *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)
static false bool isValidLoadStoreOffset(int64_t Off)
#define DUMP_AFTER()
#define OPTADDRMODE_NAME
#define KILL_PASS()
#define OPTADDRMODE_DESC
static bool isAddConstantOp(const MachineInstr &MI, int64_t &Amount)
#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
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
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:275
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.
Analysis pass which computes a MachineDominatorTree.
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 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
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
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:36
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:578
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
void initializeARCOptAddrModePass(PassRegistry &)
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