//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "DbgValueHistoryCalculator.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include <cassert>
#include <map>
#include <utility>

using namespace llvm;

#define DEBUG_TYPE "dwarfdebug"

// \brief If @MI is a DBG_VALUE with debug value described by a
// defined register, returns the number of this register.
// In the other case, returns 0.
static unsigned isDescribedByReg(const MachineInstr &MI) {
  assert(MI.isDebugValue());
  assert(MI.getNumOperands() == 4);
  // If location of variable is described using a register (directly or
  // indirectly), this register is always a first operand.
  return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0;
}

void DbgValueHistoryMap::startInstrRange(InlinedVariable Var,
                                         const MachineInstr &MI) {
  // Instruction range should start with a DBG_VALUE instruction for the
  // variable.
  assert(MI.isDebugValue() && "not a DBG_VALUE");
  auto &Ranges = VarInstrRanges[Var];
  if (!Ranges.empty() && Ranges.back().second == nullptr &&
      Ranges.back().first->isIdenticalTo(MI)) {
    DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n"
                 << "\t" << Ranges.back().first << "\t" << MI << "\n");
    return;
  }
  Ranges.push_back(std::make_pair(&MI, nullptr));
}

void DbgValueHistoryMap::endInstrRange(InlinedVariable Var,
                                       const MachineInstr &MI) {
  auto &Ranges = VarInstrRanges[Var];
  // Verify that the current instruction range is not yet closed.
  assert(!Ranges.empty() && Ranges.back().second == nullptr);
  // For now, instruction ranges are not allowed to cross basic block
  // boundaries.
  assert(Ranges.back().first->getParent() == MI.getParent());
  Ranges.back().second = &MI;
}

unsigned DbgValueHistoryMap::getRegisterForVar(InlinedVariable Var) const {
  const auto &I = VarInstrRanges.find(Var);
  if (I == VarInstrRanges.end())
    return 0;
  const auto &Ranges = I->second;
  if (Ranges.empty() || Ranges.back().second != nullptr)
    return 0;
  return isDescribedByReg(*Ranges.back().first);
}

namespace {

// Maps physreg numbers to the variables they describe.
using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedVariable, 1>>;

} // end anonymous namespace

// \brief Claim that @Var is not described by @RegNo anymore.
static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
                                InlinedVariable Var) {
  const auto &I = RegVars.find(RegNo);
  assert(RegNo != 0U && I != RegVars.end());
  auto &VarSet = I->second;
  const auto &VarPos = llvm::find(VarSet, Var);
  assert(VarPos != VarSet.end());
  VarSet.erase(VarPos);
  // Don't keep empty sets in a map to keep it as small as possible.
  if (VarSet.empty())
    RegVars.erase(I);
}

// \brief Claim that @Var is now described by @RegNo.
static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
                               InlinedVariable Var) {
  assert(RegNo != 0U);
  auto &VarSet = RegVars[RegNo];
  assert(!is_contained(VarSet, Var));
  VarSet.push_back(Var);
}

// \brief Terminate the location range for variables described by register at
// @I by inserting @ClobberingInstr to their history.
static void clobberRegisterUses(RegDescribedVarsMap &RegVars,
                                RegDescribedVarsMap::iterator I,
                                DbgValueHistoryMap &HistMap,
                                const MachineInstr &ClobberingInstr) {
  // Iterate over all variables described by this register and add this
  // instruction to their history, clobbering it.
  for (const auto &Var : I->second)
    HistMap.endInstrRange(Var, ClobberingInstr);
  RegVars.erase(I);
}

// \brief Terminate the location range for variables described by register
// @RegNo by inserting @ClobberingInstr to their history.
static void clobberRegisterUses(RegDescribedVarsMap &RegVars, unsigned RegNo,
                                DbgValueHistoryMap &HistMap,
                                const MachineInstr &ClobberingInstr) {
  const auto &I = RegVars.find(RegNo);
  if (I == RegVars.end())
    return;
  clobberRegisterUses(RegVars, I, HistMap, ClobberingInstr);
}

// \brief Returns the first instruction in @MBB which corresponds to
// the function epilogue, or nullptr if @MBB doesn't contain an epilogue.
static const MachineInstr *getFirstEpilogueInst(const MachineBasicBlock &MBB) {
  auto LastMI = MBB.getLastNonDebugInstr();
  if (LastMI == MBB.end() || !LastMI->isReturn())
    return nullptr;
  // Assume that epilogue starts with instruction having the same debug location
  // as the return instruction.
  DebugLoc LastLoc = LastMI->getDebugLoc();
  auto Res = LastMI;
  for (MachineBasicBlock::const_reverse_iterator I = LastMI.getReverse(),
                                                 E = MBB.rend();
       I != E; ++I) {
    if (I->getDebugLoc() != LastLoc)
      return &*Res;
    Res = &*I;
  }
  // If all instructions have the same debug location, assume whole MBB is
  // an epilogue.
  return &*MBB.begin();
}

// \brief Collect registers that are modified in the function body (their
// contents is changed outside of the prologue and epilogue).
static void collectChangingRegs(const MachineFunction *MF,
                                const TargetRegisterInfo *TRI,
                                BitVector &Regs) {
  for (const auto &MBB : *MF) {
    auto FirstEpilogueInst = getFirstEpilogueInst(MBB);

    for (const auto &MI : MBB) {
      // Avoid looking at prologue or epilogue instructions.
      if (&MI == FirstEpilogueInst)
        break;
      if (MI.getFlag(MachineInstr::FrameSetup))
        continue;

      // Look for register defs and register masks. Register masks are
      // typically on calls and they clobber everything not in the mask.
      for (const MachineOperand &MO : MI.operands()) {
        // Skip virtual registers since they are handled by the parent.
        if (MO.isReg() && MO.isDef() && MO.getReg() &&
            !TRI->isVirtualRegister(MO.getReg())) {
          for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
               ++AI)
            Regs.set(*AI);
        } else if (MO.isRegMask()) {
          Regs.setBitsNotInMask(MO.getRegMask());
        }
      }
    }
  }
}

void llvm::calculateDbgValueHistory(const MachineFunction *MF,
                                    const TargetRegisterInfo *TRI,
                                    DbgValueHistoryMap &Result) {
  BitVector ChangingRegs(TRI->getNumRegs());
  collectChangingRegs(MF, TRI, ChangingRegs);

  const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
  unsigned SP = TLI->getStackPointerRegisterToSaveRestore();
  RegDescribedVarsMap RegVars;
  for (const auto &MBB : *MF) {
    for (const auto &MI : MBB) {
      if (!MI.isDebugValue()) {
        // Not a DBG_VALUE instruction. It may clobber registers which describe
        // some variables.
        for (const MachineOperand &MO : MI.operands()) {
          if (MO.isReg() && MO.isDef() && MO.getReg()) {
            // Ignore call instructions that claim to clobber SP. The AArch64
            // backend does this for aggregate function arguments.
            if (MI.isCall() && MO.getReg() == SP)
              continue;
            // If this is a virtual register, only clobber it since it doesn't
            // have aliases.
            if (TRI->isVirtualRegister(MO.getReg()))
              clobberRegisterUses(RegVars, MO.getReg(), Result, MI);
            // If this is a register def operand, it may end a debug value
            // range.
            else {
              for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
                   ++AI)
                if (ChangingRegs.test(*AI))
                  clobberRegisterUses(RegVars, *AI, Result, MI);
            }
          } else if (MO.isRegMask()) {
            // If this is a register mask operand, clobber all debug values in
            // non-CSRs.
            for (unsigned I : ChangingRegs.set_bits()) {
              // Don't consider SP to be clobbered by register masks.
              if (unsigned(I) != SP && TRI->isPhysicalRegister(I) &&
                  MO.clobbersPhysReg(I)) {
                clobberRegisterUses(RegVars, I, Result, MI);
              }
            }
          }
        }
        continue;
      }

      assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!");
      // Use the base variable (without any DW_OP_piece expressions)
      // as index into History. The full variables including the
      // piece expressions are attached to the MI.
      const DILocalVariable *RawVar = MI.getDebugVariable();
      assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
             "Expected inlined-at fields to agree");
      InlinedVariable Var(RawVar, MI.getDebugLoc()->getInlinedAt());

      if (unsigned PrevReg = Result.getRegisterForVar(Var))
        dropRegDescribedVar(RegVars, PrevReg, Var);

      Result.startInstrRange(Var, MI);

      if (unsigned NewReg = isDescribedByReg(MI))
        addRegDescribedVar(RegVars, NewReg, Var);
    }

    // Make sure locations for register-described variables are valid only
    // until the end of the basic block (unless it's the last basic block, in
    // which case let their liveness run off to the end of the function).
    if (!MBB.empty() && &MBB != &MF->back()) {
      for (auto I = RegVars.begin(), E = RegVars.end(); I != E;) {
        auto CurElem = I++; // CurElem can be erased below.
        if (TRI->isVirtualRegister(CurElem->first) ||
            ChangingRegs.test(CurElem->first))
          clobberRegisterUses(RegVars, CurElem, Result, MBB.back());
      }
    }
  }
}
