diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineCheckDebugify.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/MachineCheckDebugify.cpp | 127 | 
1 files changed, 127 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MachineCheckDebugify.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MachineCheckDebugify.cpp new file mode 100644 index 000000000000..874f726d2947 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/CodeGen/MachineCheckDebugify.cpp @@ -0,0 +1,127 @@ +//===- MachineCheckDebugify.cpp - Check debug info ------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file This checks debug info after mir-debugify (+ pass-to-test). Currently +/// it simply checks the integrity of line info in DILocation and +/// DILocalVariable which mir-debugifiy generated before. +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/StringExtras.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" + +#define DEBUG_TYPE "mir-check-debugify" + +using namespace llvm; + +namespace { + +struct CheckDebugMachineModule : public ModulePass { +  bool runOnModule(Module &M) override { +    NamedMDNode *NMD = M.getNamedMetadata("llvm.mir.debugify"); +    if (!NMD) { +      errs() << "WARNING: Please run mir-debugify to generate " +                "llvm.mir.debugify metadata first.\n"; +      return false; +    } + +    MachineModuleInfo &MMI = +        getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); + +    auto getDebugifyOperand = [&](unsigned Idx) -> unsigned { +      return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0)) +          ->getZExtValue(); +    }; +    assert(NMD->getNumOperands() == 2 && +           "llvm.mir.debugify should have exactly 2 operands!"); +    unsigned NumLines = getDebugifyOperand(0); +    unsigned NumVars = getDebugifyOperand(1); +    BitVector MissingLines{NumLines, true}; +    BitVector MissingVars{NumVars, true}; + +    for (Function &F : M.functions()) { +      MachineFunction *MF = MMI.getMachineFunction(F); +      if (!MF) +        continue; +      for (MachineBasicBlock &MBB : *MF) { +        // Find missing lines. +        // TODO: Avoid meta instructions other than dbg_val. +        for (MachineInstr &MI : MBB) { +          if (MI.isDebugValue()) +            continue; +          const DebugLoc DL = MI.getDebugLoc(); +          if (DL && DL.getLine() != 0) { +            MissingLines.reset(DL.getLine() - 1); +            continue; +          } + +          if (!DL) { +            errs() << "WARNING: Instruction with empty DebugLoc in function "; +            errs() << F.getName() << " --"; +            MI.print(errs()); +          } +        } + +        // Find missing variables. +        // TODO: Handle DBG_INSTR_REF which is under an experimental option now. +        for (MachineInstr &MI : MBB) { +          if (!MI.isDebugValue()) +            continue; +          const DILocalVariable *LocalVar = MI.getDebugVariable(); +          unsigned Var = ~0U; + +          (void)to_integer(LocalVar->getName(), Var, 10); +          assert(Var <= NumVars && "Unexpected name for DILocalVariable"); +          MissingVars.reset(Var - 1); +        } +      } +    } + +    bool Fail = false; +    for (unsigned Idx : MissingLines.set_bits()) { +      errs() << "WARNING: Missing line " << Idx + 1 << "\n"; +      Fail = true; +    } + +    for (unsigned Idx : MissingVars.set_bits()) { +      errs() << "WARNING: Missing variable " << Idx + 1 << "\n"; +      Fail = true; +    } +    errs() << "Machine IR debug info check: "; +    errs() << (Fail ? "FAIL" : "PASS") << "\n"; + +    return false; +  } + +  CheckDebugMachineModule() : ModulePass(ID) {} + +  void getAnalysisUsage(AnalysisUsage &AU) const override { +    AU.addRequired<MachineModuleInfoWrapperPass>(); +    AU.setPreservesAll(); +  } + +  static char ID; // Pass identification. +}; +char CheckDebugMachineModule::ID = 0; + +} // end anonymous namespace + +INITIALIZE_PASS_BEGIN(CheckDebugMachineModule, DEBUG_TYPE, +                      "Machine Check Debug Module", false, false) +INITIALIZE_PASS_END(CheckDebugMachineModule, DEBUG_TYPE, +                    "Machine Check Debug Module", false, false) + +ModulePass *llvm::createCheckDebugMachineModulePass() { +  return new CheckDebugMachineModule(); +}  | 
