xref: /aosp_15_r20/external/swiftshader/third_party/llvm-16.0/llvm/lib/CodeGen/MachineCheckDebugify.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1  //===- MachineCheckDebugify.cpp - Check debug info ------------------------===//
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 checks debug info after mir-debugify (+ pass-to-test). Currently
10  /// it simply checks the integrity of line info in DILocation and
11  /// DILocalVariable which mir-debugifiy generated before.
12  //===----------------------------------------------------------------------===//
13  
14  #include "llvm/CodeGen/MachineBasicBlock.h"
15  #include "llvm/CodeGen/MachineFunction.h"
16  #include "llvm/CodeGen/MachineModuleInfo.h"
17  #include "llvm/CodeGen/Passes.h"
18  #include "llvm/IR/Constants.h"
19  #include "llvm/IR/DebugInfoMetadata.h"
20  #include "llvm/InitializePasses.h"
21  #include "llvm/Pass.h"
22  
23  #define DEBUG_TYPE "mir-check-debugify"
24  
25  using namespace llvm;
26  
27  namespace {
28  
29  struct CheckDebugMachineModule : public ModulePass {
runOnModule__anoncc824f760111::CheckDebugMachineModule30    bool runOnModule(Module &M) override {
31      NamedMDNode *NMD = M.getNamedMetadata("llvm.mir.debugify");
32      if (!NMD) {
33        errs() << "WARNING: Please run mir-debugify to generate "
34                  "llvm.mir.debugify metadata first.\n";
35        return false;
36      }
37  
38      MachineModuleInfo &MMI =
39          getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
40  
41      auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
42        return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
43            ->getZExtValue();
44      };
45      assert(NMD->getNumOperands() == 2 &&
46             "llvm.mir.debugify should have exactly 2 operands!");
47      unsigned NumLines = getDebugifyOperand(0);
48      unsigned NumVars = getDebugifyOperand(1);
49      BitVector MissingLines{NumLines, true};
50      BitVector MissingVars{NumVars, true};
51  
52      for (Function &F : M.functions()) {
53        MachineFunction *MF = MMI.getMachineFunction(F);
54        if (!MF)
55          continue;
56        for (MachineBasicBlock &MBB : *MF) {
57          // Find missing lines.
58          // TODO: Avoid meta instructions other than dbg_val.
59          for (MachineInstr &MI : MBB) {
60            if (MI.isDebugValue())
61              continue;
62            const DebugLoc DL = MI.getDebugLoc();
63            if (DL && DL.getLine() != 0) {
64              MissingLines.reset(DL.getLine() - 1);
65              continue;
66            }
67  
68            if (!DL) {
69              errs() << "WARNING: Instruction with empty DebugLoc in function ";
70              errs() << F.getName() << " --";
71              MI.print(errs());
72            }
73          }
74  
75          // Find missing variables.
76          // TODO: Handle DBG_INSTR_REF which is under an experimental option now.
77          for (MachineInstr &MI : MBB) {
78            if (!MI.isDebugValue())
79              continue;
80            const DILocalVariable *LocalVar = MI.getDebugVariable();
81            unsigned Var = ~0U;
82  
83            (void)to_integer(LocalVar->getName(), Var, 10);
84            assert(Var <= NumVars && "Unexpected name for DILocalVariable");
85            MissingVars.reset(Var - 1);
86          }
87        }
88      }
89  
90      bool Fail = false;
91      for (unsigned Idx : MissingLines.set_bits()) {
92        errs() << "WARNING: Missing line " << Idx + 1 << "\n";
93        Fail = true;
94      }
95  
96      for (unsigned Idx : MissingVars.set_bits()) {
97        errs() << "WARNING: Missing variable " << Idx + 1 << "\n";
98        Fail = true;
99      }
100      errs() << "Machine IR debug info check: ";
101      errs() << (Fail ? "FAIL" : "PASS") << "\n";
102  
103      return false;
104    }
105  
CheckDebugMachineModule__anoncc824f760111::CheckDebugMachineModule106    CheckDebugMachineModule() : ModulePass(ID) {}
107  
getAnalysisUsage__anoncc824f760111::CheckDebugMachineModule108    void getAnalysisUsage(AnalysisUsage &AU) const override {
109      AU.addRequired<MachineModuleInfoWrapperPass>();
110      AU.setPreservesAll();
111    }
112  
113    static char ID; // Pass identification.
114  };
115  char CheckDebugMachineModule::ID = 0;
116  
117  } // end anonymous namespace
118  
119  INITIALIZE_PASS_BEGIN(CheckDebugMachineModule, DEBUG_TYPE,
120                        "Machine Check Debug Module", false, false)
121  INITIALIZE_PASS_END(CheckDebugMachineModule, DEBUG_TYPE,
122                      "Machine Check Debug Module", false, false)
123  
createCheckDebugMachineModulePass()124  ModulePass *llvm::createCheckDebugMachineModulePass() {
125    return new CheckDebugMachineModule();
126  }
127