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 &MF = MMI.getOrCreateMachineFunction(F); 31 32 DISubprogram *SP = F.getSubprogram(); 33 assert(SP && "IR Debugify just created it?"); 34 35 LLVMContext &Ctx = F.getParent()->getContext(); 36 unsigned NextLine = SP->getLine(); 37 38 for (MachineBasicBlock &MBB : MF) { 39 for (MachineInstr &MI : MBB) { 40 // This will likely emit line numbers beyond the end of the imagined 41 // source function and into subsequent ones. We don't do anything about 42 // that as it doesn't really matter to the compiler where the line is in 43 // the imaginary source code. 44 MI.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP)); 45 } 46 } 47 48 return true; 49 } 50 51 /// ModulePass for attaching synthetic debug info to everything, used with the 52 /// legacy module pass manager. 53 struct DebugifyMachineModule : public ModulePass { 54 bool runOnModule(Module &M) override { 55 MachineModuleInfo &MMI = 56 getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 57 return applyDebugifyMetadata( 58 M, M.functions(), 59 "ModuleDebugify: ", [&](DIBuilder &DIB, Function &F) -> bool { 60 return applyDebugifyMetadataToMachineFunction(MMI, DIB, F); 61 }); 62 } 63 64 DebugifyMachineModule() : ModulePass(ID) {} 65 66 void getAnalysisUsage(AnalysisUsage &AU) const override { 67 AU.addRequired<MachineModuleInfoWrapperPass>(); 68 AU.addPreserved<MachineModuleInfoWrapperPass>(); 69 } 70 71 static char ID; // Pass identification. 72 }; 73 char DebugifyMachineModule::ID = 0; 74 75 } // end anonymous namespace 76 77 INITIALIZE_PASS_BEGIN(DebugifyMachineModule, DEBUG_TYPE, 78 "Machine Debugify Module", false, false) 79 INITIALIZE_PASS_END(DebugifyMachineModule, DEBUG_TYPE, 80 "Machine Debugify Module", false, false) 81 82 ModulePass *createDebugifyMachineModulePass() { 83 return new DebugifyMachineModule(); 84 } 85