//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Lower global variables with target extension type "amdgpu.named.barrier"
// that require specialized address assignment. It assigns a unique
// barrier identifier to each named-barrier variable and encodes
// this identifier within the !absolute_symbol metadata of that global.
//
//===----------------------------------------------------------------------===//

#include "AMDGPU.h"
#include "AMDGPUMemoryUtils.h"
#include "AMDGPUTargetMachine.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/ReplaceConstant.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

#define DEBUG_TYPE "amdgpu-lower-exec-sync"

using namespace llvm;
using namespace AMDGPU;

namespace {

static bool isNamedBarrierToLower(const GlobalVariable &GV) {
  return isNamedBarrier(GV) && !GV.isAbsoluteSymbolRef();
}

// Write the specified address into metadata where it can be retrieved by
// the assembler. Format is a half open range, [Address Address+1)
static void recordAbsoluteAddress(Module *M, GlobalVariable *GV,
                                  uint32_t Address) {
  LLVMContext &Ctx = M->getContext();
  auto *IntTy = M->getDataLayout().getIntPtrType(Ctx, AMDGPUAS::LOCAL_ADDRESS);
  auto *MinC = ConstantAsMetadata::get(ConstantInt::get(IntTy, Address));
  auto *MaxC = ConstantAsMetadata::get(ConstantInt::get(IntTy, Address + 1));
  GV->setMetadata(LLVMContext::MD_absolute_symbol,
                  MDNode::get(Ctx, {MinC, MaxC}));
}

/// Get next available ID for sync object. The ID allocation is tracked in \p
/// MaxNumGroup groups by \p NextAvailableIDTracker. Each call of the function
/// will ask for \p IDCnt against all the \p Kernels, it will return the
/// maximum of the available ones and update the ID tracker.
template <typename T>
unsigned allocateExecSyncID(T &NextAvailableIDTracker,
                            ArrayRef<Function *> Kernels, unsigned GroupID,
                            unsigned MaxNumGroup, unsigned IDCnt) {
  constexpr unsigned InitialVal = 1;
  unsigned NextID = InitialVal;
  for (Function *F : Kernels) {
    const SmallVectorImpl<unsigned> &NextAvailableID =
        NextAvailableIDTracker.lookup(F);
    unsigned ID = InitialVal;
    if (!NextAvailableID.empty())
      ID = NextAvailableID[GroupID];

    if (ID > NextID)
      NextID = ID;
  }

  // Bump the next available id for the kernels.
  for (Function *F : Kernels) {
    auto Inserted = NextAvailableIDTracker.try_emplace(F);
    // Initialize on first insertion.
    if (Inserted.second)
      Inserted.first->second.assign(MaxNumGroup, InitialVal);
    // Update the available ID.
    Inserted.first->second[GroupID] = NextID + IDCnt;
  }
  return NextID;
}

// Main utility function for special LDS variables lowering.
static bool lowerExecSyncGlobalVariables(Module &M, GVUsesInfoTy &GVUsesInfo) {
  bool Changed = false;
  const DataLayout &DL = M.getDataLayout();

  constexpr unsigned NumBarScopes = 1;
  MapVector<GlobalVariable *, SmallVector<Function *>> AllocationQ;
  DenseMap<Function *, SmallVector<unsigned, NumBarScopes>> KernelBarrierIDs;

  for (auto &[F, GVs] : GVUsesInfo.IndirectAccess) {
    for (auto *GV : GVs) {
      if (!isNamedBarrier(*GV) || GV->isAbsoluteSymbolRef())
        continue;
      auto Iter = AllocationQ.find(GV);
      if (Iter == AllocationQ.end())
        AllocationQ.insert({GV, {F}});
      else
        Iter->second.push_back(F);
    }
  }

  for (auto &[F, GVs] : GVUsesInfo.DirectAccess) {
    for (auto *GV : GVs) {
      if (!isNamedBarrier(*GV) || GV->isAbsoluteSymbolRef())
        continue;
      auto Iter = AllocationQ.find(GV);
      if (Iter == AllocationQ.end())
        AllocationQ.insert({GV, {F}});
      else
        Iter->second.push_back(F);
    }
  }

  sort(AllocationQ, [](std::pair<GlobalVariable *, SmallVector<Function *>> A,
                       std::pair<GlobalVariable *, SmallVector<Function *>> B) {
    // First order by number of kernels that access the GlobalVariable.
    if (A.second.size() != B.second.size())
      return A.second.size() > B.second.size();

    // Then order by their names so we always get a deterministic order.
    return A.first->getName() < B.first->getName();
  });

  for (auto &[GV, Kernels] : AllocationQ) {
    unsigned Offset;
    if (TargetExtType *ExtTy = isNamedBarrier(*GV)) {
      unsigned BarrierScope = ExtTy->getIntParameter(0);
      unsigned BarCnt = getNumNamedBarriersDeclared(DL, *GV);

      unsigned BarID = allocateExecSyncID(KernelBarrierIDs, Kernels,
                                          BarrierScope, NumBarScopes, BarCnt);

      LLVM_DEBUG(GV->printAsOperand(dbgs(), false);
                 dbgs() << " was assigned barrier id: " << BarID
                        << " id-count: " << BarCnt << "\n");
      Offset = BarID;
    } else {
      llvm_unreachable("Unhandled special variable type.");
    }

    recordAbsoluteAddress(&M, GV, Offset);
  }

  // Also erase those special LDS variables from indirect_access.
  for (auto &K : GVUsesInfo.IndirectAccess) {
    assert(isKernel(*K.first));
    K.second.remove_if([](GlobalVariable *GV) { return isNamedBarrier(*GV); });
  }
  return Changed;
}

static bool hasBarrierToLower(const GVUsesInfoTy &GVUsesInfo) {
  for (auto &Map : {GVUsesInfo.DirectAccess, GVUsesInfo.IndirectAccess}) {
    for (auto &[Fn, GVs] : Map) {
      for (auto &GV : GVs) {
        if (AMDGPU::isNamedBarrier(*GV))
          return true;
      }
    }
  }
  return false;
}

// With object linking, barrier ID assignment is deferred to the linker.
// Externalize named barrier globals and emit self-contained metadata so the
// AsmPrinter can generate the callgraph entries the linker needs.
static bool handleNamedBarriersForObjectLinking(Module &M) {
  DenseMap<GlobalVariable *, DenseSet<Function *>> BarrierToFuncs;
  for (GlobalVariable &GV : M.globals()) {
    if (!isNamedBarrier(GV) || GV.use_empty())
      continue;
    for (User *U : GV.users()) {
      if (auto *I = dyn_cast<Instruction>(U))
        BarrierToFuncs[&GV].insert(I->getFunction());
    }
  }
  if (BarrierToFuncs.empty())
    return false;

  LLVMContext &Ctx = M.getContext();
  NamedMDNode *BarMD = M.getOrInsertNamedMetadata("amdgpu.named_barrier.uses");

  std::string ModuleId;
  ModuleId = getUniqueModuleId(&M);
  assert(!ModuleId.empty() &&
         "modules with named barriers should have a unique ID");
  for (auto &[V, Funcs] : BarrierToFuncs) {
    if (V->hasLocalLinkage())
      V->setName("__amdgpu_named_barrier." + V->getName() + ModuleId);
    else if (!V->getName().starts_with("__amdgpu_named_barrier"))
      V->setName("__amdgpu_named_barrier." + V->getName());
    V->setInitializer(nullptr);
    V->setLinkage(GlobalValue::ExternalLinkage);

    SmallVector<Metadata *, 4> Ops;
    Ops.push_back(ValueAsMetadata::get(V));
    for (Function *F : Funcs)
      Ops.push_back(ValueAsMetadata::get(F));
    BarMD->addOperand(MDNode::get(Ctx, Ops));
  }
  return true;
}

static bool runLowerExecSyncGlobals(Module &M) {
  if (AMDGPUTargetMachine::EnableObjectLinking)
    return handleNamedBarriersForObjectLinking(M);

  CallGraph CG = CallGraph(M);
  bool Changed = false;
  Changed |=
      eliminateGVConstantExprUsesFromAllInstructions(M, isNamedBarrierToLower);

  // For each kernel, what variables does it access directly or through
  // callees
  GVUsesInfoTy BarrierUsesInfo =
      getTransitiveUsesOfGV(CG, M, isNamedBarrierToLower);

  if (hasBarrierToLower(BarrierUsesInfo)) {
    // Special LDS variables need special address assignment
    Changed |= lowerExecSyncGlobalVariables(M, BarrierUsesInfo);
  }

  return Changed;
}

class AMDGPULowerExecSyncLegacy : public ModulePass {
public:
  static char ID;
  AMDGPULowerExecSyncLegacy() : ModulePass(ID) {}
  bool runOnModule(Module &M) override;
};

} // namespace

char AMDGPULowerExecSyncLegacy::ID = 0;
char &llvm::AMDGPULowerExecSyncLegacyPassID = AMDGPULowerExecSyncLegacy::ID;

INITIALIZE_PASS_BEGIN(AMDGPULowerExecSyncLegacy, DEBUG_TYPE,
                      "AMDGPU lowering of execution synchronization", false,
                      false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_END(AMDGPULowerExecSyncLegacy, DEBUG_TYPE,
                    "AMDGPU lowering of execution synchronization", false,
                    false)

bool AMDGPULowerExecSyncLegacy::runOnModule(Module &M) {
  return runLowerExecSyncGlobals(M);
}

ModulePass *llvm::createAMDGPULowerExecSyncLegacyPass() {
  return new AMDGPULowerExecSyncLegacy();
}

PreservedAnalyses AMDGPULowerExecSyncPass::run(Module &M,
                                               ModuleAnalysisManager &AM) {
  return runLowerExecSyncGlobals(M) ? PreservedAnalyses::none()
                                    : PreservedAnalyses::all();
}
