CFIInstrInserter.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  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. #include "llvm/ADT/DepthFirstIterator.h"
  20. #include "llvm/CodeGen/MachineFunctionPass.h"
  21. #include "llvm/CodeGen/MachineInstrBuilder.h"
  22. #include "llvm/CodeGen/Passes.h"
  23. #include "llvm/CodeGen/TargetFrameLowering.h"
  24. #include "llvm/CodeGen/TargetInstrInfo.h"
  25. #include "llvm/CodeGen/TargetSubtargetInfo.h"
  26. #include "llvm/InitializePasses.h"
  27. #include "llvm/MC/MCDwarf.h"
  28. using namespace llvm;
  29. static cl::opt<bool> VerifyCFI("verify-cfiinstrs",
  30. cl::desc("Verify Call Frame Information instructions"),
  31. cl::init(false),
  32. cl::Hidden);
  33. namespace {
  34. class CFIInstrInserter : public MachineFunctionPass {
  35. public:
  36. static char ID;
  37. CFIInstrInserter() : MachineFunctionPass(ID) {
  38. initializeCFIInstrInserterPass(*PassRegistry::getPassRegistry());
  39. }
  40. void getAnalysisUsage(AnalysisUsage &AU) const override {
  41. AU.setPreservesAll();
  42. MachineFunctionPass::getAnalysisUsage(AU);
  43. }
  44. bool runOnMachineFunction(MachineFunction &MF) override {
  45. if (!MF.needsFrameMoves())
  46. return false;
  47. MBBVector.resize(MF.getNumBlockIDs());
  48. calculateCFAInfo(MF);
  49. if (VerifyCFI) {
  50. if (unsigned ErrorNum = verify(MF))
  51. report_fatal_error("Found " + Twine(ErrorNum) +
  52. " in/out CFI information errors.");
  53. }
  54. bool insertedCFI = insertCFIInstrs(MF);
  55. MBBVector.clear();
  56. return insertedCFI;
  57. }
  58. private:
  59. struct MBBCFAInfo {
  60. MachineBasicBlock *MBB;
  61. /// Value of cfa offset valid at basic block entry.
  62. int IncomingCFAOffset = -1;
  63. /// Value of cfa offset valid at basic block exit.
  64. int OutgoingCFAOffset = -1;
  65. /// Value of cfa register valid at basic block entry.
  66. unsigned IncomingCFARegister = 0;
  67. /// Value of cfa register valid at basic block exit.
  68. unsigned OutgoingCFARegister = 0;
  69. /// Set of callee saved registers saved at basic block entry.
  70. BitVector IncomingCSRSaved;
  71. /// Set of callee saved registers saved at basic block exit.
  72. BitVector OutgoingCSRSaved;
  73. /// If in/out cfa offset and register values for this block have already
  74. /// been set or not.
  75. bool Processed = false;
  76. };
  77. #define INVALID_REG UINT_MAX
  78. #define INVALID_OFFSET INT_MAX
  79. /// contains the location where CSR register is saved.
  80. struct CSRSavedLocation {
  81. CSRSavedLocation(std::optional<unsigned> R, std::optional<int> O)
  82. : Reg(R), Offset(O) {}
  83. std::optional<unsigned> Reg;
  84. std::optional<int> Offset;
  85. };
  86. /// Contains cfa offset and register values valid at entry and exit of basic
  87. /// blocks.
  88. std::vector<MBBCFAInfo> MBBVector;
  89. /// Map the callee save registers to the locations where they are saved.
  90. SmallDenseMap<unsigned, CSRSavedLocation, 16> CSRLocMap;
  91. /// Calculate cfa offset and register values valid at entry and exit for all
  92. /// basic blocks in a function.
  93. void calculateCFAInfo(MachineFunction &MF);
  94. /// Calculate cfa offset and register values valid at basic block exit by
  95. /// checking the block for CFI instructions. Block's incoming CFA info remains
  96. /// the same.
  97. void calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo);
  98. /// Update in/out cfa offset and register values for successors of the basic
  99. /// block.
  100. void updateSuccCFAInfo(MBBCFAInfo &MBBInfo);
  101. /// Check if incoming CFA information of a basic block matches outgoing CFA
  102. /// information of the previous block. If it doesn't, insert CFI instruction
  103. /// at the beginning of the block that corrects the CFA calculation rule for
  104. /// that block.
  105. bool insertCFIInstrs(MachineFunction &MF);
  106. /// Return the cfa offset value that should be set at the beginning of a MBB
  107. /// if needed. The negated value is needed when creating CFI instructions that
  108. /// set absolute offset.
  109. int getCorrectCFAOffset(MachineBasicBlock *MBB) {
  110. return MBBVector[MBB->getNumber()].IncomingCFAOffset;
  111. }
  112. void reportCFAError(const MBBCFAInfo &Pred, const MBBCFAInfo &Succ);
  113. void reportCSRError(const MBBCFAInfo &Pred, const MBBCFAInfo &Succ);
  114. /// Go through each MBB in a function and check that outgoing offset and
  115. /// register of its predecessors match incoming offset and register of that
  116. /// MBB, as well as that incoming offset and register of its successors match
  117. /// outgoing offset and register of the MBB.
  118. unsigned verify(MachineFunction &MF);
  119. };
  120. } // namespace
  121. char CFIInstrInserter::ID = 0;
  122. INITIALIZE_PASS(CFIInstrInserter, "cfi-instr-inserter",
  123. "Check CFA info and insert CFI instructions if needed", false,
  124. false)
  125. FunctionPass *llvm::createCFIInstrInserter() { return new CFIInstrInserter(); }
  126. void CFIInstrInserter::calculateCFAInfo(MachineFunction &MF) {
  127. // Initial CFA offset value i.e. the one valid at the beginning of the
  128. // function.
  129. int InitialOffset =
  130. MF.getSubtarget().getFrameLowering()->getInitialCFAOffset(MF);
  131. // Initial CFA register value i.e. the one valid at the beginning of the
  132. // function.
  133. Register InitialRegister =
  134. MF.getSubtarget().getFrameLowering()->getInitialCFARegister(MF);
  135. const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
  136. unsigned NumRegs = TRI.getNumRegs();
  137. // Initialize MBBMap.
  138. for (MachineBasicBlock &MBB : MF) {
  139. MBBCFAInfo &MBBInfo = MBBVector[MBB.getNumber()];
  140. MBBInfo.MBB = &MBB;
  141. MBBInfo.IncomingCFAOffset = InitialOffset;
  142. MBBInfo.OutgoingCFAOffset = InitialOffset;
  143. MBBInfo.IncomingCFARegister = InitialRegister;
  144. MBBInfo.OutgoingCFARegister = InitialRegister;
  145. MBBInfo.IncomingCSRSaved.resize(NumRegs);
  146. MBBInfo.OutgoingCSRSaved.resize(NumRegs);
  147. }
  148. CSRLocMap.clear();
  149. // Set in/out cfa info for all blocks in the function. This traversal is based
  150. // on the assumption that the first block in the function is the entry block
  151. // i.e. that it has initial cfa offset and register values as incoming CFA
  152. // information.
  153. updateSuccCFAInfo(MBBVector[MF.front().getNumber()]);
  154. }
  155. void CFIInstrInserter::calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo) {
  156. // Outgoing cfa offset set by the block.
  157. int SetOffset = MBBInfo.IncomingCFAOffset;
  158. // Outgoing cfa register set by the block.
  159. unsigned SetRegister = MBBInfo.IncomingCFARegister;
  160. MachineFunction *MF = MBBInfo.MBB->getParent();
  161. const std::vector<MCCFIInstruction> &Instrs = MF->getFrameInstructions();
  162. const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo();
  163. unsigned NumRegs = TRI.getNumRegs();
  164. BitVector CSRSaved(NumRegs), CSRRestored(NumRegs);
  165. // Determine cfa offset and register set by the block.
  166. for (MachineInstr &MI : *MBBInfo.MBB) {
  167. if (MI.isCFIInstruction()) {
  168. std::optional<unsigned> CSRReg;
  169. std::optional<int> CSROffset;
  170. unsigned CFIIndex = MI.getOperand(0).getCFIIndex();
  171. const MCCFIInstruction &CFI = Instrs[CFIIndex];
  172. switch (CFI.getOperation()) {
  173. case MCCFIInstruction::OpDefCfaRegister:
  174. SetRegister = CFI.getRegister();
  175. break;
  176. case MCCFIInstruction::OpDefCfaOffset:
  177. SetOffset = CFI.getOffset();
  178. break;
  179. case MCCFIInstruction::OpAdjustCfaOffset:
  180. SetOffset += CFI.getOffset();
  181. break;
  182. case MCCFIInstruction::OpDefCfa:
  183. SetRegister = CFI.getRegister();
  184. SetOffset = CFI.getOffset();
  185. break;
  186. case MCCFIInstruction::OpOffset:
  187. CSROffset = CFI.getOffset();
  188. break;
  189. case MCCFIInstruction::OpRegister:
  190. CSRReg = CFI.getRegister2();
  191. break;
  192. case MCCFIInstruction::OpRelOffset:
  193. CSROffset = CFI.getOffset() - SetOffset;
  194. break;
  195. case MCCFIInstruction::OpRestore:
  196. CSRRestored.set(CFI.getRegister());
  197. break;
  198. case MCCFIInstruction::OpLLVMDefAspaceCfa:
  199. // TODO: Add support for handling cfi_def_aspace_cfa.
  200. #ifndef NDEBUG
  201. report_fatal_error(
  202. "Support for cfi_llvm_def_aspace_cfa not implemented! Value of CFA "
  203. "may be incorrect!\n");
  204. #endif
  205. break;
  206. case MCCFIInstruction::OpRememberState:
  207. // TODO: Add support for handling cfi_remember_state.
  208. #ifndef NDEBUG
  209. report_fatal_error(
  210. "Support for cfi_remember_state not implemented! Value of CFA "
  211. "may be incorrect!\n");
  212. #endif
  213. break;
  214. case MCCFIInstruction::OpRestoreState:
  215. // TODO: Add support for handling cfi_restore_state.
  216. #ifndef NDEBUG
  217. report_fatal_error(
  218. "Support for cfi_restore_state not implemented! Value of CFA may "
  219. "be incorrect!\n");
  220. #endif
  221. break;
  222. // Other CFI directives do not affect CFA value.
  223. case MCCFIInstruction::OpUndefined:
  224. case MCCFIInstruction::OpSameValue:
  225. case MCCFIInstruction::OpEscape:
  226. case MCCFIInstruction::OpWindowSave:
  227. case MCCFIInstruction::OpNegateRAState:
  228. case MCCFIInstruction::OpGnuArgsSize:
  229. break;
  230. }
  231. if (CSRReg || CSROffset) {
  232. auto It = CSRLocMap.find(CFI.getRegister());
  233. if (It == CSRLocMap.end()) {
  234. CSRLocMap.insert(
  235. {CFI.getRegister(), CSRSavedLocation(CSRReg, CSROffset)});
  236. } else if (It->second.Reg != CSRReg || It->second.Offset != CSROffset) {
  237. llvm_unreachable("Different saved locations for the same CSR");
  238. }
  239. CSRSaved.set(CFI.getRegister());
  240. }
  241. }
  242. }
  243. MBBInfo.Processed = true;
  244. // Update outgoing CFA info.
  245. MBBInfo.OutgoingCFAOffset = SetOffset;
  246. MBBInfo.OutgoingCFARegister = SetRegister;
  247. // Update outgoing CSR info.
  248. BitVector::apply([](auto x, auto y, auto z) { return (x | y) & ~z; },
  249. MBBInfo.OutgoingCSRSaved, MBBInfo.IncomingCSRSaved, CSRSaved,
  250. CSRRestored);
  251. }
  252. void CFIInstrInserter::updateSuccCFAInfo(MBBCFAInfo &MBBInfo) {
  253. SmallVector<MachineBasicBlock *, 4> Stack;
  254. Stack.push_back(MBBInfo.MBB);
  255. do {
  256. MachineBasicBlock *Current = Stack.pop_back_val();
  257. MBBCFAInfo &CurrentInfo = MBBVector[Current->getNumber()];
  258. calculateOutgoingCFAInfo(CurrentInfo);
  259. for (auto *Succ : CurrentInfo.MBB->successors()) {
  260. MBBCFAInfo &SuccInfo = MBBVector[Succ->getNumber()];
  261. if (!SuccInfo.Processed) {
  262. SuccInfo.IncomingCFAOffset = CurrentInfo.OutgoingCFAOffset;
  263. SuccInfo.IncomingCFARegister = CurrentInfo.OutgoingCFARegister;
  264. SuccInfo.IncomingCSRSaved = CurrentInfo.OutgoingCSRSaved;
  265. Stack.push_back(Succ);
  266. }
  267. }
  268. } while (!Stack.empty());
  269. }
  270. bool CFIInstrInserter::insertCFIInstrs(MachineFunction &MF) {
  271. const MBBCFAInfo *PrevMBBInfo = &MBBVector[MF.front().getNumber()];
  272. const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
  273. bool InsertedCFIInstr = false;
  274. BitVector SetDifference;
  275. for (MachineBasicBlock &MBB : MF) {
  276. // Skip the first MBB in a function
  277. if (MBB.getNumber() == MF.front().getNumber()) continue;
  278. const MBBCFAInfo &MBBInfo = MBBVector[MBB.getNumber()];
  279. auto MBBI = MBBInfo.MBB->begin();
  280. DebugLoc DL = MBBInfo.MBB->findDebugLoc(MBBI);
  281. // If the current MBB will be placed in a unique section, a full DefCfa
  282. // must be emitted.
  283. const bool ForceFullCFA = MBB.isBeginSection();
  284. if ((PrevMBBInfo->OutgoingCFAOffset != MBBInfo.IncomingCFAOffset &&
  285. PrevMBBInfo->OutgoingCFARegister != MBBInfo.IncomingCFARegister) ||
  286. ForceFullCFA) {
  287. // If both outgoing offset and register of a previous block don't match
  288. // incoming offset and register of this block, or if this block begins a
  289. // section, add a def_cfa instruction with the correct offset and
  290. // register for this block.
  291. unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
  292. nullptr, MBBInfo.IncomingCFARegister, getCorrectCFAOffset(&MBB)));
  293. BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
  294. .addCFIIndex(CFIIndex);
  295. InsertedCFIInstr = true;
  296. } else if (PrevMBBInfo->OutgoingCFAOffset != MBBInfo.IncomingCFAOffset) {
  297. // If outgoing offset of a previous block doesn't match incoming offset
  298. // of this block, add a def_cfa_offset instruction with the correct
  299. // offset for this block.
  300. unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(
  301. nullptr, getCorrectCFAOffset(&MBB)));
  302. BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
  303. .addCFIIndex(CFIIndex);
  304. InsertedCFIInstr = true;
  305. } else if (PrevMBBInfo->OutgoingCFARegister !=
  306. MBBInfo.IncomingCFARegister) {
  307. unsigned CFIIndex =
  308. MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(
  309. nullptr, MBBInfo.IncomingCFARegister));
  310. BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
  311. .addCFIIndex(CFIIndex);
  312. InsertedCFIInstr = true;
  313. }
  314. if (ForceFullCFA) {
  315. MF.getSubtarget().getFrameLowering()->emitCalleeSavedFrameMovesFullCFA(
  316. *MBBInfo.MBB, MBBI);
  317. InsertedCFIInstr = true;
  318. PrevMBBInfo = &MBBInfo;
  319. continue;
  320. }
  321. BitVector::apply([](auto x, auto y) { return x & ~y; }, SetDifference,
  322. PrevMBBInfo->OutgoingCSRSaved, MBBInfo.IncomingCSRSaved);
  323. for (int Reg : SetDifference.set_bits()) {
  324. unsigned CFIIndex =
  325. MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg));
  326. BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
  327. .addCFIIndex(CFIIndex);
  328. InsertedCFIInstr = true;
  329. }
  330. BitVector::apply([](auto x, auto y) { return x & ~y; }, SetDifference,
  331. MBBInfo.IncomingCSRSaved, PrevMBBInfo->OutgoingCSRSaved);
  332. for (int Reg : SetDifference.set_bits()) {
  333. auto it = CSRLocMap.find(Reg);
  334. assert(it != CSRLocMap.end() && "Reg should have an entry in CSRLocMap");
  335. unsigned CFIIndex;
  336. CSRSavedLocation RO = it->second;
  337. if (!RO.Reg && RO.Offset) {
  338. CFIIndex = MF.addFrameInst(
  339. MCCFIInstruction::createOffset(nullptr, Reg, *RO.Offset));
  340. } else if (RO.Reg && !RO.Offset) {
  341. CFIIndex = MF.addFrameInst(
  342. MCCFIInstruction::createRegister(nullptr, Reg, *RO.Reg));
  343. } else {
  344. llvm_unreachable("RO.Reg and RO.Offset cannot both be valid/invalid");
  345. }
  346. BuildMI(*MBBInfo.MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
  347. .addCFIIndex(CFIIndex);
  348. InsertedCFIInstr = true;
  349. }
  350. PrevMBBInfo = &MBBInfo;
  351. }
  352. return InsertedCFIInstr;
  353. }
  354. void CFIInstrInserter::reportCFAError(const MBBCFAInfo &Pred,
  355. const MBBCFAInfo &Succ) {
  356. errs() << "*** Inconsistent CFA register and/or offset between pred and succ "
  357. "***\n";
  358. errs() << "Pred: " << Pred.MBB->getName() << " #" << Pred.MBB->getNumber()
  359. << " in " << Pred.MBB->getParent()->getName()
  360. << " outgoing CFA Reg:" << Pred.OutgoingCFARegister << "\n";
  361. errs() << "Pred: " << Pred.MBB->getName() << " #" << Pred.MBB->getNumber()
  362. << " in " << Pred.MBB->getParent()->getName()
  363. << " outgoing CFA Offset:" << Pred.OutgoingCFAOffset << "\n";
  364. errs() << "Succ: " << Succ.MBB->getName() << " #" << Succ.MBB->getNumber()
  365. << " incoming CFA Reg:" << Succ.IncomingCFARegister << "\n";
  366. errs() << "Succ: " << Succ.MBB->getName() << " #" << Succ.MBB->getNumber()
  367. << " incoming CFA Offset:" << Succ.IncomingCFAOffset << "\n";
  368. }
  369. void CFIInstrInserter::reportCSRError(const MBBCFAInfo &Pred,
  370. const MBBCFAInfo &Succ) {
  371. errs() << "*** Inconsistent CSR Saved between pred and succ in function "
  372. << Pred.MBB->getParent()->getName() << " ***\n";
  373. errs() << "Pred: " << Pred.MBB->getName() << " #" << Pred.MBB->getNumber()
  374. << " outgoing CSR Saved: ";
  375. for (int Reg : Pred.OutgoingCSRSaved.set_bits())
  376. errs() << Reg << " ";
  377. errs() << "\n";
  378. errs() << "Succ: " << Succ.MBB->getName() << " #" << Succ.MBB->getNumber()
  379. << " incoming CSR Saved: ";
  380. for (int Reg : Succ.IncomingCSRSaved.set_bits())
  381. errs() << Reg << " ";
  382. errs() << "\n";
  383. }
  384. unsigned CFIInstrInserter::verify(MachineFunction &MF) {
  385. unsigned ErrorNum = 0;
  386. for (auto *CurrMBB : depth_first(&MF)) {
  387. const MBBCFAInfo &CurrMBBInfo = MBBVector[CurrMBB->getNumber()];
  388. for (MachineBasicBlock *Succ : CurrMBB->successors()) {
  389. const MBBCFAInfo &SuccMBBInfo = MBBVector[Succ->getNumber()];
  390. // Check that incoming offset and register values of successors match the
  391. // outgoing offset and register values of CurrMBB
  392. if (SuccMBBInfo.IncomingCFAOffset != CurrMBBInfo.OutgoingCFAOffset ||
  393. SuccMBBInfo.IncomingCFARegister != CurrMBBInfo.OutgoingCFARegister) {
  394. // Inconsistent offsets/registers are ok for 'noreturn' blocks because
  395. // we don't generate epilogues inside such blocks.
  396. if (SuccMBBInfo.MBB->succ_empty() && !SuccMBBInfo.MBB->isReturnBlock())
  397. continue;
  398. reportCFAError(CurrMBBInfo, SuccMBBInfo);
  399. ErrorNum++;
  400. }
  401. // Check that IncomingCSRSaved of every successor matches the
  402. // OutgoingCSRSaved of CurrMBB
  403. if (SuccMBBInfo.IncomingCSRSaved != CurrMBBInfo.OutgoingCSRSaved) {
  404. reportCSRError(CurrMBBInfo, SuccMBBInfo);
  405. ErrorNum++;
  406. }
  407. }
  408. }
  409. return ErrorNum;
  410. }