//===- 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/CodeGen/MachineCheckDebugify.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"

#define DEBUG_TYPE "mir-check-debugify"

using namespace llvm;

namespace {

bool checkDebugMachineModuleImpl(
    Module &M, llvm::function_ref<MachineFunction *(Function &)> GetMF) {
  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;
  }

  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 = GetMF(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;
}

struct CheckDebugMachineModuleLegacy : public ModulePass {
  bool runOnModule(Module &M) override {
    MachineModuleInfo &MMI =
        getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
    return checkDebugMachineModuleImpl(
        M, [&MMI](Function &F) -> MachineFunction * {
          return MMI.getMachineFunction(F);
        });
  }

  CheckDebugMachineModuleLegacy() : ModulePass(ID) {}

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<MachineModuleInfoWrapperPass>();
    AU.setPreservesAll();
  }

  static char ID; // Pass identification.
};
char CheckDebugMachineModuleLegacy::ID = 0;

} // end anonymous namespace

INITIALIZE_PASS_BEGIN(CheckDebugMachineModuleLegacy, DEBUG_TYPE,
                      "Machine Check Debug Module", false, false)
INITIALIZE_PASS_END(CheckDebugMachineModuleLegacy, DEBUG_TYPE,
                    "Machine Check Debug Module", false, false)

ModulePass *llvm::createCheckDebugMachineModuleLegacyPass() {
  return new CheckDebugMachineModuleLegacy();
}

PreservedAnalyses CheckDebugMachineModulePass::run(Module &M,
                                                   ModuleAnalysisManager &AM) {
  FunctionAnalysisManager &FAM =
      AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
  checkDebugMachineModuleImpl(M, [&FAM](Function &F) -> MachineFunction * {
    MachineFunctionAnalysis::Result *MFA =
        FAM.getCachedResult<MachineFunctionAnalysis>(F);
    return MFA ? &MFA->getMF() : nullptr;
  });
  return PreservedAnalyses::all();
}
