//===- RemoveRedundantDebugValues.cpp - Remove Redundant Debug Value MIs --===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Function.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/PassRegistry.h"

/// \file RemoveRedundantDebugValues.cpp
///
/// The RemoveRedundantDebugValues pass removes redundant DBG_VALUEs that
/// appear in MIR after the register allocator.

#define DEBUG_TYPE "removeredundantdebugvalues"

using namespace llvm;

STATISTIC(NumRemovedBackward, "Number of DBG_VALUEs removed (backward scan)");
STATISTIC(NumRemovedForward, "Number of DBG_VALUEs removed (forward scan)");

namespace {

class RemoveRedundantDebugValues : public MachineFunctionPass {
public:
  static char ID;

  RemoveRedundantDebugValues();

  bool reduceDbgValues(MachineFunction &MF);

  /// Remove redundant debug value MIs for the given machine function.
  bool runOnMachineFunction(MachineFunction &MF) override;

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesCFG();
    MachineFunctionPass::getAnalysisUsage(AU);
  }
};

} // namespace

//===----------------------------------------------------------------------===//
//            Implementation
//===----------------------------------------------------------------------===//

char RemoveRedundantDebugValues::ID = 0;

char &llvm::RemoveRedundantDebugValuesID = RemoveRedundantDebugValues::ID;

INITIALIZE_PASS(RemoveRedundantDebugValues, DEBUG_TYPE,
                "Remove Redundant DEBUG_VALUE analysis", false, false)

/// Default construct and initialize the pass.
RemoveRedundantDebugValues::RemoveRedundantDebugValues()
    : MachineFunctionPass(ID) {
  initializeRemoveRedundantDebugValuesPass(*PassRegistry::getPassRegistry());
}

// This analysis aims to remove redundant DBG_VALUEs by going forward
// in the basic block by considering the first DBG_VALUE as a valid
// until its first (location) operand is not clobbered/modified.
// For example:
//   (1) DBG_VALUE $edi, !"var1", ...
//   (2) <block of code that does affect $edi>
//   (3) DBG_VALUE $edi, !"var1", ...
//   ...
// in this case, we can remove (3).
// TODO: Support DBG_VALUE_LIST and other debug instructions.
static bool reduceDbgValsForwardScan(MachineBasicBlock &MBB) {
  LLVM_DEBUG(dbgs() << "\n == Forward Scan == \n");

  SmallVector<MachineInstr *, 8> DbgValsToBeRemoved;
  DenseMap<DebugVariable, std::pair<MachineOperand *, const DIExpression *>>
      VariableMap;
  const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();

  for (auto &MI : MBB) {
    if (MI.isDebugValue()) {
      DebugVariable Var(MI.getDebugVariable(), NoneType(),
                        MI.getDebugLoc()->getInlinedAt());
      auto VMI = VariableMap.find(Var);
      // Just stop tracking this variable, until we cover DBG_VALUE_LIST.
      // 1  DBG_VALUE $rax, "x", DIExpression()
      // ...
      // 2  DBG_VALUE_LIST "x", DIExpression(...), $rax, $rbx
      // ...
      // 3  DBG_VALUE $rax, "x", DIExpression()
      if (MI.isDebugValueList() && VMI != VariableMap.end()) {
        VariableMap.erase(VMI);
        continue;
      }

      MachineOperand &Loc = MI.getDebugOperand(0);
      if (!Loc.isReg()) {
        // If it it's not a register, just stop tracking such variable.
        if (VMI != VariableMap.end())
          VariableMap.erase(VMI);
        continue;
      }

      // We have found a new value for a variable.
      if (VMI == VariableMap.end() ||
          VMI->second.first->getReg() != Loc.getReg() ||
          VMI->second.second != MI.getDebugExpression()) {
        VariableMap[Var] = {&Loc, MI.getDebugExpression()};
        continue;
      }

      // Found an identical DBG_VALUE, so it can be considered
      // for later removal.
      DbgValsToBeRemoved.push_back(&MI);
    }

    if (MI.isMetaInstruction())
      continue;

    // Stop tracking any location that is clobbered by this instruction.
    for (auto &Var : VariableMap) {
      auto &LocOp = Var.second.first;
      if (MI.modifiesRegister(LocOp->getReg(), TRI))
        VariableMap.erase(Var.first);
    }
  }

  for (auto &Instr : DbgValsToBeRemoved) {
    LLVM_DEBUG(dbgs() << "removing "; Instr->dump());
    Instr->eraseFromParent();
    ++NumRemovedForward;
  }

  return !DbgValsToBeRemoved.empty();
}

// This analysis aims to remove redundant DBG_VALUEs by going backward
// in the basic block and removing all but the last DBG_VALUE for any
// given variable in a set of consecutive DBG_VALUE instructions.
// For example:
//   (1) DBG_VALUE $edi, !"var1", ...
//   (2) DBG_VALUE $esi, !"var2", ...
//   (3) DBG_VALUE $edi, !"var1", ...
//   ...
// in this case, we can remove (1).
static bool reduceDbgValsBackwardScan(MachineBasicBlock &MBB) {
  LLVM_DEBUG(dbgs() << "\n == Backward Scan == \n");
  SmallVector<MachineInstr *, 8> DbgValsToBeRemoved;
  SmallDenseSet<DebugVariable> VariableSet;

  for (MachineInstr &MI : llvm::reverse(MBB)) {
    if (MI.isDebugValue()) {
      DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
                        MI.getDebugLoc()->getInlinedAt());
      auto R = VariableSet.insert(Var);
      // If it is a DBG_VALUE describing a constant as:
      //   DBG_VALUE 0, ...
      // we just don't consider such instructions as candidates
      // for redundant removal.
      if (MI.isNonListDebugValue()) {
        MachineOperand &Loc = MI.getDebugOperand(0);
        if (!Loc.isReg()) {
          // If we have already encountered this variable, just stop
          // tracking it.
          if (!R.second)
            VariableSet.erase(Var);
          continue;
        }
      }

      // We have already encountered the value for this variable,
      // so this one can be deleted.
      if (!R.second)
        DbgValsToBeRemoved.push_back(&MI);
      continue;
    }

    // If we encountered a non-DBG_VALUE, try to find the next
    // sequence with consecutive DBG_VALUE instructions.
    VariableSet.clear();
  }

  for (auto &Instr : DbgValsToBeRemoved) {
    LLVM_DEBUG(dbgs() << "removing "; Instr->dump());
    Instr->eraseFromParent();
    ++NumRemovedBackward;
  }

  return !DbgValsToBeRemoved.empty();
}

bool RemoveRedundantDebugValues::reduceDbgValues(MachineFunction &MF) {
  LLVM_DEBUG(dbgs() << "\nDebug Value Reduction\n");

  bool Changed = false;

  for (auto &MBB : MF) {
    Changed |= reduceDbgValsBackwardScan(MBB);
    Changed |= reduceDbgValsForwardScan(MBB);
  }

  return Changed;
}

bool RemoveRedundantDebugValues::runOnMachineFunction(MachineFunction &MF) {
  // Skip functions without debugging information.
  if (!MF.getFunction().getSubprogram())
    return false;

  // Skip functions from NoDebug compilation units.
  if (MF.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
      DICompileUnit::NoDebug)
    return false;

  bool Changed = reduceDbgValues(MF);
  return Changed;
}
