15ffd83dbSDimitry Andric //===- MachineDebugify.cpp - Attach synthetic debug info to everything ----===// 25ffd83dbSDimitry Andric // 35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65ffd83dbSDimitry Andric // 75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 85ffd83dbSDimitry Andric /// 95ffd83dbSDimitry Andric /// \file This pass attaches synthetic debug info to everything. It can be used 105ffd83dbSDimitry Andric /// to create targeted tests for debug info preservation, or test for CodeGen 115ffd83dbSDimitry Andric /// differences with vs. without debug info. 125ffd83dbSDimitry Andric /// 135ffd83dbSDimitry Andric /// This isn't intended to have feature parity with Debugify. 145ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 155ffd83dbSDimitry Andric 165ffd83dbSDimitry Andric #include "llvm/ADT/DenseMap.h" 175ffd83dbSDimitry Andric #include "llvm/ADT/SmallVector.h" 185ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 195ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 205ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 215ffd83dbSDimitry Andric #include "llvm/CodeGen/Passes.h" 225ffd83dbSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 235ffd83dbSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 245ffd83dbSDimitry Andric #include "llvm/IR/DIBuilder.h" 255ffd83dbSDimitry Andric #include "llvm/IR/DebugInfo.h" 265ffd83dbSDimitry Andric #include "llvm/IR/IntrinsicInst.h" 275ffd83dbSDimitry Andric #include "llvm/InitializePasses.h" 285ffd83dbSDimitry Andric #include "llvm/Transforms/Utils/Debugify.h" 295ffd83dbSDimitry Andric 305ffd83dbSDimitry Andric #define DEBUG_TYPE "mir-debugify" 315ffd83dbSDimitry Andric 325ffd83dbSDimitry Andric using namespace llvm; 335ffd83dbSDimitry Andric 345ffd83dbSDimitry Andric namespace { 355ffd83dbSDimitry Andric bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI, 365ffd83dbSDimitry Andric DIBuilder &DIB, Function &F) { 375ffd83dbSDimitry Andric MachineFunction *MaybeMF = MMI.getMachineFunction(F); 385ffd83dbSDimitry Andric if (!MaybeMF) 395ffd83dbSDimitry Andric return false; 405ffd83dbSDimitry Andric MachineFunction &MF = *MaybeMF; 415ffd83dbSDimitry Andric const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 425ffd83dbSDimitry Andric 435ffd83dbSDimitry Andric DISubprogram *SP = F.getSubprogram(); 445ffd83dbSDimitry Andric assert(SP && "IR Debugify just created it?"); 455ffd83dbSDimitry Andric 465ffd83dbSDimitry Andric Module &M = *F.getParent(); 475ffd83dbSDimitry Andric LLVMContext &Ctx = M.getContext(); 485ffd83dbSDimitry Andric 495ffd83dbSDimitry Andric unsigned NextLine = SP->getLine(); 505ffd83dbSDimitry Andric for (MachineBasicBlock &MBB : MF) { 515ffd83dbSDimitry Andric for (MachineInstr &MI : MBB) { 525ffd83dbSDimitry Andric // This will likely emit line numbers beyond the end of the imagined 535ffd83dbSDimitry Andric // source function and into subsequent ones. We don't do anything about 545ffd83dbSDimitry Andric // that as it doesn't really matter to the compiler where the line is in 555ffd83dbSDimitry Andric // the imaginary source code. 565ffd83dbSDimitry Andric MI.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP)); 575ffd83dbSDimitry Andric } 585ffd83dbSDimitry Andric } 595ffd83dbSDimitry Andric 605ffd83dbSDimitry Andric // Find local variables defined by debugify. No attempt is made to match up 615ffd83dbSDimitry Andric // MIR-level regs to the 'correct' IR-level variables: there isn't a simple 625ffd83dbSDimitry Andric // way to do that, and it isn't necessary to find interesting CodeGen bugs. 635ffd83dbSDimitry Andric // Instead, simply keep track of one variable per line. Later, we can insert 645ffd83dbSDimitry Andric // DBG_VALUE insts that point to these local variables. Emitting DBG_VALUEs 655ffd83dbSDimitry Andric // which cover a wide range of lines can help stress the debug info passes: 665ffd83dbSDimitry Andric // if we can't do that, fall back to using the local variable which precedes 675ffd83dbSDimitry Andric // all the others. 685ffd83dbSDimitry Andric Function *DbgValF = M.getFunction("llvm.dbg.value"); 695ffd83dbSDimitry Andric DbgValueInst *EarliestDVI = nullptr; 705ffd83dbSDimitry Andric DenseMap<unsigned, DILocalVariable *> Line2Var; 715ffd83dbSDimitry Andric DIExpression *Expr = nullptr; 725ffd83dbSDimitry Andric if (DbgValF) { 735ffd83dbSDimitry Andric for (const Use &U : DbgValF->uses()) { 745ffd83dbSDimitry Andric auto *DVI = dyn_cast<DbgValueInst>(U.getUser()); 755ffd83dbSDimitry Andric if (!DVI || DVI->getFunction() != &F) 765ffd83dbSDimitry Andric continue; 775ffd83dbSDimitry Andric unsigned Line = DVI->getDebugLoc().getLine(); 785ffd83dbSDimitry Andric assert(Line != 0 && "debugify should not insert line 0 locations"); 795ffd83dbSDimitry Andric Line2Var[Line] = DVI->getVariable(); 805ffd83dbSDimitry Andric if (!EarliestDVI || Line < EarliestDVI->getDebugLoc().getLine()) 815ffd83dbSDimitry Andric EarliestDVI = DVI; 825ffd83dbSDimitry Andric Expr = DVI->getExpression(); 835ffd83dbSDimitry Andric } 845ffd83dbSDimitry Andric } 855ffd83dbSDimitry Andric if (Line2Var.empty()) 865ffd83dbSDimitry Andric return true; 875ffd83dbSDimitry Andric 885ffd83dbSDimitry Andric // Now, try to insert a DBG_VALUE instruction after each real instruction. 895ffd83dbSDimitry Andric // Do this by introducing debug uses of each register definition. If that is 905ffd83dbSDimitry Andric // not possible (e.g. we have a phi or a meta instruction), emit a constant. 915ffd83dbSDimitry Andric uint64_t NextImm = 0; 925ffd83dbSDimitry Andric const MCInstrDesc &DbgValDesc = TII.get(TargetOpcode::DBG_VALUE); 935ffd83dbSDimitry Andric for (MachineBasicBlock &MBB : MF) { 945ffd83dbSDimitry Andric MachineBasicBlock::iterator FirstNonPHIIt = MBB.getFirstNonPHI(); 955ffd83dbSDimitry Andric for (auto I = MBB.begin(), E = MBB.end(); I != E; ) { 965ffd83dbSDimitry Andric MachineInstr &MI = *I; 975ffd83dbSDimitry Andric ++I; 985ffd83dbSDimitry Andric 995ffd83dbSDimitry Andric // `I` may point to a DBG_VALUE created in the previous loop iteration. 1005ffd83dbSDimitry Andric if (MI.isDebugInstr()) 1015ffd83dbSDimitry Andric continue; 1025ffd83dbSDimitry Andric 1035ffd83dbSDimitry Andric // It's not allowed to insert DBG_VALUEs after a terminator. 1045ffd83dbSDimitry Andric if (MI.isTerminator()) 1055ffd83dbSDimitry Andric continue; 1065ffd83dbSDimitry Andric 1075ffd83dbSDimitry Andric // Find a suitable insertion point for the DBG_VALUE. 1085ffd83dbSDimitry Andric auto InsertBeforeIt = MI.isPHI() ? FirstNonPHIIt : I; 1095ffd83dbSDimitry Andric 1105ffd83dbSDimitry Andric // Find a suitable local variable for the DBG_VALUE. 1115ffd83dbSDimitry Andric unsigned Line = MI.getDebugLoc().getLine(); 1125ffd83dbSDimitry Andric if (!Line2Var.count(Line)) 1135ffd83dbSDimitry Andric Line = EarliestDVI->getDebugLoc().getLine(); 1145ffd83dbSDimitry Andric DILocalVariable *LocalVar = Line2Var[Line]; 1155ffd83dbSDimitry Andric assert(LocalVar && "No variable for current line?"); 1165ffd83dbSDimitry Andric 1175ffd83dbSDimitry Andric // Emit DBG_VALUEs for register definitions. 1185ffd83dbSDimitry Andric SmallVector<MachineOperand *, 4> RegDefs; 1195ffd83dbSDimitry Andric for (MachineOperand &MO : MI.operands()) 1205ffd83dbSDimitry Andric if (MO.isReg() && MO.isDef() && MO.getReg()) 1215ffd83dbSDimitry Andric RegDefs.push_back(&MO); 1225ffd83dbSDimitry Andric for (MachineOperand *MO : RegDefs) 1235ffd83dbSDimitry Andric BuildMI(MBB, InsertBeforeIt, MI.getDebugLoc(), DbgValDesc, 1245ffd83dbSDimitry Andric /*IsIndirect=*/false, *MO, LocalVar, Expr); 1255ffd83dbSDimitry Andric 1265ffd83dbSDimitry Andric // OK, failing that, emit a constant DBG_VALUE. 1275ffd83dbSDimitry Andric if (RegDefs.empty()) { 1285ffd83dbSDimitry Andric auto ImmOp = MachineOperand::CreateImm(NextImm++); 1295ffd83dbSDimitry Andric BuildMI(MBB, InsertBeforeIt, MI.getDebugLoc(), DbgValDesc, 1305ffd83dbSDimitry Andric /*IsIndirect=*/false, ImmOp, LocalVar, Expr); 1315ffd83dbSDimitry Andric } 1325ffd83dbSDimitry Andric } 1335ffd83dbSDimitry Andric } 1345ffd83dbSDimitry Andric 1355ffd83dbSDimitry Andric return true; 1365ffd83dbSDimitry Andric } 1375ffd83dbSDimitry Andric 1385ffd83dbSDimitry Andric /// ModulePass for attaching synthetic debug info to everything, used with the 1395ffd83dbSDimitry Andric /// legacy module pass manager. 1405ffd83dbSDimitry Andric struct DebugifyMachineModule : public ModulePass { 1415ffd83dbSDimitry Andric bool runOnModule(Module &M) override { 1425ffd83dbSDimitry Andric MachineModuleInfo &MMI = 1435ffd83dbSDimitry Andric getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); 1445ffd83dbSDimitry Andric return applyDebugifyMetadata( 1455ffd83dbSDimitry Andric M, M.functions(), 1465ffd83dbSDimitry Andric "ModuleDebugify: ", [&](DIBuilder &DIB, Function &F) -> bool { 1475ffd83dbSDimitry Andric return applyDebugifyMetadataToMachineFunction(MMI, DIB, F); 1485ffd83dbSDimitry Andric }); 1495ffd83dbSDimitry Andric } 1505ffd83dbSDimitry Andric 1515ffd83dbSDimitry Andric DebugifyMachineModule() : ModulePass(ID) {} 1525ffd83dbSDimitry Andric 1535ffd83dbSDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 1545ffd83dbSDimitry Andric AU.addRequired<MachineModuleInfoWrapperPass>(); 1555ffd83dbSDimitry Andric AU.addPreserved<MachineModuleInfoWrapperPass>(); 1565ffd83dbSDimitry Andric AU.setPreservesCFG(); 1575ffd83dbSDimitry Andric } 1585ffd83dbSDimitry Andric 1595ffd83dbSDimitry Andric static char ID; // Pass identification. 1605ffd83dbSDimitry Andric }; 1615ffd83dbSDimitry Andric char DebugifyMachineModule::ID = 0; 1625ffd83dbSDimitry Andric 1635ffd83dbSDimitry Andric } // end anonymous namespace 1645ffd83dbSDimitry Andric 1655ffd83dbSDimitry Andric INITIALIZE_PASS_BEGIN(DebugifyMachineModule, DEBUG_TYPE, 1665ffd83dbSDimitry Andric "Machine Debugify Module", false, false) 1675ffd83dbSDimitry Andric INITIALIZE_PASS_END(DebugifyMachineModule, DEBUG_TYPE, 1685ffd83dbSDimitry Andric "Machine Debugify Module", false, false) 1695ffd83dbSDimitry Andric 1705ffd83dbSDimitry Andric ModulePass *llvm::createDebugifyMachineModulePass() { 1715ffd83dbSDimitry Andric return new DebugifyMachineModule(); 1725ffd83dbSDimitry Andric } 173