//===-- AMDGPUMachineFunctionInfo.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
//
//===----------------------------------------------------------------------===//

#include "AMDGPUMachineFunction.h"
#include "AMDGPU.h"
#include "AMDGPUPerfHintAnalysis.h"
#include "AMDGPUSubtarget.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/Target/TargetMachine.h"

using namespace llvm;

AMDGPUMachineFunction::AMDGPUMachineFunction(const Function &F,
                                             const AMDGPUSubtarget &ST)
    : IsEntryFunction(AMDGPU::isEntryFunctionCC(F.getCallingConv())),
      IsModuleEntryFunction(
          AMDGPU::isModuleEntryFunctionCC(F.getCallingConv())),
      NoSignedZerosFPMath(false) {

  // FIXME: Should initialize KernArgSize based on ExplicitKernelArgOffset,
  // except reserved size is not correctly aligned.

  Attribute MemBoundAttr = F.getFnAttribute("amdgpu-memory-bound");
  MemoryBound = MemBoundAttr.getValueAsBool();

  Attribute WaveLimitAttr = F.getFnAttribute("amdgpu-wave-limiter");
  WaveLimiter = WaveLimitAttr.getValueAsBool();

  // FIXME: How is this attribute supposed to interact with statically known
  // global sizes?
  StringRef S = F.getFnAttribute("amdgpu-gds-size").getValueAsString();
  if (!S.empty())
    S.consumeInteger(0, GDSSize);

  // Assume the attribute allocates before any known GDS globals.
  StaticGDSSize = GDSSize;

  CallingConv::ID CC = F.getCallingConv();
  if (CC == CallingConv::AMDGPU_KERNEL || CC == CallingConv::SPIR_KERNEL)
    ExplicitKernArgSize = ST.getExplicitKernArgSize(F, MaxKernArgAlign);

  // FIXME: Shouldn't be target specific
  Attribute NSZAttr = F.getFnAttribute("no-signed-zeros-fp-math");
  NoSignedZerosFPMath =
      NSZAttr.isStringAttribute() && NSZAttr.getValueAsString() == "true";
}

unsigned AMDGPUMachineFunction::allocateLDSGlobal(const DataLayout &DL,
                                                  const GlobalVariable &GV,
                                                  Align Trailing) {
  auto Entry = LocalMemoryObjects.insert(std::pair(&GV, 0));
  if (!Entry.second)
    return Entry.first->second;

  Align Alignment =
      DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType());

  unsigned Offset;
  if (GV.getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS) {
    /// TODO: We should sort these to minimize wasted space due to alignment
    /// padding. Currently the padding is decided by the first encountered use
    /// during lowering.
    Offset = StaticLDSSize = alignTo(StaticLDSSize, Alignment);

    StaticLDSSize += DL.getTypeAllocSize(GV.getValueType());

    // Align LDS size to trailing, e.g. for aligning dynamic shared memory
    LDSSize = alignTo(StaticLDSSize, Trailing);
  } else {
    assert(GV.getAddressSpace() == AMDGPUAS::REGION_ADDRESS &&
           "expected region address space");

    Offset = StaticGDSSize = alignTo(StaticGDSSize, Alignment);
    StaticGDSSize += DL.getTypeAllocSize(GV.getValueType());

    // FIXME: Apply alignment of dynamic GDS
    GDSSize = StaticGDSSize;
  }

  Entry.first->second = Offset;
  return Offset;
}

static constexpr StringLiteral ModuleLDSName = "llvm.amdgcn.module.lds";

bool AMDGPUMachineFunction::isKnownAddressLDSGlobal(const GlobalVariable &GV) {
  auto name = GV.getName();
  return (name == ModuleLDSName) ||
         (name.startswith("llvm.amdgcn.kernel.") && name.endswith(".lds"));
}

const Function *AMDGPUMachineFunction::getKernelLDSFunctionFromGlobal(
    const GlobalVariable &GV) {
  const Module &M = *GV.getParent();
  StringRef N(GV.getName());
  if (N.consume_front("llvm.amdgcn.kernel.") && N.consume_back(".lds")) {
    return M.getFunction(N);
  }
  return nullptr;
}

const GlobalVariable *
AMDGPUMachineFunction::getKernelLDSGlobalFromFunction(const Function &F) {
  const Module *M = F.getParent();
  std::string KernelLDSName = "llvm.amdgcn.kernel.";
  KernelLDSName += F.getName();
  KernelLDSName += ".lds";
  return M->getNamedGlobal(KernelLDSName);
}

// This kernel calls no functions that require the module lds struct
static bool canElideModuleLDS(const Function &F) {
  return F.hasFnAttribute("amdgpu-elide-module-lds");
}

unsigned AMDGPUMachineFunction::calculateKnownAddressOfLDSGlobal(
    const GlobalVariable &GV) {
  // module.lds, then alignment padding, then kernel.lds, then other variables
  // if any

  assert(isKnownAddressLDSGlobal(GV));
  unsigned Offset = 0;

  if (GV.getName() == ModuleLDSName) {
    return 0;
  }

  const Module *M = GV.getParent();
  const DataLayout &DL = M->getDataLayout();

  const GlobalVariable *GVM = M->getNamedGlobal(ModuleLDSName);
  const Function *f = getKernelLDSFunctionFromGlobal(GV);

  // Account for module.lds if allocated for this function
  if (GVM && f && !canElideModuleLDS(*f)) {
    // allocator aligns this to var align, but it's zero to begin with
    Offset += DL.getTypeAllocSize(GVM->getValueType());
  }

  // No dynamic LDS alignment done by allocateModuleLDSGlobal
  Offset = alignTo(
      Offset, DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType()));

  return Offset;
}

void AMDGPUMachineFunction::allocateKnownAddressLDSGlobal(const Function &F) {
  const Module *M = F.getParent();

  // This function is called before allocating any other LDS so that it can
  // reliably put values at known addresses. Consequently, dynamic LDS, if
  // present, will not yet have been allocated

  assert(getDynLDSAlign() == Align() && "dynamic LDS not yet allocated");

  if (isModuleEntryFunction()) {

    // Pointer values start from zero, memory allocated per-kernel-launch
    // Variables can be grouped into a module level struct and a struct per
    // kernel function by AMDGPULowerModuleLDSPass. If that is done, they
    // are allocated at statically computable addresses here.
    //
    // Address 0
    // {
    //   llvm.amdgcn.module.lds
    // }
    // alignment padding
    // {
    //   llvm.amdgcn.kernel.some-name.lds
    // }
    // other variables, e.g. dynamic lds, allocated after this call

    const GlobalVariable *GV = M->getNamedGlobal(ModuleLDSName);
    const GlobalVariable *KV = getKernelLDSGlobalFromFunction(F);

    if (GV && !canElideModuleLDS(F)) {
      assert(isKnownAddressLDSGlobal(*GV));
      unsigned Offset = allocateLDSGlobal(M->getDataLayout(), *GV, Align());
      (void)Offset;
      assert(Offset == calculateKnownAddressOfLDSGlobal(*GV) &&
             "Module LDS expected to be allocated before other LDS");
    }

    if (KV) {
      // The per-kernel offset is deterministic because it is allocated
      // before any other non-module LDS variables.
      assert(isKnownAddressLDSGlobal(*KV));
      unsigned Offset = allocateLDSGlobal(M->getDataLayout(), *KV, Align());
      (void)Offset;
      assert(Offset == calculateKnownAddressOfLDSGlobal(*KV) &&
             "Kernel LDS expected to be immediately after module LDS");
    }
  }
}

std::optional<uint32_t>
AMDGPUMachineFunction::getLDSKernelIdMetadata(const Function &F) {
  auto MD = F.getMetadata("llvm.amdgcn.lds.kernel.id");
  if (MD && MD->getNumOperands() == 1) {
    ConstantInt *KnownSize = mdconst::extract<ConstantInt>(MD->getOperand(0));
    if (KnownSize) {
      uint64_t V = KnownSize->getZExtValue();
      if (V <= UINT32_MAX) {
        return V;
      }
    }
  }
  return {};
}

void AMDGPUMachineFunction::setDynLDSAlign(const DataLayout &DL,
                                           const GlobalVariable &GV) {
  assert(DL.getTypeAllocSize(GV.getValueType()).isZero());

  Align Alignment =
      DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType());
  if (Alignment <= DynLDSAlign)
    return;

  LDSSize = alignTo(StaticLDSSize, Alignment);
  DynLDSAlign = Alignment;
}
