LLVM 23.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
68private:
69 /// contains the location where CSR register is saved.
70 class CSRSavedLocation {
71 public:
72 enum Kind { Invalid, Register, CFAOffset };
73 Kind K = Invalid;
74
75 private:
76 union {
77 // Dwarf register number
78 unsigned Reg;
79 // CFA offset
80 int64_t Offset;
81 };
82
83 public:
84 CSRSavedLocation() {}
85
86 static CSRSavedLocation createCFAOffset(int64_t Offset) {
87 CSRSavedLocation Loc;
88 Loc.K = Kind::CFAOffset;
89 Loc.Offset = Offset;
90 return Loc;
91 }
92
93 static CSRSavedLocation createRegister(unsigned Reg) {
94 CSRSavedLocation Loc;
95 Loc.K = Kind::Register;
96 Loc.Reg = Reg;
97 return Loc;
98 }
99
100 bool isValid() const { return K != Kind::Invalid; }
101
102 unsigned getRegister() const {
103 assert(K == Kind::Register);
104 return Reg;
105 }
106
107 int64_t getOffset() const {
108 assert(K == Kind::CFAOffset);
109 return Offset;
110 }
111
112 bool operator==(const CSRSavedLocation &RHS) const {
113 if (K != RHS.K)
114 return false;
115 switch (K) {
116 case Kind::Invalid:
117 return true;
118 case Kind::Register:
119 return getRegister() == RHS.getRegister();
120 case Kind::CFAOffset:
121 return getOffset() == RHS.getOffset();
122 }
123 llvm_unreachable("Unknown CSRSavedLocation Kind!");
124 }
125 bool operator!=(const CSRSavedLocation &RHS) const {
126 return !(*this == RHS);
127 }
128 void dump(raw_ostream &OS) const {
129 switch (K) {
130 case Kind::Invalid:
131 OS << "Invalid";
132 break;
133 case Kind::Register:
134 OS << "In Dwarf register: " << Reg;
135 break;
136 case Kind::CFAOffset:
137 OS << "At CFA offset: " << Offset;
138 break;
139 }
140 }
141 };
142
143 struct MBBCFAInfo {
144 MachineBasicBlock *MBB;
145 /// Value of cfa offset valid at basic block entry.
146 int64_t IncomingCFAOffset = -1;
147 /// Value of cfa offset valid at basic block exit.
148 int64_t OutgoingCFAOffset = -1;
149 /// Value of cfa register valid at basic block entry.
150 unsigned IncomingCFARegister = 0;
151 /// Value of cfa register valid at basic block exit.
152 unsigned OutgoingCFARegister = 0;
153 /// Set of callee saved registers saved at basic block entry.
154 BitVector IncomingCSRSaved;
155 /// Set of callee saved registers saved at basic block exit.
156 BitVector OutgoingCSRSaved;
157 /// If in/out cfa offset and register values for this block have already
158 /// been set or not.
159 bool Processed = false;
160 };
161
162 /// Contains cfa offset and register values valid at entry and exit of basic
163 /// blocks.
164 std::vector<MBBCFAInfo> MBBVector;
165
166 /// Map the callee save registers to the locations where they are saved.
167 SmallDenseMap<unsigned, CSRSavedLocation, 16> CSRLocMap;
168
169 /// Calculate cfa offset and register values valid at entry and exit for all
170 /// basic blocks in a function.
171 void calculateCFAInfo(MachineFunction &MF);
172 /// Calculate cfa offset and register values valid at basic block exit by
173 /// checking the block for CFI instructions. Block's incoming CFA info remains
174 /// the same.
175 void calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo);
176 /// Update in/out cfa offset and register values for successors of the basic
177 /// block.
178 void updateSuccCFAInfo(MBBCFAInfo &MBBInfo);
179
180 /// Check if incoming CFA information of a basic block matches outgoing CFA
181 /// information of the previous block. If it doesn't, insert CFI instruction
182 /// at the beginning of the block that corrects the CFA calculation rule for
183 /// that block.
184 bool insertCFIInstrs(MachineFunction &MF);
185 /// Return the cfa offset value that should be set at the beginning of a MBB
186 /// if needed. The negated value is needed when creating CFI instructions that
187 /// set absolute offset.
188 int64_t getCorrectCFAOffset(MachineBasicBlock *MBB) {
189 return MBBVector[MBB->getNumber()].IncomingCFAOffset;
190 }
191
192 void reportCFAError(const MBBCFAInfo &Pred, const MBBCFAInfo &Succ);
193 void reportCSRError(const MBBCFAInfo &Pred, const MBBCFAInfo &Succ);
194 /// Go through each MBB in a function and check that outgoing offset and
195 /// register of its predecessors match incoming offset and register of that
196 /// MBB, as well as that incoming offset and register of its successors match
197 /// outgoing offset and register of the MBB.
198 unsigned verify(MachineFunction &MF);
199};
200} // namespace
201
202char CFIInstrInserter::ID = 0;
203INITIALIZE_PASS(CFIInstrInserter, "cfi-instr-inserter",
204 "Check CFA info and insert CFI instructions if needed", false,
205 false)
206FunctionPass *llvm::createCFIInstrInserter() { return new CFIInstrInserter(); }
207
208void CFIInstrInserter::calculateCFAInfo(MachineFunction &MF) {
209 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
210 // Initial CFA offset value i.e. the one valid at the beginning of the
211 // function.
212 int InitialOffset =
214 // Initial CFA register value i.e. the one valid at the beginning of the
215 // function.
216 Register InitialRegister =
218 unsigned DwarfInitialRegister = TRI.getDwarfRegNum(InitialRegister, true);
219 unsigned NumRegs = TRI.getNumSupportedRegs(MF);
220
221 // Initialize MBBMap.
222 for (MachineBasicBlock &MBB : MF) {
223 MBBCFAInfo &MBBInfo = MBBVector[MBB.getNumber()];
224 MBBInfo.MBB = &MBB;
225 MBBInfo.IncomingCFAOffset = InitialOffset;
226 MBBInfo.OutgoingCFAOffset = InitialOffset;
227 MBBInfo.IncomingCFARegister = DwarfInitialRegister;
228 MBBInfo.OutgoingCFARegister = DwarfInitialRegister;
229 MBBInfo.IncomingCSRSaved.resize(NumRegs);
230 MBBInfo.OutgoingCSRSaved.resize(NumRegs);
231 }
232 CSRLocMap.clear();
233
234 // Set in/out cfa info for all blocks in the function. This traversal is based
235 // on the assumption that the first block in the function is the entry block
236 // i.e. that it has initial cfa offset and register values as incoming CFA
237 // information.
238 updateSuccCFAInfo(MBBVector[MF.front().getNumber()]);
239}
240
241void CFIInstrInserter::calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo) {
242 // Outgoing cfa offset set by the block.
243 int64_t SetOffset = MBBInfo.IncomingCFAOffset;
244 // Outgoing cfa register set by the block.
245 unsigned SetRegister = MBBInfo.IncomingCFARegister;
246 MachineFunction *MF = MBBInfo.MBB->getParent();
247 const std::vector<MCCFIInstruction> &Instrs = MF->getFrameInstructions();
248 const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo();
249 unsigned NumRegs = TRI.getNumSupportedRegs(*MF);
250 BitVector CSRSaved(NumRegs), CSRRestored(NumRegs);
251
252#ifndef NDEBUG
253 int RememberState = 0;
254#endif
255
256 // Determine cfa offset and register set by the block.
257 for (MachineInstr &MI : *MBBInfo.MBB) {
258 if (MI.isCFIInstruction()) {
259 std::optional<unsigned> CSRReg;
260 std::optional<int64_t> CSROffset;
261 unsigned CFIIndex = MI.getOperand(0).getCFIIndex();
262 const MCCFIInstruction &CFI = Instrs[CFIIndex];
263 switch (CFI.getOperation()) {
265 SetRegister = CFI.getRegister();
266 break;
268 SetOffset = CFI.getOffset();
269 break;
271 SetOffset += CFI.getOffset();
272 break;
274 SetRegister = CFI.getRegister();
275 SetOffset = CFI.getOffset();
276 break;
278 CSROffset = CFI.getOffset();
279 break;
281 CSRReg = CFI.getRegister2();
282 break;
284 CSROffset = CFI.getOffset() - SetOffset;
285 break;
287 CSRRestored.set(CFI.getRegister());
288 break;
290 // TODO: Add support for handling cfi_def_aspace_cfa.
291#ifndef NDEBUG
293 "Support for cfi_llvm_def_aspace_cfa not implemented! Value of CFA "
294 "may be incorrect!\n");
295#endif
296 break;
298 // TODO: Add support for handling cfi_remember_state.
299#ifndef NDEBUG
300 // Currently we need cfi_remember_state and cfi_restore_state to be in
301 // the same BB, so it will not impact outgoing CFA.
302 ++RememberState;
303 if (RememberState != 1)
305 SMLoc(),
306 "Support for cfi_remember_state not implemented! Value of CFA "
307 "may be incorrect!\n");
308#endif
309 break;
311 // TODO: Add support for handling cfi_restore_state.
312#ifndef NDEBUG
313 --RememberState;
314 if (RememberState != 0)
316 SMLoc(),
317 "Support for cfi_restore_state not implemented! Value of CFA may "
318 "be incorrect!\n");
319#endif
320 break;
321 // Other CFI directives do not affect CFA value.
331 break;
332 }
333 assert((!CSRReg.has_value() || !CSROffset.has_value()) &&
334 "A register can only be at an offset from CFA or in another "
335 "register, but not both!");
336 CSRSavedLocation CSRLoc;
337 if (CSRReg)
338 CSRLoc = CSRSavedLocation::createRegister(*CSRReg);
339 else if (CSROffset)
340 CSRLoc = CSRSavedLocation::createCFAOffset(*CSROffset);
341 if (CSRLoc.isValid()) {
342 auto [It, Inserted] = CSRLocMap.insert({CFI.getRegister(), CSRLoc});
343 if (!Inserted && It->second != CSRLoc)
345 "Different saved locations for the same CSR");
346 CSRSaved.set(CFI.getRegister());
347 }
348 }
349 }
350
351#ifndef NDEBUG
352 if (RememberState != 0)
354 SMLoc(),
355 "Support for cfi_remember_state not implemented! Value of CFA may be "
356 "incorrect!\n");
357#endif
358
359 MBBInfo.Processed = true;
360
361 // Update outgoing CFA info.
362 MBBInfo.OutgoingCFAOffset = SetOffset;
363 MBBInfo.OutgoingCFARegister = SetRegister;
364
365 // Update outgoing CSR info.
366 BitVector::apply([](auto x, auto y, auto z) { return (x | y) & ~z; },
367 MBBInfo.OutgoingCSRSaved, MBBInfo.IncomingCSRSaved, CSRSaved,
368 CSRRestored);
369}
370
371void CFIInstrInserter::updateSuccCFAInfo(MBBCFAInfo &MBBInfo) {
372 SmallVector<MachineBasicBlock *, 4> Stack;
373 Stack.push_back(MBBInfo.MBB);
374
375 do {
376 MachineBasicBlock *Current = Stack.pop_back_val();
377 MBBCFAInfo &CurrentInfo = MBBVector[Current->getNumber()];
378 calculateOutgoingCFAInfo(CurrentInfo);
379 for (auto *Succ : CurrentInfo.MBB->successors()) {
380 MBBCFAInfo &SuccInfo = MBBVector[Succ->getNumber()];
381 if (!SuccInfo.Processed) {
382 SuccInfo.IncomingCFAOffset = CurrentInfo.OutgoingCFAOffset;
383 SuccInfo.IncomingCFARegister = CurrentInfo.OutgoingCFARegister;
384 SuccInfo.IncomingCSRSaved = CurrentInfo.OutgoingCSRSaved;
385 Stack.push_back(Succ);
386 }
387 }
388 } while (!Stack.empty());
389}
390
391bool CFIInstrInserter::insertCFIInstrs(MachineFunction &MF) {
392 const MBBCFAInfo *PrevMBBInfo = &MBBVector[MF.front().getNumber()];
393 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
394 bool InsertedCFIInstr = false;
395
396 BitVector SetDifference;
397 for (MachineBasicBlock &MBB : MF) {
398 // Skip the first MBB in a function
399 if (MBB.getNumber() == MF.front().getNumber()) continue;
400
401 const MBBCFAInfo &MBBInfo = MBBVector[MBB.getNumber()];
402 auto MBBI = MBBInfo.MBB->begin();
403 DebugLoc DL = MBBInfo.MBB->findDebugLoc(MBBI);
404
405 // If the current MBB will be placed in a unique section, a full DefCfa
406 // must be emitted.
407 const bool ForceFullCFA = MBB.isBeginSection();
408
409 if ((PrevMBBInfo->OutgoingCFAOffset != MBBInfo.IncomingCFAOffset &&
410 PrevMBBInfo->OutgoingCFARegister != MBBInfo.IncomingCFARegister) ||
411 ForceFullCFA) {
412 // If both outgoing offset and register of a previous block don't match
413 // incoming offset and register of this block, or if this block begins a
414 // section, add a def_cfa instruction with the correct offset and
415 // register for this block.
416 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
417 nullptr, MBBInfo.IncomingCFARegister, getCorrectCFAOffset(&MBB)));
418 BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
419 .addCFIIndex(CFIIndex);
420 InsertedCFIInstr = true;
421 } else if (PrevMBBInfo->OutgoingCFAOffset != MBBInfo.IncomingCFAOffset) {
422 // If outgoing offset of a previous block doesn't match incoming offset
423 // of this block, add a def_cfa_offset instruction with the correct
424 // offset for this block.
425 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(
426 nullptr, getCorrectCFAOffset(&MBB)));
427 BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
428 .addCFIIndex(CFIIndex);
429 InsertedCFIInstr = true;
430 } else if (PrevMBBInfo->OutgoingCFARegister !=
431 MBBInfo.IncomingCFARegister) {
432 unsigned CFIIndex =
434 nullptr, MBBInfo.IncomingCFARegister));
435 BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
436 .addCFIIndex(CFIIndex);
437 InsertedCFIInstr = true;
438 }
439
440 if (ForceFullCFA) {
441 MF.getSubtarget().getFrameLowering()->emitCalleeSavedFrameMovesFullCFA(
442 *MBBInfo.MBB, MBBI);
443 InsertedCFIInstr = true;
444 PrevMBBInfo = &MBBInfo;
445 continue;
446 }
447
448 BitVector::apply([](auto x, auto y) { return x & ~y; }, SetDifference,
449 PrevMBBInfo->OutgoingCSRSaved, MBBInfo.IncomingCSRSaved);
450 for (int Reg : SetDifference.set_bits()) {
451 unsigned CFIIndex =
452 MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg));
453 BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
454 .addCFIIndex(CFIIndex);
455 InsertedCFIInstr = true;
456 }
457
458 BitVector::apply([](auto x, auto y) { return x & ~y; }, SetDifference,
459 MBBInfo.IncomingCSRSaved, PrevMBBInfo->OutgoingCSRSaved);
460 for (int Reg : SetDifference.set_bits()) {
461 auto it = CSRLocMap.find(Reg);
462 assert(it != CSRLocMap.end() && "Reg should have an entry in CSRLocMap");
463 unsigned CFIIndex;
464 CSRSavedLocation RO = it->second;
465 switch (RO.K) {
466 case CSRSavedLocation::CFAOffset: {
467 CFIIndex = MF.addFrameInst(
468 MCCFIInstruction::createOffset(nullptr, Reg, RO.getOffset()));
469 break;
470 }
471 case CSRSavedLocation::Register: {
472 CFIIndex = MF.addFrameInst(
473 MCCFIInstruction::createRegister(nullptr, Reg, RO.getRegister()));
474 break;
475 }
476 default:
477 llvm_unreachable("Invalid CSRSavedLocation!");
478 }
479 BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
480 .addCFIIndex(CFIIndex);
481 InsertedCFIInstr = true;
482 }
483
484 PrevMBBInfo = &MBBInfo;
485 }
486 return InsertedCFIInstr;
487}
488
489void CFIInstrInserter::reportCFAError(const MBBCFAInfo &Pred,
490 const MBBCFAInfo &Succ) {
491 errs() << "*** Inconsistent CFA register and/or offset between pred and succ "
492 "***\n";
493 errs() << "Pred: " << Pred.MBB->getName() << " #" << Pred.MBB->getNumber()
494 << " in " << Pred.MBB->getParent()->getName()
495 << " outgoing CFA Reg:" << Pred.OutgoingCFARegister << "\n";
496 errs() << "Pred: " << Pred.MBB->getName() << " #" << Pred.MBB->getNumber()
497 << " in " << Pred.MBB->getParent()->getName()
498 << " outgoing CFA Offset:" << Pred.OutgoingCFAOffset << "\n";
499 errs() << "Succ: " << Succ.MBB->getName() << " #" << Succ.MBB->getNumber()
500 << " incoming CFA Reg:" << Succ.IncomingCFARegister << "\n";
501 errs() << "Succ: " << Succ.MBB->getName() << " #" << Succ.MBB->getNumber()
502 << " incoming CFA Offset:" << Succ.IncomingCFAOffset << "\n";
503}
504
505void CFIInstrInserter::reportCSRError(const MBBCFAInfo &Pred,
506 const MBBCFAInfo &Succ) {
507 errs() << "*** Inconsistent CSR Saved between pred and succ in function "
508 << Pred.MBB->getParent()->getName() << " ***\n";
509 errs() << "Pred: " << Pred.MBB->getName() << " #" << Pred.MBB->getNumber()
510 << " outgoing CSR Saved: ";
511 for (int Reg : Pred.OutgoingCSRSaved.set_bits())
512 errs() << Reg << " ";
513 errs() << "\n";
514 errs() << "Succ: " << Succ.MBB->getName() << " #" << Succ.MBB->getNumber()
515 << " incoming CSR Saved: ";
516 for (int Reg : Succ.IncomingCSRSaved.set_bits())
517 errs() << Reg << " ";
518 errs() << "\n";
519}
520
521unsigned CFIInstrInserter::verify(MachineFunction &MF) {
522 unsigned ErrorNum = 0;
523 for (auto *CurrMBB : depth_first(&MF)) {
524 const MBBCFAInfo &CurrMBBInfo = MBBVector[CurrMBB->getNumber()];
525 for (MachineBasicBlock *Succ : CurrMBB->successors()) {
526 const MBBCFAInfo &SuccMBBInfo = MBBVector[Succ->getNumber()];
527 // Check that incoming offset and register values of successors match the
528 // outgoing offset and register values of CurrMBB
529 if (SuccMBBInfo.IncomingCFAOffset != CurrMBBInfo.OutgoingCFAOffset ||
530 SuccMBBInfo.IncomingCFARegister != CurrMBBInfo.OutgoingCFARegister) {
531 // Inconsistent offsets/registers are ok for 'noreturn' blocks because
532 // we don't generate epilogues inside such blocks.
533 if (SuccMBBInfo.MBB->succ_empty() && !SuccMBBInfo.MBB->isReturnBlock())
534 continue;
535 reportCFAError(CurrMBBInfo, SuccMBBInfo);
536 ErrorNum++;
537 }
538 // Check that IncomingCSRSaved of every successor matches the
539 // OutgoingCSRSaved of CurrMBB
540 if (SuccMBBInfo.IncomingCSRSaved != CurrMBBInfo.OutgoingCSRSaved) {
541 reportCSRError(CurrMBBInfo, SuccMBBInfo);
542 ErrorNum++;
543 }
544 }
545 }
546 return ErrorNum;
547}
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...
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
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
@ 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:2122
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:173
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:163
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.