LLVM 24.0.0git
RISCVZilsdOptimizer.cpp
Go to the documentation of this file.
1//===-- RISCVZilsdOptimizer.cpp - RISC-V Zilsd Load/Store Optimizer ------===//
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// This file contains a pass that performs load/store optimizations for the
10// RISC-V Zilsd extension. It combines pairs of 32-bit load/store instructions
11// into single 64-bit LD/SD instructions when possible.
12//
13// The pass runs in two phases:
14// 1. Pre-allocation: Reschedules loads/stores to bring consecutive memory
15// accesses closer together and forms LD/SD pairs with register hints.
16// 2. Post-allocation: Fixes invalid LD/SD instructions if register allocation
17// didn't provide suitable consecutive registers.
18//
19// Note: second phase is integrated into RISCVLoadStoreOptimizer
20//
21//===----------------------------------------------------------------------===//
22
23#include "RISCV.h"
24#include "RISCVInstrInfo.h"
25#include "RISCVRegisterInfo.h"
26#include "RISCVSubtarget.h"
27#include "llvm/ADT/DenseMap.h"
29#include "llvm/ADT/Statistic.h"
40#include "llvm/IR/Analysis.h"
42#include "llvm/Support/Debug.h"
43#include <algorithm>
44
45using namespace llvm;
46
47#define DEBUG_TYPE "riscv-pre-alloc-zilsd-opt"
48
49STATISTIC(NumLDFormed, "Number of LD instructions formed");
50STATISTIC(NumSDFormed, "Number of SD instructions formed");
51
52namespace {
53
54//===----------------------------------------------------------------------===//
55// Pre-allocation Zilsd optimization pass
56//===----------------------------------------------------------------------===//
57class RISCVPreAllocZilsdOptLegacy : public MachineFunctionPass {
58public:
59 static char ID;
60
61 RISCVPreAllocZilsdOptLegacy() : MachineFunctionPass(ID) {}
62
63 bool runOnMachineFunction(MachineFunction &MF) override;
64
65 StringRef getPassName() const override {
66 return "RISC-V pre-allocation Zilsd load/store optimization";
67 }
68
69 MachineFunctionProperties getRequiredProperties() const override {
70 return MachineFunctionProperties().setIsSSA();
71 }
72
73 void getAnalysisUsage(AnalysisUsage &AU) const override {
74 AU.addRequired<AAResultsWrapperPass>();
75 AU.addRequired<MachineDominatorTreeWrapperPass>();
76 AU.setPreservesCFG();
78 }
79};
80
81class RISCVPreAllocZilsdOptImpl {
82 enum class MemoryOffsetKind {
83 Imm = 0,
84 Global = 1,
85 CPI = 2,
86 BlockAddr = 3,
87 FrameIdx = 4,
88 Unknown = 5,
89 };
90 using MemOffset = std::pair<MemoryOffsetKind, int>;
91 using BaseRegInfo = std::pair<unsigned, MemoryOffsetKind>;
92
93 bool isMemoryOp(const MachineInstr &MI);
94 bool rescheduleLoadStoreInstrs(MachineBasicBlock *MBB);
95 bool canFormLdSdPair(MachineInstr *MI0, MachineInstr *MI1);
96 bool rescheduleOps(MachineBasicBlock *MBB,
97 SmallVectorImpl<MachineInstr *> &MIs, BaseRegInfo Base,
98 bool IsLoad,
99 DenseMap<MachineInstr *, unsigned> &MI2LocMap);
100 bool isSafeToMove(MachineInstr *MI, MachineInstr *Target, bool MoveForward);
101 MemOffset getMemoryOpOffset(const MachineInstr &MI);
102
103 const RISCVSubtarget *STI;
104 const RISCVInstrInfo *TII;
105 const RISCVRegisterInfo *TRI;
106 MachineRegisterInfo *MRI;
107 AliasAnalysis *AA;
108 MachineDominatorTree *DT;
109 Align RequiredAlign;
110
111public:
112 bool runOnMachineFunction(MachineFunction &MF,
113 function_ref<AliasAnalysis *()> GetAA,
114 function_ref<MachineDominatorTree *()> GetMDT);
115};
116
117} // end anonymous namespace
118
119char RISCVPreAllocZilsdOptLegacy::ID = 0;
120
121INITIALIZE_PASS_BEGIN(RISCVPreAllocZilsdOptLegacy, "riscv-prera-zilsd-opt",
122 "RISC-V pre-allocation Zilsd optimization", false, false)
125INITIALIZE_PASS_END(RISCVPreAllocZilsdOptLegacy, "riscv-prera-zilsd-opt",
126 "RISC-V pre-allocation Zilsd optimization", false, false)
127
128//===----------------------------------------------------------------------===//
129// Pre-allocation pass implementation
130//===----------------------------------------------------------------------===//
131
132bool RISCVPreAllocZilsdOptImpl::runOnMachineFunction(
135 STI = &MF.getSubtarget<RISCVSubtarget>();
136 if (!STI->getCLOpts().zilsd_opt)
137 return false;
138
139 // Only run on RV32 with Zilsd extension
140 if (STI->is64Bit() || !STI->hasStdExtZilsd())
141 return false;
142
143 TII = STI->getInstrInfo();
144 TRI = STI->getRegisterInfo();
145 MRI = &MF.getRegInfo();
146 AA = GetAA();
147 DT = GetMDT();
148
149 // Check alignment: default is 8-byte, but allow 4-byte with tune feature
150 // If unaligned scalar memory is enabled, allow any alignment
151 RequiredAlign = STI->getZilsdAlign();
152 bool Modified = false;
153 for (auto &MBB : MF) {
154 Modified |= rescheduleLoadStoreInstrs(&MBB);
155 }
156
157 return Modified;
158}
159
160RISCVPreAllocZilsdOptImpl::MemOffset
161RISCVPreAllocZilsdOptImpl::getMemoryOpOffset(const MachineInstr &MI) {
162 switch (MI.getOpcode()) {
163 case RISCV::LW:
164 case RISCV::SW: {
165 // For LW/SW, the base is in operand 1 and offset is in operand 2
166 const MachineOperand &BaseOp = MI.getOperand(1);
167 const MachineOperand &OffsetOp = MI.getOperand(2);
168
169 // Handle immediate offset
170 if (OffsetOp.isImm()) {
171 if (BaseOp.isFI())
172 return std::make_pair(MemoryOffsetKind::FrameIdx, OffsetOp.getImm());
173 return std::make_pair(MemoryOffsetKind::Imm, OffsetOp.getImm());
174 }
175
176 // Handle symbolic operands with MO_LO flag (from MergeBaseOffset)
177 if (OffsetOp.getTargetFlags() & RISCVII::MO_LO) {
178 if (OffsetOp.isGlobal())
179 return std::make_pair(MemoryOffsetKind::Global, OffsetOp.getOffset());
180 if (OffsetOp.isCPI())
181 return std::make_pair(MemoryOffsetKind::CPI, OffsetOp.getOffset());
182 if (OffsetOp.isBlockAddress())
183 return std::make_pair(MemoryOffsetKind::BlockAddr,
184 OffsetOp.getOffset());
185 }
186
187 break;
188 }
189 default:
190 break;
191 }
192
193 return std::make_pair(MemoryOffsetKind::Unknown, 0);
194}
195
196bool RISCVPreAllocZilsdOptImpl::canFormLdSdPair(MachineInstr *MI0,
197 MachineInstr *MI1) {
198 if (!MI0->hasOneMemOperand() || !MI1->hasOneMemOperand())
199 return false;
200
201 // Get offsets and check they are consecutive
202 int Offset0 = getMemoryOpOffset(*MI0).second;
203 int Offset1 = getMemoryOpOffset(*MI1).second;
204
205 // Offsets must be 4 bytes apart
206 if (Offset1 - Offset0 != 4)
207 return false;
208
209 // We need to guarantee the alignment(base + offset) is legal.
210 const MachineMemOperand *MMO = *MI0->memoperands_begin();
211 if (MMO->getAlign() < RequiredAlign)
212 return false;
213
214 // Check that the two destination/source registers are different for
215 // load/store respectively.
216 if (MI0->getOperand(0).getReg() == MI1->getOperand(0).getReg())
217 return false;
218
219 return true;
220}
221
222bool RISCVPreAllocZilsdOptImpl::isSafeToMove(MachineInstr *MI,
223 MachineInstr *Target,
224 bool MoveForward) {
225 MachineBasicBlock *MBB = MI->getParent();
226 MachineBasicBlock::iterator Start = MI->getIterator();
227 MachineBasicBlock::iterator End = Target->getIterator();
228
229 if (!MoveForward)
230 std::swap(Start, End);
231
232 // Increment Start to skip the current instruction
233 if (Start != MBB->end())
234 ++Start;
235
236 Register DefReg = MI->getOperand(0).getReg();
237 const MachineOperand &BaseOp = MI->getOperand(1);
238
239 unsigned ScanCount = 0;
240 for (auto It = Start; It != End; ++It, ++ScanCount) {
241 // Don't move across calls or terminators
242 if (It->isCall() || It->isTerminator()) {
243 LLVM_DEBUG(dbgs() << "Cannot move across call/terminator: " << *It);
244 return false;
245 }
246
247 // Don't move across instructions that modify memory barrier
248 if (It->hasUnmodeledSideEffects()) {
249 LLVM_DEBUG(dbgs() << "Cannot move across instruction with side effects: "
250 << *It);
251 return false;
252 }
253
254 // Check if the base register is modified
255 if (BaseOp.isReg() && It->modifiesRegister(BaseOp.getReg(), TRI)) {
256 LLVM_DEBUG(dbgs() << "Base register " << BaseOp.getReg()
257 << " modified by: " << *It);
258 return false;
259 }
260
261 // For loads, check if the loaded value is used
262 if (MI->mayLoad() &&
263 (It->readsRegister(DefReg, TRI) || It->modifiesRegister(DefReg, TRI))) {
264 LLVM_DEBUG(dbgs() << "Destination register " << DefReg
265 << " used by: " << *It);
266 return false;
267 }
268
269 // For stores, check if the stored register is modified
270 if (MI->mayStore() && It->modifiesRegister(DefReg, TRI)) {
271 LLVM_DEBUG(dbgs() << "Source register " << DefReg
272 << " modified by: " << *It);
273 return false;
274 }
275
276 // Check for memory operation interference
277 if (It->mayLoadOrStore() && It->mayAlias(AA, *MI, /*UseTBAA*/ false)) {
278 LLVM_DEBUG(dbgs() << "Memory operation interference detected\n");
279 return false;
280 }
281 }
282
283 return true;
284}
285
286bool RISCVPreAllocZilsdOptImpl::rescheduleOps(
287 MachineBasicBlock *MBB, SmallVectorImpl<MachineInstr *> &MIs,
288 BaseRegInfo Base, bool IsLoad,
289 DenseMap<MachineInstr *, unsigned> &MI2LocMap) {
290 // Sort by offset, at this point it ensure base reg and MemoryOffsetKind are
291 // same, so we just need to simply sort by offset value.
292 llvm::sort(MIs.begin(), MIs.end(), [this](MachineInstr *A, MachineInstr *B) {
293 return getMemoryOpOffset(*A).second < getMemoryOpOffset(*B).second;
294 });
295
296 bool Modified = false;
297
298 // Try to pair consecutive operations
299 for (size_t i = 0; i + 1 < MIs.size(); i++) {
300 MachineInstr *MI0 = MIs[i];
301 MachineInstr *MI1 = MIs[i + 1];
302
303 Register FirstReg = MI0->getOperand(0).getReg();
304 Register SecondReg = MI1->getOperand(0).getReg();
305 const MachineOperand &BaseOp = MI0->getOperand(1);
306 const MachineOperand &OffsetOp = MI0->getOperand(2);
307 assert((BaseOp.isReg() || BaseOp.isFI()) &&
308 "Base register should be register or frame index");
309
310 // At this point, MI0 and MI1 are:
311 // 1. both either LW or SW.
312 // 2. guaranteed to have same memory kind.
313 // 3. guaranteed to have same base register.
314 // 4. already be sorted by offset value.
315 // so we don't have to check these in canFormLdSdPair.
316 if (!canFormLdSdPair(MI0, MI1))
317 continue;
318
319 // Use MI2LocMap to determine which instruction appears later in program
320 // order
321 bool MI1IsLater = MI2LocMap[MI1] > MI2LocMap[MI0];
322
323 // For loads: move later instruction up (backwards) to earlier instruction
324 // For stores: move earlier instruction down (forwards) to later instruction
325 MachineInstr *MoveInstr, *TargetInstr;
326 if (IsLoad) {
327 // For loads: move the later instruction to the earlier one
328 MoveInstr = MI1IsLater ? MI1 : MI0;
329 TargetInstr = MI1IsLater ? MI0 : MI1;
330 } else {
331 // For stores: move the earlier instruction to the later one
332 MoveInstr = MI1IsLater ? MI0 : MI1;
333 TargetInstr = MI1IsLater ? MI1 : MI0;
334 }
335
336 unsigned Distance = MI1IsLater ? MI2LocMap[MI1] - MI2LocMap[MI0]
337 : MI2LocMap[MI0] - MI2LocMap[MI1];
338 if (!isSafeToMove(MoveInstr, TargetInstr, !IsLoad) ||
339 Distance > STI->getCLOpts().zilsd_max_reschedule_distance)
340 continue;
341
342 // Move the instruction to the target position
343 MachineBasicBlock::iterator InsertPos = TargetInstr->getIterator();
344 ++InsertPos;
345
346 // If we need to move an instruction, do it now
347 if (MoveInstr != TargetInstr)
348 MBB->splice(InsertPos, MBB, MoveInstr->getIterator());
349
350 // Create the paired instruction
351 MachineInstrBuilder MIB;
352 DebugLoc DL = MI0->getDebugLoc();
353
354 if (IsLoad) {
355 MIB = BuildMI(*MBB, InsertPos, DL, TII->get(RISCV::PseudoLD_RV32_OPT))
356 .addDef(FirstReg)
357 .addDef(SecondReg);
358 ++NumLDFormed;
359 LLVM_DEBUG(dbgs() << "Formed LD: " << *MIB << "\n");
360 } else {
361 MIB = BuildMI(*MBB, InsertPos, DL, TII->get(RISCV::PseudoSD_RV32_OPT))
362 .addReg(FirstReg)
363 .addReg(SecondReg);
364 ++NumSDFormed;
365 LLVM_DEBUG(dbgs() << "Formed SD: " << *MIB << "\n");
366 }
367
368 if (BaseOp.isReg())
369 MIB = MIB.addReg(BaseOp.getReg());
370 else
371 MIB = MIB.addFrameIndex(BaseOp.getIndex());
372 MIB = MIB.add(OffsetOp);
373
374 // Copy memory operands
375 MIB.cloneMergedMemRefs({MI0, MI1});
376
377 // Add register allocation hints for consecutive registers
378 // RISC-V Zilsd requires even/odd register pairs
379 // Only set hints for virtual registers (physical registers already have
380 // encoding)
381 if (FirstReg.isVirtual() && SecondReg.isVirtual()) {
382 // For virtual registers, we can't determine even/odd yet, but we can hint
383 // that they should be allocated as a consecutive pair
384 MRI->setRegAllocationHint(FirstReg, RISCVRI::RegPairEven, SecondReg);
385 MRI->setRegAllocationHint(SecondReg, RISCVRI::RegPairOdd, FirstReg);
386 }
387
388 // Remove the original instructions
389 MI0->eraseFromParent();
390 MI1->eraseFromParent();
391
392 Modified = true;
393
394 // Skip the next instruction since we've already processed it
395 i++;
396 }
397
398 return Modified;
399}
400
401bool RISCVPreAllocZilsdOptImpl::isMemoryOp(const MachineInstr &MI) {
402 unsigned Opcode = MI.getOpcode();
403 if (Opcode != RISCV::LW && Opcode != RISCV::SW)
404 return false;
405
406 if (!MI.getOperand(1).isReg() && !MI.getOperand(1).isFI())
407 return false;
408
409 // When no memory operands are present, conservatively assume unaligned,
410 // volatile, unfoldable.
411 if (!MI.hasOneMemOperand())
412 return false;
413
414 const MachineMemOperand *MMO = *MI.memoperands_begin();
415
416 if (MMO->isVolatile() || MMO->isAtomic())
417 return false;
418
419 // sw <undef> could probably be eliminated entirely, but for now we just want
420 // to avoid making a mess of it.
421 if (MI.getOperand(0).isReg() && MI.getOperand(0).isUndef())
422 return false;
423
424 // Likewise don't mess with references to undefined addresses.
425 if (MI.getOperand(1).isReg() && MI.getOperand(1).isUndef())
426 return false;
427
428 return true;
429}
430
431bool RISCVPreAllocZilsdOptImpl::rescheduleLoadStoreInstrs(
432 MachineBasicBlock *MBB) {
433 bool Modified = false;
434
435 // Process the basic block in windows delimited by calls, terminators,
436 // or instructions with duplicate base+offset pairs
439
440 while (MBBI != E) {
441 // Map from instruction to its location in the current window
442 DenseMap<MachineInstr *, unsigned> MI2LocMap;
443
444 // Map from base register to list of load/store instructions
445 using Base2InstMap = DenseMap<BaseRegInfo, SmallVector<MachineInstr *, 4>>;
446 using BaseVec = SmallVector<BaseRegInfo, 4>;
447 Base2InstMap Base2LdsMap;
448 Base2InstMap Base2StsMap;
449 BaseVec LdBases;
450 BaseVec StBases;
451
452 unsigned Loc = 0;
453
454 // Build the current window of instructions
455 for (; MBBI != E; ++MBBI) {
456 MachineInstr &MI = *MBBI;
457
458 // Stop at barriers (calls and terminators)
459 if (MI.isCall() || MI.isTerminator()) {
460 // Move past the barrier for next iteration
461 ++MBBI;
462 break;
463 }
464
465 // Track instruction location in window
466 if (!MI.isDebugInstr())
467 MI2LocMap[&MI] = ++Loc;
468
469 MemOffset Offset = getMemoryOpOffset(MI);
470 // Skip non-memory operations or it's not a valid memory offset kind.
471 if (!isMemoryOp(MI) || Offset.first == MemoryOffsetKind::Unknown)
472 continue;
473
474 bool IsLd = (MI.getOpcode() == RISCV::LW);
475 const MachineOperand &BaseOp = MI.getOperand(1);
476 unsigned Base;
477 if (BaseOp.isReg())
478 Base = BaseOp.getReg().id();
479 else
480 Base = BaseOp.getIndex();
481 bool StopHere = false;
482
483 // Lambda to find or add base register entries
484 auto FindBases = [&](Base2InstMap &Base2Ops, BaseVec &Bases) {
485 auto [BI, Inserted] = Base2Ops.try_emplace({Base, Offset.first});
486 if (Inserted) {
487 // First time seeing this base register
488 BI->second.push_back(&MI);
489 Bases.push_back({Base, Offset.first});
490 return;
491 }
492 // Check if we've seen this exact base+offset before
493 if (any_of(BI->second, [&](const MachineInstr *PrevMI) {
494 return Offset == getMemoryOpOffset(*PrevMI);
495 })) {
496 // Found duplicate base+offset - stop here to process current window
497 StopHere = true;
498 } else {
499 BI->second.push_back(&MI);
500 }
501 };
502
503 if (IsLd)
504 FindBases(Base2LdsMap, LdBases);
505 else
506 FindBases(Base2StsMap, StBases);
507
508 if (StopHere) {
509 // Found a duplicate (a base+offset combination that's seen earlier).
510 // Backtrack to process the current window.
511 --Loc;
512 break;
513 }
514 }
515
516 // Process the current window - reschedule loads
517 for (auto Base : LdBases) {
518 SmallVectorImpl<MachineInstr *> &Lds = Base2LdsMap[Base];
519 if (Lds.size() > 1) {
520 Modified |= rescheduleOps(MBB, Lds, Base, true, MI2LocMap);
521 }
522 }
523
524 // Process the current window - reschedule stores
525 for (auto Base : StBases) {
526 SmallVectorImpl<MachineInstr *> &Sts = Base2StsMap[Base];
527 if (Sts.size() > 1) {
528 Modified |= rescheduleOps(MBB, Sts, Base, false, MI2LocMap);
529 }
530 }
531 }
532
533 return Modified;
534}
535
536//===----------------------------------------------------------------------===//
537// Pass creation functions
538//===----------------------------------------------------------------------===//
539
541 return new RISCVPreAllocZilsdOptLegacy();
542}
543
544bool RISCVPreAllocZilsdOptLegacy::runOnMachineFunction(MachineFunction &MF) {
545 if (skipFunction(MF.getFunction()))
546 return false;
547 RISCVPreAllocZilsdOptImpl Impl;
548 return Impl.runOnMachineFunction(
549 MF, [&]() { return &getAnalysis<AAResultsWrapperPass>().getAAResults(); },
550 [&]() {
551 return &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
552 });
553}
554
555PreservedAnalyses
558 RISCVPreAllocZilsdOptImpl Impl;
559 bool Changed = Impl.runOnMachineFunction(
560 MF,
561 [&]() {
563 .getManager()
564 .getResult<AAManager>(MF.getFunction());
565 },
566 [&]() { return &MFAM.getResult<MachineDominatorTreeAnalysis>(MF); });
570}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t Imm
static bool isMemoryOp(const MachineInstr &MI)
Returns true if instruction is a memory operation that this pass is capable of operating on.
static int getMemoryOpOffset(const MachineInstr &MI)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
if(PassOpts->AAPipeline)
#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
MachineRegisterInfo & MRI
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
static bool isSafeToMove(const MachineOperand *Def, const MachineOperand *Use, const MachineInstr *Insert, const WebAssemblyFunctionInfo &MFI, const MachineRegisterInfo &MRI, bool Optimize)
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:280
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
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.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & cloneMergedMemRefs(ArrayRef< const MachineInstr * > OtherMIs) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool isAtomic() const
Returns true if this operation has an atomic ordering requirement of unordered or higher,...
LLVM_ABI Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
void setRegAllocationHint(Register VReg, unsigned Type, Register PrefReg)
setRegAllocationHint - Specify a register allocation hint for the specified virtual register.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
const RISCVOptions & getCLOpts() const
const RISCVRegisterInfo * getRegisterInfo() const override
Align getZilsdAlign() const
const RISCVInstrInfo * getInstrInfo() const override
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
constexpr unsigned id() const
Definition Register.h:100
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
Definition ilist_node.h:123
Pass manager infrastructure for declaring and invalidating analyses.
Abstract Attribute helper functions.
Definition Attributor.h:164
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Unknown
Not known to have no common set bits.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ Global
Append to llvm.global_dtors.
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
FunctionPass * createRISCVPreAllocZilsdOptLegacyPass()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880