//===- Utility.cpp ------ Collection of generic offloading utilities ------===//
//
// 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/Frontend/Offloading/Utility.h"
#include "llvm/BinaryFormat/AMDGPUMetadataVerifier.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/BinaryFormat/MsgPackDocument.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Value.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/OffloadBinary.h"
#include "llvm/ObjectYAML/yaml2obj.h"
#include "llvm/Support/MemoryBufferRef.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

using namespace llvm;
using namespace llvm::offloading;
using namespace llvm::offloading::sycl;

StructType *offloading::getEntryTy(Module &M) {
  LLVMContext &C = M.getContext();
  StructType *EntryTy =
      StructType::getTypeByName(C, "struct.__tgt_offload_entry");
  if (!EntryTy)
    EntryTy = StructType::create(
        "struct.__tgt_offload_entry", Type::getInt64Ty(C), Type::getInt16Ty(C),
        Type::getInt16Ty(C), Type::getInt32Ty(C), PointerType::getUnqual(C),
        PointerType::getUnqual(C), Type::getInt64Ty(C), Type::getInt64Ty(C),
        PointerType::getUnqual(C));
  return EntryTy;
}

std::pair<Constant *, GlobalVariable *>
offloading::getOffloadingEntryInitializer(Module &M, object::OffloadKind Kind,
                                          Constant *Addr, StringRef Name,
                                          uint64_t Size, uint32_t Flags,
                                          uint64_t Data, Constant *AuxAddr) {
  const llvm::Triple &Triple = M.getTargetTriple();
  Type *PtrTy = PointerType::getUnqual(M.getContext());
  Type *Int64Ty = Type::getInt64Ty(M.getContext());
  Type *Int32Ty = Type::getInt32Ty(M.getContext());
  Type *Int16Ty = Type::getInt16Ty(M.getContext());

  Constant *AddrName = ConstantDataArray::getString(M.getContext(), Name);

  StringRef Prefix =
      Triple.isNVPTX() ? "$offloading$entry_name" : ".offloading.entry_name";

  // Create the constant string used to look up the symbol in the device.
  auto *Str =
      new GlobalVariable(M, AddrName->getType(), /*isConstant=*/true,
                         GlobalValue::InternalLinkage, AddrName, Prefix);
  StringRef SectionName = ".llvm.rodata.offloading";
  Str->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
  Str->setSection(SectionName);
  Str->setAlignment(Align(1));

  // Make a metadata node for these constants so it can be queried from IR.
  NamedMDNode *MD = M.getOrInsertNamedMetadata("llvm.offloading.symbols");
  Metadata *MDVals[] = {ConstantAsMetadata::get(Str)};
  MD->addOperand(llvm::MDNode::get(M.getContext(), MDVals));

  // Construct the offloading entry.
  Constant *EntryData[] = {
      ConstantExpr::getNullValue(Int64Ty),
      ConstantInt::get(Int16Ty, 1),
      ConstantInt::get(Int16Ty, Kind),
      ConstantInt::get(Int32Ty, Flags),
      ConstantExpr::getPointerBitCastOrAddrSpaceCast(Addr, PtrTy),
      ConstantExpr::getPointerBitCastOrAddrSpaceCast(Str, PtrTy),
      ConstantInt::get(Int64Ty, Size),
      ConstantInt::get(Int64Ty, Data),
      AuxAddr ? ConstantExpr::getPointerBitCastOrAddrSpaceCast(AuxAddr, PtrTy)
              : ConstantExpr::getNullValue(PtrTy)};
  Constant *EntryInitializer = ConstantStruct::get(getEntryTy(M), EntryData);
  return {EntryInitializer, Str};
}

StringRef offloading::getOffloadEntrySection(Module &M) {
  return M.getTargetTriple().isOSBinFormatMachO() ? "__LLVM,offload_entries"
                                                  : "llvm_offload_entries";
}

/// Returns the start/end symbol names for iterating offloading entries in a
/// given section. Mach-O uses \1section$start$/\1section$end$ convention;
/// ELF/COFF use __start_/__stop_ prefixes.
static std::pair<std::string, std::string>
getOffloadEntryBoundarySymbols(const Triple &T, StringRef SectionName) {
  if (T.isOSBinFormatMachO()) {
    std::string SymSection = SectionName.str();
    std::replace(SymSection.begin(), SymSection.end(), ',', '$');
    return {"\1section$start$" + SymSection, "\1section$end$" + SymSection};
  }
  return {("__start_" + SectionName).str(), ("__stop_" + SectionName).str()};
}

GlobalVariable *offloading::emitOffloadingEntry(
    Module &M, object::OffloadKind Kind, Constant *Addr, StringRef Name,
    uint64_t Size, uint32_t Flags, uint64_t Data, Constant *AuxAddr) {
  const llvm::Triple &Triple = M.getTargetTriple();
  StringRef SectionName = getOffloadEntrySection(M);

  auto [EntryInitializer, NameGV] = getOffloadingEntryInitializer(
      M, Kind, Addr, Name, Size, Flags, Data, AuxAddr);

  StringRef Prefix =
      Triple.isNVPTX() ? "$offloading$entry$" : ".offloading.entry.";
  auto *Entry = new GlobalVariable(
      M, getEntryTy(M),
      /*isConstant=*/true, GlobalValue::WeakAnyLinkage, EntryInitializer,
      Prefix + Name, nullptr, GlobalValue::NotThreadLocal,
      M.getDataLayout().getDefaultGlobalsAddressSpace());

  // The entry has to be created in the section the linker expects it to be.
  if (Triple.isOSBinFormatCOFF())
    Entry->setSection((SectionName + "$OE").str());
  else
    Entry->setSection(SectionName);
  Entry->setAlignment(Align(object::OffloadBinary::getAlignment()));
  return Entry;
}

std::pair<Constant *, Constant *> offloading::getOffloadEntryArray(Module &M) {
  const llvm::Triple &Triple = M.getTargetTriple();
  StringRef SectionName = getOffloadEntrySection(M);

  constexpr unsigned COFFSentinelEntryCount = 1;
  unsigned EntryCount =
      Triple.isOSBinFormatCOFF() ? COFFSentinelEntryCount : 0u;
  auto *ZeroInitializer =
      ConstantAggregateZero::get(ArrayType::get(getEntryTy(M), EntryCount));
  auto *EntryInit = Triple.isOSBinFormatCOFF() ? ZeroInitializer : nullptr;
  auto *EntryType = ZeroInitializer->getType();
  auto Linkage = Triple.isOSBinFormatCOFF() ? GlobalValue::WeakODRLinkage
                                            : GlobalValue::ExternalLinkage;

  auto [StartName, StopName] =
      getOffloadEntryBoundarySymbols(Triple, SectionName);

  auto *EntriesB = new GlobalVariable(M, EntryType, /*isConstant=*/true,
                                      Linkage, EntryInit, StartName);
  EntriesB->setVisibility(GlobalValue::HiddenVisibility);
  auto *EntriesE = new GlobalVariable(M, EntryType, /*isConstant=*/true,
                                      Linkage, EntryInit, StopName);
  EntriesE->setVisibility(GlobalValue::HiddenVisibility);

  if (Triple.isOSBinFormatELF()) {
    // We assume that external begin/end symbols that we have created above will
    // be defined by the linker. This is done whenever a section name with a
    // valid C-identifier is present. We define a dummy variable here to force
    // the linker to always provide these symbols.
    auto *DummyEntry = new GlobalVariable(
        M, ZeroInitializer->getType(), true, GlobalVariable::InternalLinkage,
        ZeroInitializer, "__dummy." + SectionName);
    DummyEntry->setSection(SectionName);
    DummyEntry->setAlignment(Align(object::OffloadBinary::getAlignment()));
    appendToUsed(M, DummyEntry);
  } else if (Triple.isOSBinFormatMachO()) {
    // Mach-O needs a dummy variable in the section (like ELF) to ensure the
    // linker provides the section boundary symbols. Mark it used so the
    // section survives dead-stripping.
    auto *DummyEntry = new GlobalVariable(
        M, ZeroInitializer->getType(), true, GlobalVariable::InternalLinkage,
        ZeroInitializer, "__dummy." + SectionName);
    DummyEntry->setSection(SectionName);
    DummyEntry->setAlignment(Align(object::OffloadBinary::getAlignment()));
    appendToUsed(M, DummyEntry);
  } else {
    // The COFF linker will merge sections containing a '$' together into a
    // single section. The order of entries in this section will be sorted
    // alphabetically by the characters following the '$' in the name. Set the
    // sections here to ensure that the beginning and end symbols are sorted.
    EntriesB->setSection((SectionName + "$OA").str());
    EntriesE->setSection((SectionName + "$OZ").str());
    EntriesB->setAlignment(Align(object::OffloadBinary::getAlignment()));
    EntriesE->setAlignment(Align(object::OffloadBinary::getAlignment()));

    // COFF lays out offload entries by sorted subsections: $OA is a synthetic
    // begin sentinel, $OE contains real entries, and $OZ is a synthetic end
    // sentinel. Keep the boundary sections non-empty so lld-link does not
    // discard them under /opt:ref, but skip the begin sentinel for runtime
    // users.
    Type *Int32Ty = Type::getInt32Ty(M.getContext());
    Constant *Indices[] = {ConstantInt::get(Int32Ty, 0),
                           ConstantInt::get(Int32Ty, COFFSentinelEntryCount)};
    Constant *BeginAfterSentinel = ConstantExpr::getGetElementPtr(
        M.getDataLayout(), EntriesB->getValueType(), EntriesB, Indices,
        GEPNoWrapFlags::inBounds());
    return std::make_pair(BeginAfterSentinel, EntriesE);
  }

  return std::make_pair(EntriesB, EntriesE);
}

bool llvm::offloading::amdgpu::isImageCompatibleWithEnv(StringRef ImageArch,
                                                        uint32_t ImageFlags,
                                                        StringRef EnvTargetID) {
  using namespace llvm::ELF;
  StringRef EnvArch = EnvTargetID.split(":").first;

  // Trivial check if the base processors match.
  if (EnvArch != ImageArch)
    return false;

  // Check if the image is requesting xnack on or off.
  switch (ImageFlags & EF_AMDGPU_FEATURE_XNACK_V4) {
  case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
    // The image is 'xnack-' so the environment must be 'xnack-'.
    if (!EnvTargetID.contains("xnack-"))
      return false;
    break;
  case EF_AMDGPU_FEATURE_XNACK_ON_V4:
    // The image is 'xnack+' so the environment must be 'xnack+'.
    if (!EnvTargetID.contains("xnack+"))
      return false;
    break;
  case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
  case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
  default:
    break;
  }

  // Check if the image is requesting sramecc on or off.
  switch (ImageFlags & EF_AMDGPU_FEATURE_SRAMECC_V4) {
  case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
    // The image is 'sramecc-' so the environment must be 'sramecc-'.
    if (!EnvTargetID.contains("sramecc-"))
      return false;
    break;
  case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
    // The image is 'sramecc+' so the environment must be 'sramecc+'.
    if (!EnvTargetID.contains("sramecc+"))
      return false;
    break;
  case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
  case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
    break;
  }

  return true;
}

namespace {
/// Reads the AMDGPU specific per-kernel-metadata from an image.
class KernelInfoReader {
public:
  KernelInfoReader(StringMap<offloading::amdgpu::AMDGPUKernelMetaData> &KIM)
      : KernelInfoMap(KIM) {}

  /// Process ELF note to read AMDGPU metadata from respective information
  /// fields.
  Error processNote(const llvm::object::ELF64LE::Note &Note, size_t Align) {
    if (Note.getName() != "AMDGPU")
      return Error::success(); // We are not interested in other things

    assert(Note.getType() == ELF::NT_AMDGPU_METADATA &&
           "Parse AMDGPU MetaData");
    auto Desc = Note.getDesc(Align);
    StringRef MsgPackString =
        StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
    msgpack::Document MsgPackDoc;
    if (!MsgPackDoc.readFromBlob(MsgPackString, /*Multi=*/false))
      return Error::success();

    AMDGPU::HSAMD::V3::MetadataVerifier Verifier(true);
    if (!Verifier.verify(MsgPackDoc.getRoot()))
      return Error::success();

    auto RootMap = MsgPackDoc.getRoot().getMap(true);

    if (auto Err = iterateAMDKernels(RootMap))
      return Err;

    return Error::success();
  }

private:
  /// Extracts the relevant information via simple string look-up in the msgpack
  /// document elements.
  Error
  extractKernelData(msgpack::MapDocNode::MapTy::value_type V,
                    std::string &KernelName,
                    offloading::amdgpu::AMDGPUKernelMetaData &KernelData) {
    if (!V.first.isString())
      return Error::success();

    const auto IsKey = [](const msgpack::DocNode &DK, StringRef SK) {
      return DK.getString() == SK;
    };

    const auto GetSequenceOfThreeInts = [](msgpack::DocNode &DN,
                                           uint32_t *Vals) {
      assert(DN.isArray() && "MsgPack DocNode is an array node");
      auto DNA = DN.getArray();
      assert(DNA.size() == 3 && "ArrayNode has at most three elements");

      int I = 0;
      for (auto DNABegin = DNA.begin(), DNAEnd = DNA.end(); DNABegin != DNAEnd;
           ++DNABegin) {
        Vals[I++] = DNABegin->getUInt();
      }
    };

    if (IsKey(V.first, ".name")) {
      KernelName = V.second.toString();
    } else if (IsKey(V.first, ".sgpr_count")) {
      KernelData.SGPRCount = V.second.getUInt();
    } else if (IsKey(V.first, ".sgpr_spill_count")) {
      KernelData.SGPRSpillCount = V.second.getUInt();
    } else if (IsKey(V.first, ".vgpr_count")) {
      KernelData.VGPRCount = V.second.getUInt();
    } else if (IsKey(V.first, ".vgpr_spill_count")) {
      KernelData.VGPRSpillCount = V.second.getUInt();
    } else if (IsKey(V.first, ".agpr_count")) {
      KernelData.AGPRCount = V.second.getUInt();
    } else if (IsKey(V.first, ".private_segment_fixed_size")) {
      KernelData.PrivateSegmentSize = V.second.getUInt();
    } else if (IsKey(V.first, ".group_segment_fixed_size")) {
      KernelData.GroupSegmentList = V.second.getUInt();
    } else if (IsKey(V.first, ".reqd_workgroup_size")) {
      GetSequenceOfThreeInts(V.second, KernelData.RequestedWorkgroupSize);
    } else if (IsKey(V.first, ".workgroup_size_hint")) {
      GetSequenceOfThreeInts(V.second, KernelData.WorkgroupSizeHint);
    } else if (IsKey(V.first, ".wavefront_size")) {
      KernelData.WavefrontSize = V.second.getUInt();
    } else if (IsKey(V.first, ".max_flat_workgroup_size")) {
      KernelData.MaxFlatWorkgroupSize = V.second.getUInt();
    } else if (IsKey(V.first, ".args")) {
      auto ArgsArray = V.second.getArray();
      for (auto ArgIt = ArgsArray.begin(), ArgEnd = ArgsArray.end();
           ArgIt != ArgEnd; ++ArgIt) {
        auto ArgMap = ArgIt->getMap();

        auto OffsetIt = ArgMap.find(".offset");
        if (OffsetIt == ArgMap.end())
          return createStringError(
              inconvertibleErrorCode(),
              "Missing required .offset key in kernel argument metadata map");

        auto SizeIt = ArgMap.find(".size");
        if (SizeIt == ArgMap.end())
          return createStringError(
              inconvertibleErrorCode(),
              "Missing required .size key in kernel argument metadata map");

        KernelData.ArgMDs.emplace_back(OffsetIt->second.getUInt(),
                                       SizeIt->second.getUInt());
      }
    }

    return Error::success();
  }

  /// Get the "amdhsa.kernels" element from the msgpack Document
  Expected<msgpack::ArrayDocNode> getAMDKernelsArray(msgpack::MapDocNode &MDN) {
    auto Res = MDN.find("amdhsa.kernels");
    if (Res == MDN.end())
      return createStringError(inconvertibleErrorCode(),
                               "Could not find amdhsa.kernels key");

    auto Pair = *Res;
    assert(Pair.second.isArray() &&
           "AMDGPU kernel entries are arrays of entries");

    return Pair.second.getArray();
  }

  /// Iterate all entries for one "amdhsa.kernels" entry. Each entry is a
  /// MapDocNode that either maps a string to a single value (most of them) or
  /// to another array of things. Currently, we only handle the case that maps
  /// to scalar value.
  Error generateKernelInfo(msgpack::ArrayDocNode::ArrayTy::iterator It) {
    offloading::amdgpu::AMDGPUKernelMetaData KernelData;
    std::string KernelName;
    auto Entry = (*It).getMap();
    for (auto MI = Entry.begin(), E = Entry.end(); MI != E; ++MI)
      if (auto Err = extractKernelData(*MI, KernelName, KernelData))
        return Err;

    KernelInfoMap.insert({KernelName, KernelData});
    return Error::success();
  }

  /// Go over the list of AMD kernels in the "amdhsa.kernels" entry
  Error iterateAMDKernels(msgpack::MapDocNode &MDN) {
    auto KernelsOrErr = getAMDKernelsArray(MDN);
    if (auto Err = KernelsOrErr.takeError())
      return Err;

    auto KernelsArr = *KernelsOrErr;
    for (auto It = KernelsArr.begin(), E = KernelsArr.end(); It != E; ++It) {
      if (!It->isMap())
        continue; // we expect <key,value> pairs

      // Obtain the value for the different entries. Each array entry is a
      // MapDocNode
      if (auto Err = generateKernelInfo(It))
        return Err;
    }
    return Error::success();
  }

  // Kernel names are the keys
  StringMap<offloading::amdgpu::AMDGPUKernelMetaData> &KernelInfoMap;
};
} // namespace

Error llvm::offloading::amdgpu::getAMDGPUMetaDataFromImage(
    MemoryBufferRef MemBuffer,
    StringMap<offloading::amdgpu::AMDGPUKernelMetaData> &KernelInfoMap,
    uint16_t &ELFABIVersion) {
  Error Err = Error::success(); // Used later as out-parameter

  auto ELFOrError = object::ELF64LEFile::create(MemBuffer.getBuffer());
  if (auto Err = ELFOrError.takeError())
    return Err;

  const object::ELF64LEFile ELFObj = ELFOrError.get();
  Expected<ArrayRef<object::ELF64LE::Shdr>> Sections = ELFObj.sections();
  if (!Sections)
    return Sections.takeError();
  KernelInfoReader Reader(KernelInfoMap);

  // Read the code object version from ELF image header
  auto Header = ELFObj.getHeader();
  ELFABIVersion = (uint8_t)(Header.e_ident[ELF::EI_ABIVERSION]);
  for (const auto &S : *Sections) {
    if (S.sh_type != ELF::SHT_NOTE)
      continue;

    for (const auto N : ELFObj.notes(S, Err)) {
      if (Err)
        return Err;
      // Fills the KernelInfoTabel entries in the reader
      if ((Err = Reader.processNote(N, S.sh_addralign)))
        return Err;
    }
  }
  return Error::success();
}

Error offloading::containerizeImage(std::unique_ptr<MemoryBuffer> &Img,
                                    llvm::Triple Triple,
                                    object::ImageKind ImageKind,
                                    object::OffloadKind OffloadKind,
                                    int32_t ImageFlags,
                                    MapVector<StringRef, StringRef> &MetaData) {
  using namespace object;

  // Create inner OffloadBinary containing the raw image.
  OffloadBinary::OffloadingImage InnerImage;
  InnerImage.TheImageKind = ImageKind;
  InnerImage.TheOffloadKind = OffloadKind;
  InnerImage.Flags = ImageFlags;

  InnerImage.StringData["triple"] = Triple.getTriple();
  for (const auto &[Key, Value] : MetaData)
    InnerImage.StringData[Key] = Value;

  InnerImage.Image = std::move(Img);

  SmallString<0> InnerBinaryData = OffloadBinary::write(InnerImage);

  Img = MemoryBuffer::getMemBufferCopy(InnerBinaryData);
  return Error::success();
}

Error offloading::intel::containerizeOpenMPSPIRVImage(
    std::unique_ptr<MemoryBuffer> &Binary, llvm::Triple Triple,
    StringRef CompileOpts, StringRef LinkOpts) {
  constexpr char INTEL_ONEOMP_OFFLOAD_VERSION[] = "1.0";

  assert(Triple.isSPIRV() && Triple.getVendor() == llvm::Triple::Intel &&
         "Expected SPIR-V triple with Intel vendor");

  MapVector<StringRef, StringRef> MetaData;
  MetaData["version"] = INTEL_ONEOMP_OFFLOAD_VERSION;
  if (!CompileOpts.empty())
    MetaData["compile-opts"] = CompileOpts;
  if (!LinkOpts.empty())
    MetaData["link-opts"] = LinkOpts;

  return containerizeImage(Binary, Triple, object::ImageKind::IMG_SPIRV,
                           object::OffloadKind::OFK_OpenMP, /*ImageFlags=*/0,
                           MetaData);
}

void sycl::writeSymbolTable(ArrayRef<StringRef> Names, SmallString<0> &Out) {
  uint32_t Count = Names.size();

  // Compute the byte offset where string data begins: right after the header
  // and the entry array.
  uint32_t StringDataOffset =
      sizeof(SymbolTableHeader) + Count * sizeof(SymbolTableEntry);

  // Compute total size and reserve to prevent reallocation while writing
  // entries via pointer (append() could otherwise invalidate the pointer).
  uint32_t TotalSize = StringDataOffset;
  for (StringRef N : Names)
    TotalSize += N.size() + 1;
  Out.reserve(TotalSize);
  Out.resize(StringDataOffset);

  // Write the header.
  auto *Header = reinterpret_cast<SymbolTableHeader *>(Out.data());
  Header->Count = Count;

  // Write each entry and append the corresponding null-terminated name.
  auto *Entries = reinterpret_cast<SymbolTableEntry *>(Header + 1);
  uint32_t CurrentOffset = StringDataOffset;
  for (uint32_t I = 0; I < Count; ++I) {
    Entries[I].OffsetToSymbol = CurrentOffset;
    Entries[I].SymbolSize = Names[I].size();
    Out.append(Names[I]);
    Out.push_back('\0');
    CurrentOffset += Names[I].size() + 1;
  }
}
