///===- DroppedVariableStatsIR.cpp ----------------------------------------===//
///
/// 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
/// Dropped Variable Statistics for Debug Information. Reports any number
/// of #dbg_value that get dropped due to an optimization pass.
///
///===---------------------------------------------------------------------===//

#include "llvm/IR/DroppedVariableStatsIR.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassInstrumentation.h"

using namespace llvm;

void DroppedVariableStatsIR::runBeforePass(StringRef P, IRUnitRef IR) {
  setup();
  if (const auto *M = dyn_cast<Module>(IR))
    return this->runOnModule(P, M, true);
  if (const auto *F = dyn_cast<Function>(IR))
    return this->runOnFunction(P, F, true);
}

void DroppedVariableStatsIR::runAfterPass(StringRef P, IRUnitRef IR) {
  if (const auto *M = dyn_cast<Module>(IR))
    runAfterPassModule(P, M);
  else if (const auto *F = dyn_cast<Function>(IR))
    runAfterPassFunction(P, F);
  cleanup();
}

void DroppedVariableStatsIR::runAfterPassFunction(StringRef PassID,
                                                  const Function *F) {
  runOnFunction(PassID, F, false);
  calculateDroppedVarStatsOnFunction(F, PassID, F->getName().str(), "Function");
}

void DroppedVariableStatsIR::runAfterPassModule(StringRef PassID,
                                                const Module *M) {
  runOnModule(PassID, M, false);
  calculateDroppedVarStatsOnModule(M, PassID, M->getName().str(), "Module");
}

void DroppedVariableStatsIR::runOnFunction(StringRef PassID, const Function *F,
                                           bool Before) {
  auto &DebugVariables = DebugVariablesStack.back()[F];
  auto FuncName = F->getName();
  Func = F;
  run(DebugVariables, FuncName, Before);
}

void DroppedVariableStatsIR::calculateDroppedVarStatsOnFunction(
    const Function *F, StringRef PassID, StringRef FuncOrModName,
    StringRef PassLevel) {
  Func = F;
  StringRef FuncName = F->getName();
  DebugVariables &DbgVariables = DebugVariablesStack.back()[F];
  calculateDroppedStatsAndPrint(DbgVariables, FuncName, PassID, FuncOrModName,
                                PassLevel, Func);
}

void DroppedVariableStatsIR::runOnModule(StringRef PassID, const Module *M,
                                         bool Before) {
  for (auto &F : *M) {
    runOnFunction(PassID, &F, Before);
  }
}

void DroppedVariableStatsIR::calculateDroppedVarStatsOnModule(
    const Module *M, StringRef PassID, StringRef FuncOrModName,
    StringRef PassLevel) {
  for (auto &F : *M) {
    calculateDroppedVarStatsOnFunction(&F, PassID, FuncOrModName, PassLevel);
  }
}

void DroppedVariableStatsIR::registerCallbacks(
    PassInstrumentationCallbacks &PIC) {
  if (!DroppedVariableStatsEnabled)
    return;

  PIC.registerBeforeNonSkippedPassCallback(
      [this](StringRef P, IRUnitRef IR) { return runBeforePass(P, IR); });
  PIC.registerAfterPassCallback(
      [this](StringRef P, IRUnitRef IR, const PreservedAnalyses &PA) {
        return runAfterPass(P, IR);
      });
  PIC.registerAfterPassInvalidatedCallback(
      [this](StringRef P, const PreservedAnalyses &PA) { return cleanup(); });
}

void DroppedVariableStatsIR::visitEveryInstruction(
    unsigned &DroppedCount, DenseMap<VarID, DILocation *> &InlinedAtsMap,
    VarID Var) {
  const DIScope *DbgValScope = std::get<0>(Var);
  for (const auto &I : instructions(Func)) {
    auto *DbgLoc = I.getDebugLoc().get();
    if (!DbgLoc)
      continue;
    if (updateDroppedCount(DbgLoc, DbgLoc->getScope(), DbgValScope,
                           InlinedAtsMap, Var, DroppedCount))
      break;
  }
}

void DroppedVariableStatsIR::visitEveryDebugRecord(
    DenseSet<VarID> &VarIDSet,
    DenseMap<StringRef, DenseMap<VarID, DILocation *>> &InlinedAtsMap,
    StringRef FuncName, bool Before) {
  for (const auto &I : instructions(Func)) {
    for (DbgRecord &DR : I.getDbgRecordRange()) {
      if (auto *Dbg = dyn_cast<DbgVariableRecord>(&DR)) {
        auto *DbgVar = Dbg->getVariable();
        auto DbgLoc = DR.getDebugLoc();
        populateVarIDSetAndInlinedMap(DbgVar, DbgLoc, VarIDSet, InlinedAtsMap,
                                      FuncName, Before);
      }
    }
  }
}
