//===- GlobalHandler.cpp - Target independent global & env. var handling --===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Target independent global handler and environment manager.
//
//===----------------------------------------------------------------------===//

#include "GlobalHandler.h"
#include "PluginInterface.h"
#include "Utils/ELF.h"

#include "Shared/Utils.h"

#include "llvm/ProfileData/InstrProfData.inc"
#include "llvm/Support/Error.h"

#include <cstring>
#include <string>

using namespace llvm;
using namespace omp;
using namespace target;
using namespace plugin;

Expected<std::unique_ptr<ObjectFile>>
GenericGlobalHandlerTy::getELFObjectFile(DeviceImageTy &Image) {
  assert(utils::elf::isELF(Image.getMemoryBuffer().getBuffer()) &&
         "Input is not an ELF file");

  return ELFObjectFileBase::createELFObjectFile(Image.getMemoryBuffer());
}

Error GenericGlobalHandlerTy::moveGlobalBetweenDeviceAndHost(
    GenericDeviceTy &Device, DeviceImageTy &Image, const GlobalTy &HostGlobal,
    bool Device2Host) {

  GlobalTy DeviceGlobal(HostGlobal.getName(), HostGlobal.getSize());

  // Get the metadata from the global on the device.
  if (auto Err = getGlobalMetadataFromDevice(Device, Image, DeviceGlobal))
    return Err;

  // Perform the actual transfer.
  return moveGlobalBetweenDeviceAndHost(Device, HostGlobal, DeviceGlobal,
                                        Device2Host);
}

/// Actually move memory between host and device. See readGlobalFromDevice and
/// writeGlobalToDevice for the interface description.
Error GenericGlobalHandlerTy::moveGlobalBetweenDeviceAndHost(
    GenericDeviceTy &Device, const GlobalTy &HostGlobal,
    const GlobalTy &DeviceGlobal, bool Device2Host) {

  // Transfer the data from the source to the destination.
  if (Device2Host) {
    if (auto Err =
            Device.dataRetrieve(HostGlobal.getPtr(), DeviceGlobal.getPtr(),
                                HostGlobal.getSize(), nullptr))
      return Err;
  } else {
    if (auto Err = Device.dataSubmit(DeviceGlobal.getPtr(), HostGlobal.getPtr(),
                                     HostGlobal.getSize(), nullptr))
      return Err;
  }

  DP("Successfully %s %u bytes associated with global symbol '%s' %s the "
     "device "
     "(%p -> %p).\n",
     Device2Host ? "read" : "write", HostGlobal.getSize(),
     HostGlobal.getName().data(), Device2Host ? "from" : "to",
     DeviceGlobal.getPtr(), HostGlobal.getPtr());

  return Plugin::success();
}

bool GenericGlobalHandlerTy::isSymbolInImage(GenericDeviceTy &Device,
                                             DeviceImageTy &Image,
                                             StringRef SymName) {
  // Get the ELF object file for the image. Notice the ELF object may already
  // be created in previous calls, so we can reuse it. If this is unsuccessful
  // just return false as we couldn't find it.
  auto ELFObjOrErr = getELFObjectFile(Image);
  if (!ELFObjOrErr) {
    consumeError(ELFObjOrErr.takeError());
    return false;
  }

  // Search the ELF symbol using the symbol name.
  auto SymOrErr = utils::elf::getSymbol(**ELFObjOrErr, SymName);
  if (!SymOrErr) {
    consumeError(SymOrErr.takeError());
    return false;
  }

  return SymOrErr->has_value();
}

Error GenericGlobalHandlerTy::getGlobalMetadataFromImage(
    GenericDeviceTy &Device, DeviceImageTy &Image, GlobalTy &ImageGlobal) {

  // Get the ELF object file for the image. Notice the ELF object may already
  // be created in previous calls, so we can reuse it.
  auto ELFObj = getELFObjectFile(Image);
  if (!ELFObj)
    return ELFObj.takeError();

  // Search the ELF symbol using the symbol name.
  auto SymOrErr = utils::elf::getSymbol(**ELFObj, ImageGlobal.getName());
  if (!SymOrErr)
    return Plugin::error("Failed ELF lookup of global '%s': %s",
                         ImageGlobal.getName().data(),
                         toString(SymOrErr.takeError()).data());

  if (!SymOrErr->has_value())
    return Plugin::error("Failed to find global symbol '%s' in the ELF image",
                         ImageGlobal.getName().data());

  auto AddrOrErr = utils::elf::getSymbolAddress(**SymOrErr);
  // Get the section to which the symbol belongs.
  if (!AddrOrErr)
    return Plugin::error("Failed to get ELF symbol from global '%s': %s",
                         ImageGlobal.getName().data(),
                         toString(AddrOrErr.takeError()).data());

  // Setup the global symbol's address and size.
  ImageGlobal.setPtr(const_cast<void *>(*AddrOrErr));
  ImageGlobal.setSize((*SymOrErr)->getSize());

  return Plugin::success();
}

Error GenericGlobalHandlerTy::readGlobalFromImage(GenericDeviceTy &Device,
                                                  DeviceImageTy &Image,
                                                  const GlobalTy &HostGlobal) {

  GlobalTy ImageGlobal(HostGlobal.getName(), -1);
  if (auto Err = getGlobalMetadataFromImage(Device, Image, ImageGlobal))
    return Err;

  if (ImageGlobal.getSize() != HostGlobal.getSize())
    return Plugin::error("Transfer failed because global symbol '%s' has "
                         "%u bytes in the ELF image but %u bytes on the host",
                         HostGlobal.getName().data(), ImageGlobal.getSize(),
                         HostGlobal.getSize());

  DP("Global symbol '%s' was found in the ELF image and %u bytes will copied "
     "from %p to %p.\n",
     HostGlobal.getName().data(), HostGlobal.getSize(), ImageGlobal.getPtr(),
     HostGlobal.getPtr());

  assert(Image.getStart() <= ImageGlobal.getPtr() &&
         utils::advancePtr(ImageGlobal.getPtr(), ImageGlobal.getSize()) <
             utils::advancePtr(Image.getStart(), Image.getSize()) &&
         "Attempting to read outside the image!");

  // Perform the copy from the image to the host memory.
  std::memcpy(HostGlobal.getPtr(), ImageGlobal.getPtr(), HostGlobal.getSize());

  return Plugin::success();
}

bool GenericGlobalHandlerTy::hasProfilingGlobals(GenericDeviceTy &Device,
                                                 DeviceImageTy &Image) {
  GlobalTy global(getInstrProfNamesVarName().str(), 0);
  if (auto Err = getGlobalMetadataFromImage(Device, Image, global)) {
    consumeError(std::move(Err));
    return false;
  }
  return true;
}

Expected<GPUProfGlobals>
GenericGlobalHandlerTy::readProfilingGlobals(GenericDeviceTy &Device,
                                             DeviceImageTy &Image) {
  GPUProfGlobals DeviceProfileData;
  auto ObjFile = getELFObjectFile(Image);
  if (!ObjFile)
    return ObjFile.takeError();

  std::unique_ptr<ELFObjectFileBase> ELFObj(
      static_cast<ELFObjectFileBase *>(ObjFile->release()));
  DeviceProfileData.TargetTriple = ELFObj->makeTriple();

  // Iterate through elf symbols
  for (auto &Sym : ELFObj->symbols()) {
    auto NameOrErr = Sym.getName();
    if (!NameOrErr)
      return NameOrErr.takeError();

    // Check if given current global is a profiling global based
    // on name
    if (*NameOrErr == getInstrProfNamesVarName()) {
      // Read in profiled function names
      DeviceProfileData.NamesData = SmallVector<uint8_t>(Sym.getSize(), 0);
      GlobalTy NamesGlobal(NameOrErr->str(), Sym.getSize(),
                           DeviceProfileData.NamesData.data());
      if (auto Err = readGlobalFromDevice(Device, Image, NamesGlobal))
        return Err;
    } else if (NameOrErr->starts_with(getInstrProfCountersVarPrefix())) {
      // Read global variable profiling counts
      SmallVector<int64_t> Counts(Sym.getSize() / sizeof(int64_t), 0);
      GlobalTy CountGlobal(NameOrErr->str(), Sym.getSize(), Counts.data());
      if (auto Err = readGlobalFromDevice(Device, Image, CountGlobal))
        return Err;
      DeviceProfileData.Counts.append(std::move(Counts));
    } else if (NameOrErr->starts_with(getInstrProfDataVarPrefix())) {
      // Read profiling data for this global variable
      __llvm_profile_data Data{};
      GlobalTy DataGlobal(NameOrErr->str(), Sym.getSize(), &Data);
      if (auto Err = readGlobalFromDevice(Device, Image, DataGlobal))
        return Err;
      DeviceProfileData.Data.push_back(std::move(Data));
    } else if (*NameOrErr == INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR)) {
      uint64_t RawVersionData;
      GlobalTy RawVersionGlobal(NameOrErr->str(), Sym.getSize(),
                                &RawVersionData);
      if (auto Err = readGlobalFromDevice(Device, Image, RawVersionGlobal))
        return Err;
      DeviceProfileData.Version = RawVersionData;
    }
  }
  return DeviceProfileData;
}

void GPUProfGlobals::dump() const {
  outs() << "======= GPU Profile =======\nTarget: " << TargetTriple.str()
         << "\n";

  outs() << "======== Counters =========\n";
  for (size_t i = 0; i < Counts.size(); i++) {
    if (i > 0 && i % 10 == 0)
      outs() << "\n";
    else if (i != 0)
      outs() << " ";
    outs() << Counts[i];
  }
  outs() << "\n";

  outs() << "========== Data ===========\n";
  for (const auto &ProfData : Data) {
    outs() << "{ ";
// The ProfData.Name maybe array, eg: NumValueSites[IPVK_Last+1] .
// If we print out it directly, we are accessing out of bound data.
// Skip dumping the array for now.
#define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer)                     \
  if (sizeof(#Name) > 2 && #Name[sizeof(#Name) - 2] == ']') {                  \
    outs() << "[...] ";                                                        \
  } else {                                                                     \
    outs() << ProfData.Name << " ";                                            \
  }
#include "llvm/ProfileData/InstrProfData.inc"
    outs() << "}\n";
  }

  outs() << "======== Functions ========\n";
  std::string s;
  s.reserve(NamesData.size());
  for (uint8_t Name : NamesData) {
    s.push_back((char)Name);
  }

  InstrProfSymtab Symtab;
  if (Error Err = Symtab.create(StringRef(s))) {
    consumeError(std::move(Err));
  }
  Symtab.dumpNames(outs());
  outs() << "===========================\n";
}

Error GPUProfGlobals::write() const {
  if (!__llvm_write_custom_profile)
    return Plugin::error("Could not find symbol __llvm_write_custom_profile. "
                         "The compiler-rt profiling library must be linked for "
                         "GPU PGO to work.");

  size_t DataSize = Data.size() * sizeof(__llvm_profile_data),
         CountsSize = Counts.size() * sizeof(int64_t);
  __llvm_profile_data *DataBegin, *DataEnd;
  char *CountersBegin, *CountersEnd, *NamesBegin, *NamesEnd;

  // Initialize array of contiguous data. We need to make sure each section is
  // contiguous so that the PGO library can compute deltas properly
  SmallVector<uint8_t> ContiguousData(NamesData.size() + DataSize + CountsSize);

  // Compute region pointers
  DataBegin = (__llvm_profile_data *)(ContiguousData.data() + CountsSize);
  DataEnd =
      (__llvm_profile_data *)(ContiguousData.data() + CountsSize + DataSize);
  CountersBegin = (char *)ContiguousData.data();
  CountersEnd = (char *)(ContiguousData.data() + CountsSize);
  NamesBegin = (char *)(ContiguousData.data() + CountsSize + DataSize);
  NamesEnd = (char *)(ContiguousData.data() + CountsSize + DataSize +
                      NamesData.size());

  // Copy data to contiguous buffer
  memcpy(DataBegin, Data.data(), DataSize);
  memcpy(CountersBegin, Counts.data(), CountsSize);
  memcpy(NamesBegin, NamesData.data(), NamesData.size());

  // Invoke compiler-rt entrypoint
  int result = __llvm_write_custom_profile(
      TargetTriple.str().c_str(), DataBegin, DataEnd, CountersBegin,
      CountersEnd, NamesBegin, NamesEnd, &Version);
  if (result != 0)
    return Plugin::error("Error writing GPU PGO data to file");

  return Plugin::success();
}
