//===-- NVPTXDwarfDebug.cpp - NVPTX DwarfDebug Implementation ------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file implements helper functions for NVPTX-specific debug information
// processing.
//
//===----------------------------------------------------------------------===//

#include "NVPTXDwarfDebug.h"
#include "NVPTXSubtarget.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/NVPTXAddrSpace.h"
#include "llvm/Target/TargetMachine.h"

using namespace llvm;

// Command line option to control inlined_at enhancement to lineinfo support.
// Valid only when debuginfo emissionkind is DebugDirectivesOnly or
// LineTablesOnly.
static cl::opt<bool> LineInfoWithInlinedAt(
    "line-info-inlined-at",
    cl::desc("Emit line with inlined_at enhancement for NVPTX"), cl::init(true),
    cl::Hidden);

NVPTXDwarfDebug::NVPTXDwarfDebug(AsmPrinter *A) : DwarfDebug(A) {
  // PTX emits debug strings inline (no .debug_str section), does not support
  // .debug_ranges, and uses sections as references (no temp symbols inside
  // DWARF sections).  DWARF v2 is the default for NVPTX and does not support
  // accelerator tables.
  setUseInlineStrings(true);
  setUseRangesSection(false);
  setUseSectionsAsReferences(true);
  Asm->OutStreamer->getContext().setDwarfVersion(2);
  setTheAccelTableKind(AccelTableKind::None);
}

MCSymbol *NVPTXDwarfDebug::getOrCreateFuncNameSymbol(StringRef LinkageName) {
  return InfoHolder.getStringPool().getEntry(*Asm, LinkageName).getSymbol();
}

bool NVPTXDwarfDebug::isEnhancedLineinfo(const MachineFunction &MF) const {
  const DISubprogram *SP = MF.getFunction().getSubprogram();
  const NVPTXSubtarget &STI = MF.getSubtarget<NVPTXSubtarget>();
  return LineInfoWithInlinedAt && (STI.getPTXVersion() >= 72) && SP &&
         (SP->getUnit()->isDebugDirectivesOnly() ||
          SP->getUnit()->getEmissionKind() == DICompileUnit::LineTablesOnly);
}

/// NVPTX-specific source line recording with inlined_at support.
///
/// Why this exists:
/// NVPTX supports an "enhanced lineinfo" mode where inlining context is carried
/// via line-table directives, rather than full DWARF DIEs. This is conceptually
/// similar to proposals[1] for richer DWARF line tables that carry inline call
/// context and callee identity in the line table. NVPTX implements this via
/// target-specific `.loc` extensions in the PTX ISA[3].
///
/// How it impacts PTX assembly generation:
/// - When enabled (PTX ISA >= 7.2 + line-tables-only / debug-directives-only),
///   we emit multiple consecutive `.loc` directives for a single inlined
///   instruction: the instruction's own location and its `inlined_at` parent
///   chain.
/// - During emission we use `MCStreamer::emitDwarfLocDirectiveWithInlinedAt` to
///   emit an enhanced `.loc` directive[3] that carries the extra
///   `function_name` and `inlined_at` operands in the PTX assembly stream.
///
/// Example (conceptual PTX `.loc` sequence for an inlined callsite):
///   .loc 1 16 3                            // caller location
///   .loc 1  5 3, function_name $L__info_stringN, inlined_at 1 16 3
///                                         // inlined callee location
///   Here, $L__info_stringN is a label (or label+immediate) referring into
///   `.debug_str`.
///
/// How this impacts DWARF :
/// DWARF generation tools that consume this PTX(e.g. ptxas assembler) can use
/// the `inlined_at` and `function_name` operands to extend the DWARF v2
/// line table information.
/// This adds:
/// - a `context` column[2]: the `inlined_at <file> <line> <col>` information
///   populates an inlining "context" (a reference to the parent/callsite row)
///   enabling reconstruction of inline call chains from the line table.
/// - a `function_name` column[2]: the `.loc ... function_name <sym>` identifies
///   the inlined callee associated with a non-zero context.
///
/// References:
/// - [1] DWARF line tables / Two-Level Line Tables:
///   https://wiki.dwarfstd.org/TwoLevelLineTables.md
/// - [2] DWARF issue tracking for Two-Level Line Tables:
///   https://dwarfstd.org/issues/140906.1.html
/// - [3] NVIDIA PTX ISA `.loc` (debugging directives; PTX ISA 7.2+):
///   https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#debugging-directives-loc
void NVPTXDwarfDebug::recordTargetSourceLine(const DebugLoc &DL,
                                             unsigned Flags) {
  // Maintain a work list of .loc to be emitted. If we are emitting the
  // inlined_at directive, we might need to emit additional .loc prior
  // to it for the location contained in the inlined_at.
  SmallVector<const DILocation *, 8> WorkList;
  SmallDenseSet<const DILocation *, 8> WorkListSet;
  const DILocation *EmitLoc = DL.get();

  if (!EmitLoc)
    return;

  const MachineFunction *MF = Asm->MF;
  if (!MF)
    return;

  const bool EnhancedLineinfo = isEnhancedLineinfo(*MF);

  while (EmitLoc) {
    // Get the scope for the current location.
    const DIScope *Scope = EmitLoc->getScope();
    if (!Scope)
      break; // scope is null, we are done.

    // Check if this loc is already in work list, if so, we are done.
    if (WorkListSet.contains(EmitLoc))
      break;

    // Add this location to the work list.
    WorkList.push_back(EmitLoc);
    WorkListSet.insert(EmitLoc);

    if (!EnhancedLineinfo) // No enhanced lineinfo, we are done.
      break;

    const DILocation *IA = EmitLoc->getInlinedAt();
    // Check if this has inlined_at information, and if the parent location
    // has not yet been emitted. If already emitted, we don't need to
    // re-emit the parent chain.
    if (IA && !EmittedInlinedAtLocs.contains(IA))
      EmitLoc = IA;
    else // We are done.
      break;
  }

  const unsigned CUID = Asm->OutStreamer->getContext().getDwarfCompileUnitID();
  // Traverse the work list, and emit .loc.
  while (!WorkList.empty()) {
    const DILocation *Current = WorkList.pop_back_val();
    const DIScope *Scope = Current->getScope();

    if (!Scope)
      llvm_unreachable("we shouldn't be here for null scope");

    const DILocation *InlinedAt = Current->getInlinedAt();
    StringRef Fn = Scope->getFilename();
    const unsigned Line = Current->getLine();
    const unsigned Col = Current->getColumn();
    unsigned Discriminator = 0;
    if (Line != 0 && getDwarfVersion() >= 4)
      if (const DILexicalBlockFile *LBF = dyn_cast<DILexicalBlockFile>(Scope))
        Discriminator = LBF->getDiscriminator();

    const unsigned FileNo = static_cast<DwarfCompileUnit &>(*getUnits()[CUID])
                                .getOrCreateSourceID(Scope->getFile());

    if (EnhancedLineinfo && InlinedAt) {
      const unsigned FileIA = static_cast<DwarfCompileUnit &>(*getUnits()[CUID])
                                  .getOrCreateSourceID(InlinedAt->getFile());
      const DISubprogram *SubProgram = getDISubprogram(Current->getScope());
      DwarfStringPoolEntryRef Entry = InfoHolder.getStringPool().getEntry(
          *Asm, SubProgram->getLinkageName());
      Asm->OutStreamer->emitDwarfLocDirectiveWithInlinedAt(
          FileNo, Line, Col, FileIA, InlinedAt->getLine(),
          InlinedAt->getColumn(), Entry.getSymbol(), Flags, 0, Discriminator,
          Fn);
    } else {
      Asm->OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
                                              Discriminator, Fn);
    }
    // Mark this location as emitted so we don't re-emit the parent chain
    // for subsequent instructions that share the same inlined_at parent.
    if (EnhancedLineinfo)
      EmittedInlinedAtLocs.insert(Current);
  }
}

/// NVPTX-specific debug info initialization.
void NVPTXDwarfDebug::initializeTargetDebugInfo(const MachineFunction &MF) {
  EmittedInlinedAtLocs.clear();
}

// PTX does not support subtracting labels from the code section in the
// debug_loc section.  To work around this, the NVPTX backend needs the
// compile unit to have no low_pc in order to have a zero base_address
// when handling debug_loc in cuda-gdb.
bool NVPTXDwarfDebug::shouldAttachCompileUnitRanges() const {
  return !tuneForGDB();
}

// Same label-subtraction limitation as above: cuda-gdb doesn't handle
// setting a per-variable base to zero, so we emit labels with no base
// while having no compile unit low_pc.
bool NVPTXDwarfDebug::shouldResetBaseAddress(const MCSection &Section) const {
  return tuneForGDB();
}

static unsigned translateToNVVMDWARFAddrSpace(unsigned AddrSpace) {
  switch (AddrSpace) {
  case NVPTXAS::ADDRESS_SPACE_GENERIC:
    return NVPTXAS::DWARF_ADDR_generic_space;
  case NVPTXAS::ADDRESS_SPACE_GLOBAL:
    return NVPTXAS::DWARF_ADDR_global_space;
  case NVPTXAS::ADDRESS_SPACE_SHARED:
    return NVPTXAS::DWARF_ADDR_shared_space;
  case NVPTXAS::ADDRESS_SPACE_CONST:
    return NVPTXAS::DWARF_ADDR_const_space;
  case NVPTXAS::ADDRESS_SPACE_LOCAL:
    return NVPTXAS::DWARF_ADDR_local_space;
  default:
    llvm_unreachable(
        "Cannot translate unknown address space to DWARF address space");
    return AddrSpace;
  }
}

// cuda-gdb requires DW_AT_address_class on variable DIEs.  The address space
// is encoded in the DIExpression as a DW_OP_constu <DWARF Address Space>
// DW_OP_swap DW_OP_xderef sequence.  We strip that sequence from the
// expression and return the address space so the caller can emit
// DW_AT_address_class separately.
const DIExpression *NVPTXDwarfDebug::adjustExpressionForTarget(
    const DIExpression *Expr, std::optional<unsigned> &TargetAddrSpace) const {
  if (!tuneForGDB())
    return Expr;
  unsigned LocalAddrSpace;
  const DIExpression *NewExpr =
      DIExpression::extractAddressClass(Expr, LocalAddrSpace);
  if (NewExpr != Expr) {
    TargetAddrSpace = LocalAddrSpace;
    return NewExpr;
  }
  return Expr;
}

// Emit DW_AT_address_class for cuda-gdb.  See NVPTXAS::DWARF_AddressSpace.
//
// The address class depends on the variable's storage kind:
//   Global:     from the expression (if encoded) or the IR address space
//   Register:   DWARF_ADDR_reg_space (no expression means register location)
//   FrameIndex: from the expression (if encoded) or DWARF_ADDR_local_space
void NVPTXDwarfDebug::addTargetVariableAttributes(
    DwarfCompileUnit &CU, DIE &Die, std::optional<unsigned> TargetAddrSpace,
    VariableLocationKind VarLocKind, const GlobalVariable *GV) const {
  if (!tuneForGDB())
    return;

  unsigned DefaultAddrSpace = NVPTXAS::DWARF_ADDR_global_space;
  switch (VarLocKind) {
  case VariableLocationKind::Global:
    if (!TargetAddrSpace && GV)
      TargetAddrSpace =
          translateToNVVMDWARFAddrSpace(GV->getType()->getAddressSpace());
    DefaultAddrSpace = NVPTXAS::DWARF_ADDR_global_space;
    break;
  case VariableLocationKind::Register:
    DefaultAddrSpace = NVPTXAS::DWARF_ADDR_reg_space;
    break;
  case VariableLocationKind::FrameIndex:
    DefaultAddrSpace = NVPTXAS::DWARF_ADDR_local_space;
    break;
  }

  CU.addUInt(Die, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
             TargetAddrSpace.value_or(DefaultAddrSpace));
}
