//===- llvm-offload-wrapper: Create runtime registration code for devices -===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Provides a utility for generating runtime registration code for device code.
// We take a binary image (CUDA fatbinary, HIP offload bundle, LLVM binary) and
// create a new IR module that calls the respective runtime to load it on the
// device.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/Frontend/Offloading/OffloadWrapper.h"
#include "llvm/Frontend/Offloading/Utility.h"
#include "llvm/Object/OffloadBinary.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/WithColor.h"
#include "llvm/TargetParser/Host.h"

using namespace llvm;

static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);

static cl::OptionCategory
    OffloadWrapeprCategory("llvm-offload-wrapper options");

static cl::opt<object::OffloadKind> Kind(
    "kind", cl::desc("Wrap for offload kind:"), cl::cat(OffloadWrapeprCategory),
    cl::Required,
    cl::values(clEnumValN(object::OFK_OpenMP, "openmp", "Wrap OpenMP binaries"),
               clEnumValN(object::OFK_Cuda, "cuda", "Wrap CUDA binaries"),
               clEnumValN(object::OFK_HIP, "hip", "Wrap HIP binaries")));

static cl::opt<std::string> OutputFile("o", cl::desc("Write output to <file>."),
                                       cl::value_desc("file"),
                                       cl::cat(OffloadWrapeprCategory));

static cl::list<std::string> InputFiles(cl::Positional,
                                        cl::desc("Wrap input from <file>"),
                                        cl::value_desc("file"), cl::OneOrMore,
                                        cl::cat(OffloadWrapeprCategory));

static cl::opt<std::string>
    TheTriple("triple", cl::desc("Target triple for the wrapper module"),
              cl::init(sys::getDefaultTargetTriple()),
              cl::cat(OffloadWrapeprCategory));

static Error wrapImages(ArrayRef<ArrayRef<char>> BuffersToWrap) {
  if (BuffersToWrap.size() > 1 &&
      (Kind == llvm::object::OFK_Cuda || Kind == llvm::object::OFK_HIP))
    return createStringError(
        "CUDA / HIP offloading uses a single fatbinary or offload bundle");

  LLVMContext Context;
  Module M("offload.wrapper.module", Context);
  M.setTargetTriple(llvm::Triple(TheTriple));

  switch (Kind) {
  case llvm::object::OFK_OpenMP:
    if (Error Err = offloading::wrapOpenMPBinaries(
            M, BuffersToWrap, offloading::getOffloadEntryArray(M),
            /*Suffix=*/"", /*Relocatable=*/false))
      return Err;
    break;
  case llvm::object::OFK_Cuda:
    if (Error Err = offloading::wrapCudaBinary(
            M, BuffersToWrap.front(), offloading::getOffloadEntryArray(M),
            /*Suffix=*/"", /*EmitSurfacesAndTextures=*/false))
      return Err;
    break;
  case llvm::object::OFK_HIP:
    if (Error Err = offloading::wrapHIPBinary(
            M, BuffersToWrap.front(), offloading::getOffloadEntryArray(M)))
      return Err;
    break;
  case llvm::object::OFK_SYCL:
    if (Error Err = offloading::wrapSYCLBinaries(M, BuffersToWrap.front()))
      return Err;
    break;
  default:
    return createStringError(getOffloadKindName(Kind) +
                             " wrapping is not supported");
  }

  int FD = -1;
  if (std::error_code EC = sys::fs::openFileForWrite(OutputFile, FD))
    return errorCodeToError(EC);
  llvm::raw_fd_ostream OS(FD, true);
  WriteBitcodeToFile(M, OS);

  return Error::success();
}

int main(int argc, char **argv) {
  InitLLVM X(argc, argv);
  cl::HideUnrelatedOptions(OffloadWrapeprCategory);
  cl::ParseCommandLineOptions(
      argc, argv,
      "Generate runtime registration code for a device binary image\n");

  if (Help) {
    cl::PrintHelpMessage();
    return EXIT_SUCCESS;
  }

  auto ReportError = [argv](Error E) {
    logAllUnhandledErrors(std::move(E), WithColor::error(errs(), argv[0]));
    exit(EXIT_FAILURE);
  };

  SmallVector<std::unique_ptr<MemoryBuffer>> Buffers;
  SmallVector<ArrayRef<char>> BuffersToWrap;
  for (StringRef Input : InputFiles) {
    ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
        MemoryBuffer::getFileOrSTDIN(Input);
    if (std::error_code EC = BufferOrErr.getError())
      ReportError(createFileError(Input, EC));
    std::unique_ptr<MemoryBuffer> &Buffer =
        Buffers.emplace_back(std::move(*BufferOrErr));
    BuffersToWrap.emplace_back(
        ArrayRef<char>(Buffer->getBufferStart(), Buffer->getBufferSize()));
  }

  if (Error Err = wrapImages(BuffersToWrap))
    ReportError(std::move(Err));

  return EXIT_SUCCESS;
}
