1 //===- MachineDebugify.cpp - Attach synthetic debug info to everything ----===// 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 attaches synthetic debug info to everything. It can be used 10 /// to create targeted tests for debug info preservation. 11 /// 12 /// This isn't intended to have feature parity with Debugify. 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/CodeGen/MachineFunctionPass.h" 16 #include "llvm/CodeGen/MachineModuleInfo.h" 17 #include "llvm/CodeGen/Passes.h" 18 #include "llvm/IR/DIBuilder.h" 19 #include "llvm/IR/DebugInfo.h" 20 #include "llvm/InitializePasses.h" 21 #include "llvm/Transforms/Utils/Debugify.h" 22 23 #define DEBUG_TYPE "mir-debugify" 24 25 using namespace llvm; 26 27 namespace { 28 bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI, 29 DIBuilder &DIB, Function &F) { 30 MachineFunction *MaybeMF = MMI.getMachineFunction(F); 31 if (!MaybeMF) 32 return false; 33 MachineFunction &MF = *MaybeMF; 34 35 DISubprogram *SP = F.getSubprogram(); 36 assert(SP && "IR Debugify just created it?"); 37 38 LLVMContext &Ctx = F.getParent()->getContext(); 39 unsigned NextLine = SP->getLine(); 40 41 for (MachineBasicBlock &MBB : MF) { 42 for (MachineInstr &MI : MBB) { 43 // This will likely emit line numbers beyond the end of the imagined 44 // source function and into subsequent ones. We don't do anything about 45 // that as it doesn't really matter to the compiler where the line is in 46 // the imaginary source code. 47 MI.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP)); 48 } 49 } 50 51 return true; 52 } 53 54 /// ModulePass for attaching synthetic debug info to everything, used with the 55 /// legacy module pass manager. 56 struct DebugifyMachineModule : public ModulePass { 57 bool runOnModule(Module &M) override { 58 MachineModuleInfo &MMI = 59 getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 60 return applyDebugifyMetadata( 61 M, M.functions(), 62 "ModuleDebugify: ", [&](DIBuilder &DIB, Function &F) -> bool { 63 return applyDebugifyMetadataToMachineFunction(MMI, DIB, F); 64 }); 65 } 66 67 DebugifyMachineModule() : ModulePass(ID) {} 68 69 void getAnalysisUsage(AnalysisUsage &AU) const override { 70 AU.addRequired<MachineModuleInfoWrapperPass>(); 71 AU.addPreserved<MachineModuleInfoWrapperPass>(); 72 AU.setPreservesCFG(); 73 } 74 75 static char ID; // Pass identification. 76 }; 77 char DebugifyMachineModule::ID = 0; 78 79 } // end anonymous namespace 80 81 INITIALIZE_PASS_BEGIN(DebugifyMachineModule, DEBUG_TYPE, 82 "Machine Debugify Module", false, false) 83 INITIALIZE_PASS_END(DebugifyMachineModule, DEBUG_TYPE, 84 "Machine Debugify Module", false, false) 85 86 ModulePass *llvm::createDebugifyMachineModulePass() { 87 return new DebugifyMachineModule(); 88 } 89