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