LLVM 22.0.0git
CFIInstrInserter.cpp
Go to the documentation of this file.
1//===------ CFIInstrInserter.cpp - Insert additional CFI instructions -----===//
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 This pass verifies incoming and outgoing CFA information of basic
10/// blocks. CFA information is information about offset and register set by CFI
11/// directives, valid at the start and end of a basic block. This pass checks
12/// that outgoing information of predecessors matches incoming information of
13/// their successors. Then it checks if blocks have correct CFA calculation rule
14/// set and inserts additional CFI instruction at their beginnings if they
15/// don't. CFI instructions are inserted if basic blocks have incorrect offset
16/// or register set by previous blocks, as a result of a non-linear layout of
17/// blocks in a function.
18//===----------------------------------------------------------------------===//
19
23#include "llvm/CodeGen/Passes.h"
28#include "llvm/MC/MCContext.h"
29#include "llvm/MC/MCDwarf.h"
30using namespace llvm;
31
32static cl::opt<bool> VerifyCFI("verify-cfiinstrs",
33 cl::desc("Verify Call Frame Information instructions"),
34 cl::init(false),
36
37namespace {
38class CFIInstrInserter : public MachineFunctionPass {
39 public:
40 static char ID;
41
42 CFIInstrInserter() : MachineFunctionPass(ID) {
44 }
45
46 void getAnalysisUsage(AnalysisUsage &AU) const override {
47 AU.setPreservesAll();
49 }
50
51 bool runOnMachineFunction(MachineFunction &MF) override {
52 if (!MF.needsFrameMoves())
53 return false;
54
55 MBBVector.resize(MF.getNumBlockIDs());
56 calculateCFAInfo(MF);
57
58 if (VerifyCFI) {
59 if (unsigned ErrorNum = verify(MF))
60 report_fatal_error("Found " + Twine(ErrorNum) +
61 " in/out CFI information errors.");
62 }
63 bool insertedCFI = insertCFIInstrs(MF);
64 MBBVector.clear();
65 return insertedCFI;
66 }
67
68 private:
69 struct MBBCFAInfo {
70 MachineBasicBlock *MBB;
71 /// Value of cfa offset valid at basic block entry.
72 int64_t IncomingCFAOffset = -1;
73 /// Value of cfa offset valid at basic block exit.
74 int64_t OutgoingCFAOffset = -1;
75 /// Value of cfa register valid at basic block entry.
76 unsigned IncomingCFARegister = 0;
77 /// Value of cfa register valid at basic block exit.
78 unsigned OutgoingCFARegister = 0;
79 /// Set of callee saved registers saved at basic block entry.
80 BitVector IncomingCSRSaved;
81 /// Set of callee saved registers saved at basic block exit.
82 BitVector OutgoingCSRSaved;
83 /// If in/out cfa offset and register values for this block have already
84 /// been set or not.
85 bool Processed = false;
86 };
87
88#define INVALID_REG UINT_MAX
89#define INVALID_OFFSET INT_MAX
90 /// contains the location where CSR register is saved.
91 class CSRSavedLocation {
92 public:
93 enum Kind { Invalid, Register, CFAOffset };
94 Kind K = Invalid;
95
96 private:
97 union {
98 // Dwarf register number
99 unsigned Reg;
100 // CFA offset
101 int64_t Offset;
102 };
103
104 public:
105 CSRSavedLocation() {}
106
107 static CSRSavedLocation createCFAOffset(int64_t Offset) {
108 CSRSavedLocation Loc;
109 Loc.K = Kind::CFAOffset;
110 Loc.Offset = Offset;
111 return Loc;
112 }
113
114 static CSRSavedLocation createRegister(unsigned Reg) {
115 CSRSavedLocation Loc;
116 Loc.K = Kind::Register;
117 Loc.Reg = Reg;
118 return Loc;
119 }
120
121 bool isValid() const { return K != Kind::Invalid; }
122
123 unsigned getRegister() const {
124 assert(K == Kind::Register);
125 return Reg;
126 }
127
128 int64_t getOffset() const {
129 assert(K == Kind::CFAOffset);
130 return Offset;
131 }
132
133 bool operator==(const CSRSavedLocation &RHS) const {
134 if (K != RHS.K)
135 return false;
136 switch (K) {
137 case Kind::Invalid:
138 return true;
139 case Kind::Register:
140 return getRegister() == RHS.getRegister();
141 case Kind::CFAOffset:
142 return getOffset() == RHS.getOffset();
143 }
144 llvm_unreachable("Unknown CSRSavedLocation Kind!");
145 }
146 bool operator!=(const CSRSavedLocation &RHS) const {
147 return !(*this == RHS);
148 }
149 };
150
151 /// Contains cfa offset and register values valid at entry and exit of basic
152 /// blocks.
153 std::vector<MBBCFAInfo> MBBVector;
154
155 /// Map the callee save registers to the locations where they are saved.
156 SmallDenseMap<unsigned, CSRSavedLocation, 16> CSRLocMap;
157
158 /// Calculate cfa offset and register values valid at entry and exit for all
159 /// basic blocks in a function.
160 void calculateCFAInfo(MachineFunction &MF);
161 /// Calculate cfa offset and register values valid at basic block exit by
162 /// checking the block for CFI instructions. Block's incoming CFA info remains
163 /// the same.
164 void calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo);
165 /// Update in/out cfa offset and register values for successors of the basic
166 /// block.
167 void updateSuccCFAInfo(MBBCFAInfo &MBBInfo);
168
169 /// Check if incoming CFA information of a basic block matches outgoing CFA
170 /// information of the previous block. If it doesn't, insert CFI instruction
171 /// at the beginning of the block that corrects the CFA calculation rule for
172 /// that block.
173 bool insertCFIInstrs(MachineFunction &MF);
174 /// Return the cfa offset value that should be set at the beginning of a MBB
175 /// if needed. The negated value is needed when creating CFI instructions that
176 /// set absolute offset.
177 int64_t getCorrectCFAOffset(MachineBasicBlock *MBB) {
178 return MBBVector[MBB->getNumber()].IncomingCFAOffset;
179 }
180
181 void reportCFAError(const MBBCFAInfo &Pred, const MBBCFAInfo &Succ);
182 void reportCSRError(const MBBCFAInfo &Pred, const MBBCFAInfo &Succ);
183 /// Go through each MBB in a function and check that outgoing offset and
184 /// register of its predecessors match incoming offset and register of that
185 /// MBB, as well as that incoming offset and register of its successors match
186 /// outgoing offset and register of the MBB.
187 unsigned verify(MachineFunction &MF);
188};
189} // namespace
190
191char CFIInstrInserter::ID = 0;
192INITIALIZE_PASS(CFIInstrInserter, "cfi-instr-inserter",
193 "Check CFA info and insert CFI instructions if needed", false,
194 false)
195FunctionPass *llvm::createCFIInstrInserter() { return new CFIInstrInserter(); }
196
197void CFIInstrInserter::calculateCFAInfo(MachineFunction &MF) {
198 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
199 // Initial CFA offset value i.e. the one valid at the beginning of the
200 // function.
201 int InitialOffset =
203 // Initial CFA register value i.e. the one valid at the beginning of the
204 // function.
205 Register InitialRegister =
207 unsigned DwarfInitialRegister = TRI.getDwarfRegNum(InitialRegister, true);
208 unsigned NumRegs = TRI.getNumSupportedRegs(MF);
209
210 // Initialize MBBMap.
211 for (MachineBasicBlock &MBB : MF) {
212 MBBCFAInfo &MBBInfo = MBBVector[MBB.getNumber()];
213 MBBInfo.MBB = &MBB;
214 MBBInfo.IncomingCFAOffset = InitialOffset;
215 MBBInfo.OutgoingCFAOffset = InitialOffset;
216 MBBInfo.IncomingCFARegister = DwarfInitialRegister;
217 MBBInfo.OutgoingCFARegister = DwarfInitialRegister;
218 MBBInfo.IncomingCSRSaved.resize(NumRegs);
219 MBBInfo.OutgoingCSRSaved.resize(NumRegs);
220 }
221 CSRLocMap.clear();
222
223 // Set in/out cfa info for all blocks in the function. This traversal is based
224 // on the assumption that the first block in the function is the entry block
225 // i.e. that it has initial cfa offset and register values as incoming CFA
226 // information.
227 updateSuccCFAInfo(MBBVector[MF.front().getNumber()]);
228}
229
230void CFIInstrInserter::calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo) {
231 // Outgoing cfa offset set by the block.
232 int64_t SetOffset = MBBInfo.IncomingCFAOffset;
233 // Outgoing cfa register set by the block.
234 unsigned SetRegister = MBBInfo.IncomingCFARegister;
235 MachineFunction *MF = MBBInfo.MBB->getParent();
236 const std::vector<MCCFIInstruction> &Instrs = MF->getFrameInstructions();
237 const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo();
238 unsigned NumRegs = TRI.getNumSupportedRegs(*MF);
239 BitVector CSRSaved(NumRegs), CSRRestored(NumRegs);
240
241#ifndef NDEBUG
242 int RememberState = 0;
243#endif
244
245 // Determine cfa offset and register set by the block.
246 for (MachineInstr &MI : *MBBInfo.MBB) {
247 if (MI.isCFIInstruction()) {
248 std::optional<unsigned> CSRReg;
249 std::optional<int64_t> CSROffset;
250 unsigned CFIIndex = MI.getOperand(0).getCFIIndex();
251 const MCCFIInstruction &CFI = Instrs[CFIIndex];
252 switch (CFI.getOperation()) {
254 SetRegister = CFI.getRegister();
255 break;
257 SetOffset = CFI.getOffset();
258 break;
260 SetOffset += CFI.getOffset();
261 break;
263 SetRegister = CFI.getRegister();
264 SetOffset = CFI.getOffset();
265 break;
267 CSROffset = CFI.getOffset();
268 break;
270 CSRReg = CFI.getRegister2();
271 break;
273 CSROffset = CFI.getOffset() - SetOffset;
274 break;
276 CSRRestored.set(CFI.getRegister());
277 break;
279 // TODO: Add support for handling cfi_def_aspace_cfa.
280#ifndef NDEBUG
282 "Support for cfi_llvm_def_aspace_cfa not implemented! Value of CFA "
283 "may be incorrect!\n");
284#endif
285 break;
287 // TODO: Add support for handling cfi_remember_state.
288#ifndef NDEBUG
289 // Currently we need cfi_remember_state and cfi_restore_state to be in
290 // the same BB, so it will not impact outgoing CFA.
291 ++RememberState;
292 if (RememberState != 1)
294 SMLoc(),
295 "Support for cfi_remember_state not implemented! Value of CFA "
296 "may be incorrect!\n");
297#endif
298 break;
300 // TODO: Add support for handling cfi_restore_state.
301#ifndef NDEBUG
302 --RememberState;
303 if (RememberState != 0)
305 SMLoc(),
306 "Support for cfi_restore_state not implemented! Value of CFA may "
307 "be incorrect!\n");
308#endif
309 break;
310 // Other CFI directives do not affect CFA value.
320 break;
321 }
322 assert((!CSRReg.has_value() || !CSROffset.has_value()) &&
323 "A register can only be at an offset from CFA or in another "
324 "register, but not both!");
325 CSRSavedLocation CSRLoc;
326 if (CSRReg)
327 CSRLoc = CSRSavedLocation::createRegister(*CSRReg);
328 else if (CSROffset)
329 CSRLoc = CSRSavedLocation::createCFAOffset(*CSROffset);
330 if (CSRLoc.isValid()) {
331 auto [It, Inserted] = CSRLocMap.insert({CFI.getRegister(), CSRLoc});
332 if (!Inserted && It->second != CSRLoc)
334 "Different saved locations for the same CSR");
335 CSRSaved.set(CFI.getRegister());
336 }
337 }
338 }
339
340#ifndef NDEBUG
341 if (RememberState != 0)
343 SMLoc(),
344 "Support for cfi_remember_state not implemented! Value of CFA may be "
345 "incorrect!\n");
346#endif
347
348 MBBInfo.Processed = true;
349
350 // Update outgoing CFA info.
351 MBBInfo.OutgoingCFAOffset = SetOffset;
352 MBBInfo.OutgoingCFARegister = SetRegister;
353
354 // Update outgoing CSR info.
355 BitVector::apply([](auto x, auto y, auto z) { return (x | y) & ~z; },
356 MBBInfo.OutgoingCSRSaved, MBBInfo.IncomingCSRSaved, CSRSaved,
357 CSRRestored);
358}
359
360void CFIInstrInserter::updateSuccCFAInfo(MBBCFAInfo &MBBInfo) {
361 SmallVector<MachineBasicBlock *, 4> Stack;
362 Stack.push_back(MBBInfo.MBB);
363
364 do {
365 MachineBasicBlock *Current = Stack.pop_back_val();
366 MBBCFAInfo &CurrentInfo = MBBVector[Current->getNumber()];
367 calculateOutgoingCFAInfo(CurrentInfo);
368 for (auto *Succ : CurrentInfo.MBB->successors()) {
369 MBBCFAInfo &SuccInfo = MBBVector[Succ->getNumber()];
370 if (!SuccInfo.Processed) {
371 SuccInfo.IncomingCFAOffset = CurrentInfo.OutgoingCFAOffset;
372 SuccInfo.IncomingCFARegister = CurrentInfo.OutgoingCFARegister;
373 SuccInfo.IncomingCSRSaved = CurrentInfo.OutgoingCSRSaved;
374 Stack.push_back(Succ);
375 }
376 }
377 } while (!Stack.empty());
378}
379
380bool CFIInstrInserter::insertCFIInstrs(MachineFunction &MF) {
381 const MBBCFAInfo *PrevMBBInfo = &MBBVector[MF.front().getNumber()];
382 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
383 bool InsertedCFIInstr = false;
384
385 BitVector SetDifference;
386 for (MachineBasicBlock &MBB : MF) {
387 // Skip the first MBB in a function
388 if (MBB.getNumber() == MF.front().getNumber()) continue;
389
390 const MBBCFAInfo &MBBInfo = MBBVector[MBB.getNumber()];
391 auto MBBI = MBBInfo.MBB->begin();
392 DebugLoc DL = MBBInfo.MBB->findDebugLoc(MBBI);
393
394 // If the current MBB will be placed in a unique section, a full DefCfa
395 // must be emitted.
396 const bool ForceFullCFA = MBB.isBeginSection();
397
398 if ((PrevMBBInfo->OutgoingCFAOffset != MBBInfo.IncomingCFAOffset &&
399 PrevMBBInfo->OutgoingCFARegister != MBBInfo.IncomingCFARegister) ||
400 ForceFullCFA) {
401 // If both outgoing offset and register of a previous block don't match
402 // incoming offset and register of this block, or if this block begins a
403 // section, add a def_cfa instruction with the correct offset and
404 // register for this block.
405 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
406 nullptr, MBBInfo.IncomingCFARegister, getCorrectCFAOffset(&MBB)));
407 BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
408 .addCFIIndex(CFIIndex);
409 InsertedCFIInstr = true;
410 } else if (PrevMBBInfo->OutgoingCFAOffset != MBBInfo.IncomingCFAOffset) {
411 // If outgoing offset of a previous block doesn't match incoming offset
412 // of this block, add a def_cfa_offset instruction with the correct
413 // offset for this block.
414 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(
415 nullptr, getCorrectCFAOffset(&MBB)));
416 BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
417 .addCFIIndex(CFIIndex);
418 InsertedCFIInstr = true;
419 } else if (PrevMBBInfo->OutgoingCFARegister !=
420 MBBInfo.IncomingCFARegister) {
421 unsigned CFIIndex =
423 nullptr, MBBInfo.IncomingCFARegister));
424 BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
425 .addCFIIndex(CFIIndex);
426 InsertedCFIInstr = true;
427 }
428
429 if (ForceFullCFA) {
430 MF.getSubtarget().getFrameLowering()->emitCalleeSavedFrameMovesFullCFA(
431 *MBBInfo.MBB, MBBI);
432 InsertedCFIInstr = true;
433 PrevMBBInfo = &MBBInfo;
434 continue;
435 }
436
437 BitVector::apply([](auto x, auto y) { return x & ~y; }, SetDifference,
438 PrevMBBInfo->OutgoingCSRSaved, MBBInfo.IncomingCSRSaved);
439 for (int Reg : SetDifference.set_bits()) {
440 unsigned CFIIndex =
441 MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg));
442 BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
443 .addCFIIndex(CFIIndex);
444 InsertedCFIInstr = true;
445 }
446
447 BitVector::apply([](auto x, auto y) { return x & ~y; }, SetDifference,
448 MBBInfo.IncomingCSRSaved, PrevMBBInfo->OutgoingCSRSaved);
449 for (int Reg : SetDifference.set_bits()) {
450 auto it = CSRLocMap.find(Reg);
451 assert(it != CSRLocMap.end() && "Reg should have an entry in CSRLocMap");
452 unsigned CFIIndex;
453 CSRSavedLocation RO = it->second;
454 switch (RO.K) {
455 case CSRSavedLocation::CFAOffset: {
456 CFIIndex = MF.addFrameInst(
457 MCCFIInstruction::createOffset(nullptr, Reg, RO.getOffset()));
458 break;
459 }
460 case CSRSavedLocation::Register: {
461 CFIIndex = MF.addFrameInst(
462 MCCFIInstruction::createRegister(nullptr, Reg, RO.getRegister()));
463 break;
464 }
465 default:
466 llvm_unreachable("Invalid CSRSavedLocation!");
467 }
468 BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
469 .addCFIIndex(CFIIndex);
470 InsertedCFIInstr = true;
471 }
472
473 PrevMBBInfo = &MBBInfo;
474 }
475 return InsertedCFIInstr;
476}
477
478void CFIInstrInserter::reportCFAError(const MBBCFAInfo &Pred,
479 const MBBCFAInfo &Succ) {
480 errs() << "*** Inconsistent CFA register and/or offset between pred and succ "
481 "***\n";
482 errs() << "Pred: " << Pred.MBB->getName() << " #" << Pred.MBB->getNumber()
483 << " in " << Pred.MBB->getParent()->getName()
484 << " outgoing CFA Reg:" << Pred.OutgoingCFARegister << "\n";
485 errs() << "Pred: " << Pred.MBB->getName() << " #" << Pred.MBB->getNumber()
486 << " in " << Pred.MBB->getParent()->getName()
487 << " outgoing CFA Offset:" << Pred.OutgoingCFAOffset << "\n";
488 errs() << "Succ: " << Succ.MBB->getName() << " #" << Succ.MBB->getNumber()
489 << " incoming CFA Reg:" << Succ.IncomingCFARegister << "\n";
490 errs() << "Succ: " << Succ.MBB->getName() << " #" << Succ.MBB->getNumber()
491 << " incoming CFA Offset:" << Succ.IncomingCFAOffset << "\n";
492}
493
494void CFIInstrInserter::reportCSRError(const MBBCFAInfo &Pred,
495 const MBBCFAInfo &Succ) {
496 errs() << "*** Inconsistent CSR Saved between pred and succ in function "
497 << Pred.MBB->getParent()->getName() << " ***\n";
498 errs() << "Pred: " << Pred.MBB->getName() << " #" << Pred.MBB->getNumber()
499 << " outgoing CSR Saved: ";
500 for (int Reg : Pred.OutgoingCSRSaved.set_bits())
501 errs() << Reg << " ";
502 errs() << "\n";
503 errs() << "Succ: " << Succ.MBB->getName() << " #" << Succ.MBB->getNumber()
504 << " incoming CSR Saved: ";
505 for (int Reg : Succ.IncomingCSRSaved.set_bits())
506 errs() << Reg << " ";
507 errs() << "\n";
508}
509
510unsigned CFIInstrInserter::verify(MachineFunction &MF) {
511 unsigned ErrorNum = 0;
512 for (auto *CurrMBB : depth_first(&MF)) {
513 const MBBCFAInfo &CurrMBBInfo = MBBVector[CurrMBB->getNumber()];
514 for (MachineBasicBlock *Succ : CurrMBB->successors()) {
515 const MBBCFAInfo &SuccMBBInfo = MBBVector[Succ->getNumber()];
516 // Check that incoming offset and register values of successors match the
517 // outgoing offset and register values of CurrMBB
518 if (SuccMBBInfo.IncomingCFAOffset != CurrMBBInfo.OutgoingCFAOffset ||
519 SuccMBBInfo.IncomingCFARegister != CurrMBBInfo.OutgoingCFARegister) {
520 // Inconsistent offsets/registers are ok for 'noreturn' blocks because
521 // we don't generate epilogues inside such blocks.
522 if (SuccMBBInfo.MBB->succ_empty() && !SuccMBBInfo.MBB->isReturnBlock())
523 continue;
524 reportCFAError(CurrMBBInfo, SuccMBBInfo);
525 ErrorNum++;
526 }
527 // Check that IncomingCSRSaved of every successor matches the
528 // OutgoingCSRSaved of CurrMBB
529 if (SuccMBBInfo.IncomingCSRSaved != CurrMBBInfo.OutgoingCSRSaved) {
530 reportCSRError(CurrMBBInfo, SuccMBBInfo);
531 ErrorNum++;
532 }
533 }
534 }
535 return ErrorNum;
536}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static cl::opt< bool > VerifyCFI("verify-cfiinstrs", cl::desc("Verify Call Frame Information instructions"), cl::init(false), cl::Hidden)
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
ppc ctr loops verify
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
SmallVector< MachineBasicBlock *, 4 > MBBVector
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
Value * RHS
void setPreservesAll()
Set by analyses that do not transform their input at all.
iterator_range< const_set_bits_iterator > set_bits() const
Definition BitVector.h:159
static BitVector & apply(F &&f, BitVector &Out, BitVector const &Arg, ArgTys const &...Args)
Definition BitVector.h:574
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
Definition MCDwarf.h:583
static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_restore says that the rule for Register is now the same as it was at the beginning of the functi...
Definition MCDwarf.h:657
unsigned getRegister2() const
Definition MCDwarf.h:726
unsigned getRegister() const
Definition MCDwarf.h:717
static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1, unsigned Register2, SMLoc Loc={})
.cfi_register Previous value of Register1 is saved in register Register2.
Definition MCDwarf.h:633
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
Definition MCDwarf.h:576
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
Definition MCDwarf.h:618
OpType getOperation() const
Definition MCDwarf.h:714
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
Definition MCDwarf.h:591
int64_t getOffset() const
Definition MCDwarf.h:736
LLVM_ABI void reportError(SMLoc L, const Twine &Msg)
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
bool isBeginSection() const
Returns true if this block begins any section.
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.
const std::vector< MCCFIInstruction > & getFrameInstructions() const
Returns a reference to a list of cfi instructions in the function's prologue.
bool needsFrameMoves() const
True if this function needs frame moves for debug or exceptions.
MCContext & getContext() const
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
const MachineBasicBlock & front() const
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
virtual Register getInitialCFARegister(const MachineFunction &MF) const
Return initial CFA register value i.e.
virtual int getInitialCFAOffset(const MachineFunction &MF) const
Return initial CFA offset value i.e.
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool operator!=(uint64_t V1, const APInt &V2)
Definition APInt.h:2114
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
Definition Error.cpp:177
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
LLVM_ABI void initializeCFIInstrInserterPass(PassRegistry &)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:167
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
MCCFIInstruction createCFAOffset(const TargetRegisterInfo &MRI, unsigned Reg, const StackOffset &OffsetFromDefCFA, std::optional< int64_t > IncomingVGOffsetFromDefCFA)
iterator_range< df_iterator< T > > depth_first(const T &G)
LLVM_ABI FunctionPass * createCFIInstrInserter()
Creates CFI Instruction Inserter pass.