CFIInstrInserter.cpp 18 KB

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