brintos

brintos / llvm-project-archived public Read only

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