11adeeabbSDaniel Sanders //===- MachineDebugify.cpp - Attach synthetic debug info to everything ----===//
21adeeabbSDaniel Sanders //
31adeeabbSDaniel Sanders // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41adeeabbSDaniel Sanders // See https://llvm.org/LICENSE.txt for license information.
51adeeabbSDaniel Sanders // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61adeeabbSDaniel Sanders //
71adeeabbSDaniel Sanders //===----------------------------------------------------------------------===//
81adeeabbSDaniel Sanders ///
91adeeabbSDaniel Sanders /// \file This pass attaches synthetic debug info to everything. It can be used
101adeeabbSDaniel Sanders /// to create targeted tests for debug info preservation.
111adeeabbSDaniel Sanders ///
121adeeabbSDaniel Sanders /// This isn't intended to have feature parity with Debugify.
131adeeabbSDaniel Sanders //===----------------------------------------------------------------------===//
141adeeabbSDaniel Sanders 
151adeeabbSDaniel Sanders #include "llvm/CodeGen/MachineFunctionPass.h"
161adeeabbSDaniel Sanders #include "llvm/CodeGen/MachineModuleInfo.h"
171adeeabbSDaniel Sanders #include "llvm/CodeGen/Passes.h"
181adeeabbSDaniel Sanders #include "llvm/IR/DIBuilder.h"
191adeeabbSDaniel Sanders #include "llvm/IR/DebugInfo.h"
201adeeabbSDaniel Sanders #include "llvm/InitializePasses.h"
211adeeabbSDaniel Sanders #include "llvm/Transforms/Utils/Debugify.h"
221adeeabbSDaniel Sanders 
231adeeabbSDaniel Sanders #define DEBUG_TYPE "mir-debugify"
241adeeabbSDaniel Sanders 
251adeeabbSDaniel Sanders using namespace llvm;
261adeeabbSDaniel Sanders 
271adeeabbSDaniel Sanders namespace {
281adeeabbSDaniel Sanders bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI,
291adeeabbSDaniel Sanders                                             DIBuilder &DIB, Function &F) {
30*14ad8dc0SDaniel Sanders   MachineFunction *MaybeMF = MMI.getMachineFunction(F);
31*14ad8dc0SDaniel Sanders   if (!MaybeMF)
32*14ad8dc0SDaniel Sanders     return false;
33*14ad8dc0SDaniel Sanders   MachineFunction &MF = *MaybeMF;
341adeeabbSDaniel Sanders 
351adeeabbSDaniel Sanders   DISubprogram *SP = F.getSubprogram();
361adeeabbSDaniel Sanders   assert(SP && "IR Debugify just created it?");
371adeeabbSDaniel Sanders 
381adeeabbSDaniel Sanders   LLVMContext &Ctx = F.getParent()->getContext();
391adeeabbSDaniel Sanders   unsigned NextLine = SP->getLine();
401adeeabbSDaniel Sanders 
411adeeabbSDaniel Sanders   for (MachineBasicBlock &MBB : MF) {
421adeeabbSDaniel Sanders     for (MachineInstr &MI : MBB) {
431adeeabbSDaniel Sanders       // This will likely emit line numbers beyond the end of the imagined
441adeeabbSDaniel Sanders       // source function and into subsequent ones. We don't do anything about
451adeeabbSDaniel Sanders       // that as it doesn't really matter to the compiler where the line is in
461adeeabbSDaniel Sanders       // the imaginary source code.
471adeeabbSDaniel Sanders       MI.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP));
481adeeabbSDaniel Sanders     }
491adeeabbSDaniel Sanders   }
501adeeabbSDaniel Sanders 
511adeeabbSDaniel Sanders   return true;
521adeeabbSDaniel Sanders }
531adeeabbSDaniel Sanders 
541adeeabbSDaniel Sanders /// ModulePass for attaching synthetic debug info to everything, used with the
551adeeabbSDaniel Sanders /// legacy module pass manager.
561adeeabbSDaniel Sanders struct DebugifyMachineModule : public ModulePass {
571adeeabbSDaniel Sanders   bool runOnModule(Module &M) override {
581adeeabbSDaniel Sanders     MachineModuleInfo &MMI =
591adeeabbSDaniel Sanders         getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
601adeeabbSDaniel Sanders     return applyDebugifyMetadata(
611adeeabbSDaniel Sanders         M, M.functions(),
621adeeabbSDaniel Sanders         "ModuleDebugify: ", [&](DIBuilder &DIB, Function &F) -> bool {
631adeeabbSDaniel Sanders           return applyDebugifyMetadataToMachineFunction(MMI, DIB, F);
641adeeabbSDaniel Sanders         });
651adeeabbSDaniel Sanders   }
661adeeabbSDaniel Sanders 
671adeeabbSDaniel Sanders   DebugifyMachineModule() : ModulePass(ID) {}
681adeeabbSDaniel Sanders 
691adeeabbSDaniel Sanders   void getAnalysisUsage(AnalysisUsage &AU) const override {
701adeeabbSDaniel Sanders     AU.addRequired<MachineModuleInfoWrapperPass>();
711adeeabbSDaniel Sanders     AU.addPreserved<MachineModuleInfoWrapperPass>();
72f71350f0SDaniel Sanders     AU.setPreservesCFG();
731adeeabbSDaniel Sanders   }
741adeeabbSDaniel Sanders 
751adeeabbSDaniel Sanders   static char ID; // Pass identification.
761adeeabbSDaniel Sanders };
771adeeabbSDaniel Sanders char DebugifyMachineModule::ID = 0;
781adeeabbSDaniel Sanders 
791adeeabbSDaniel Sanders } // end anonymous namespace
801adeeabbSDaniel Sanders 
811adeeabbSDaniel Sanders INITIALIZE_PASS_BEGIN(DebugifyMachineModule, DEBUG_TYPE,
821adeeabbSDaniel Sanders                       "Machine Debugify Module", false, false)
831adeeabbSDaniel Sanders INITIALIZE_PASS_END(DebugifyMachineModule, DEBUG_TYPE,
841adeeabbSDaniel Sanders                     "Machine Debugify Module", false, false)
851adeeabbSDaniel Sanders 
86f71350f0SDaniel Sanders ModulePass *llvm::createDebugifyMachineModulePass() {
871adeeabbSDaniel Sanders   return new DebugifyMachineModule();
881adeeabbSDaniel Sanders }
89