// Copyright 2018 The Clspv Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "clang/Basic/FileManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CodeGenAction.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/InitializePasses.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/Linker/Linker.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/StandardInstrumentations.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/InstCombine/InstCombine.h"
#include "llvm/Transforms/Scalar/DCE.h"
#include "llvm/Transforms/Scalar/InferAddressSpaces.h"
#include "llvm/Transforms/Scalar/SROA.h"
#include "llvm/Transforms/Scalar/StructurizeCFG.h"
#include "llvm/Transforms/Utils/LowerSwitch.h"
#include "llvm/Transforms/Utils/Mem2Reg.h"

#include "clspv/AddressSpace.h"
#include "clspv/Compiler.h"
#include "clspv/Option.h"
#include "clspv/Passes.h"
#include "clspv/Sampler.h"
#include "clspv/clspv64_builtin_library.h"
#include "clspv/clspv_builtin_library.h"
#include "clspv/opencl_builtins_header.h"

#include "Builtins.h"
#include "BuiltinsEnum.h"
#include "Constants.h"
#include "FrontendPlugin.h"
#include "Passes.h"
#include "Types.h"

#include <cassert>
#include <fstream>
#include <iostream>
#include <numeric>
#include <ostream>
#include <sstream>
#include <string>

using namespace clang;

namespace {
enum class SPIRVArch : uint32_t {
  SPIRV32 = 0,
  SPIRV64,
};

// This registration must be located in the same file as the execution of the
// action.
static FrontendPluginRegistry::Add<clspv::ExtraValidationASTAction>
    X("extra-validation",
      "Perform extra validation on OpenCL C when targeting Vulkan");
static FrontendPluginRegistry::Add<clspv::EntryPointAttrsASTAction>
    Y("attr-information-getting", "get those attrs");

static llvm::cl::opt<bool> cl_single_precision_constants(
    "cl-single-precision-constant", llvm::cl::init(false),
    llvm::cl::desc("Treat double precision floating-point constant as single "
                   "precision constant."));

// This option has not effect. Mainly because of lack of expresiveness. Instead
// use `-denorm-preserve` and `-denorm-flush-to-zero`.
static llvm::cl::opt<bool> cl_denorms_are_zero(
    "cl-denorms-are-zero", llvm::cl::init(false),
    llvm::cl::desc("If specified, denormalized floating point numbers may be "
                   "flushed to zero."));

static llvm::cl::opt<bool> cl_fp32_correctly_rounded_divide_sqrt(
    "cl-fp32-correctly-rounded-divide-sqrt", llvm::cl::init(false),
    llvm::cl::desc("Single precision floating-point divide (x/y and 1/x) and "
                   "sqrt used are correctly rounded."));

static llvm::cl::opt<bool>
    cl_opt_disable("cl-opt-disable", llvm::cl::init(false),
                   llvm::cl::desc("This option disables all optimizations. The "
                                  "default is optimizations are enabled."));

static llvm::cl::opt<bool> cl_no_signed_zeros(
    "cl-no-signed-zeros", llvm::cl::init(false),
    llvm::cl::desc("Allow optimizations for floating-point arithmetic that "
                   "ignore the signedness of zero."));

static llvm::cl::list<std::string>
    Includes(llvm::cl::Prefix, "I",
             llvm::cl::desc("Add a directory to the list of directories "
                            "to be searched for header files."),
             llvm::cl::ZeroOrMore, llvm::cl::value_desc("include path"));

static llvm::cl::list<std::string>
    Defines(llvm::cl::Prefix, "D",
            llvm::cl::desc("Define a #define directive."), llvm::cl::ZeroOrMore,
            llvm::cl::value_desc("define"));

static llvm::cl::list<std::string>
    InputsFilename(llvm::cl::Positional, llvm::cl::desc("<input files>"),
                   llvm::cl::ZeroOrMore);

static llvm::cl::opt<clang::Language> InputLanguage(
    "x", llvm::cl::desc("Select input type"),
    llvm::cl::init(clang::Language::OpenCL),
    llvm::cl::values(clEnumValN(clang::Language::OpenCL, "cl", "OpenCL source"),
                     clEnumValN(clang::Language::LLVM_IR, "ir", "LLVM IR")));

static llvm::cl::opt<std::string>
    OutputFilename("o", llvm::cl::desc("Override output filename"),
                   llvm::cl::value_desc("filename"));

static llvm::cl::opt<char>
    OptimizationLevel(llvm::cl::Prefix, "O", llvm::cl::init('2'),
                      llvm::cl::desc("Optimization level to use"),
                      llvm::cl::value_desc("level"));

static llvm::cl::opt<bool> verify("verify", llvm::cl::init(false),
                                  llvm::cl::desc("Verify diagnostic outputs"));

static llvm::cl::opt<bool>
    IgnoreWarnings("w", llvm::cl::init(false),
                   llvm::cl::desc("Disable all warnings"));

static llvm::cl::opt<bool>
    WarningsAsErrors("Werror", llvm::cl::init(false),
                     llvm::cl::desc("Turn warnings into errors"));

enum OutputFormat {
  OutputFormatLLVMIR,
  OutputFormatLLVMIRBinary,
  OutputFormatSPIRV,
  OutputFormatC,
};

static llvm::cl::opt<enum OutputFormat> OutputFormat(
    "output-format", llvm::cl::desc("Select output format (ll|bc|spv|c)"),
    llvm::cl::init(OutputFormatSPIRV),
    llvm::cl::values(
        clEnumValN(OutputFormatSPIRV, "spv", "Vulkan SPIR-V"),
        clEnumValN(
            OutputFormatLLVMIR, "ll",
            "Readable LLVM IR (Stop compilation before clspv specific passes)"),
        clEnumValN(
            OutputFormatLLVMIRBinary, "bc",
            "Binary LLVM IR (Stop compilation before clspv specific passes)"),
        clEnumValN(OutputFormatC, "c",
                   "C initializer list (of Vulkan SPIR-V)")));

static llvm::cl::opt<SPIRVArch> target_arch(
    "arch", llvm::cl::desc("Specify the target SPIRV architecture"),
    llvm::cl::init(SPIRVArch::SPIRV32),
    llvm::cl::values(
        clEnumValN(SPIRVArch::SPIRV32, "spirv32",
                   "spirv32-unknown-vulkan target (pointers are 32-bit)"),
        clEnumValN(SPIRVArch::SPIRV64, "spirv64",
                   "spirv64-unknown-vulkan target (pointers are 64-bit)"),
        // Legacy options: kept for compatibility, omitted from standard help
        // text
        clEnumValN(SPIRVArch::SPIRV32, "spir", ""),
        clEnumValN(SPIRVArch::SPIRV64, "spir64", "")));

namespace {
struct OpenCLBuiltinMemoryBuffer final : public llvm::MemoryBuffer {
  OpenCLBuiltinMemoryBuffer(const void *data, uint64_t data_length) {
    const char *dataCasted = reinterpret_cast<const char *>(data);
    init(dataCasted, dataCasted + data_length, true);
  }

  virtual llvm::MemoryBuffer::BufferKind getBufferKind() const override {
    return llvm::MemoryBuffer::MemoryBuffer_Malloc;
  }

  virtual ~OpenCLBuiltinMemoryBuffer() override {}
};
} // namespace

clang::TargetInfo *PrepareTargetInfo(CompilerInstance &instance) {
  // Create target info
  auto TargetInfo = clang::TargetInfo::CreateTargetInfo(
      instance.getDiagnostics(), instance.getTargetOpts());

  // The SPIR target enables all possible options, disable the ones we don't
  // want
  auto &Opts = TargetInfo->getSupportedOpenCLOpts();

  // Conditionally disable extensions based on support
  if (!clspv::Option::FP16()) {
    Opts["cl_khr_fp16"] = false;
  }
  if (!clspv::Option::FP64()) {
    Opts["cl_khr_fp64"] = false;
  }
  // Enable/Disable CL3.0 feature macros for unsupported features
  if (instance.getLangOpts().LangStd == clang::LangStandard::lang_opencl30) {

    auto EnabledFeatureMacros = clspv::Option::EnabledFeatureMacros();
    // overwrite feature macro list for certain options
    if (clspv::Option::FP64()) {
      EnabledFeatureMacros.insert(clspv::FeatureMacro::__opencl_c_fp64);
    }
    if (clspv::Option::ImageSupport()) {
      EnabledFeatureMacros.insert(clspv::FeatureMacro::__opencl_c_images);
    }

    // TODO remove when feature macros are added to OpenCLExtensions.def
    // https://github.com/llvm/llvm-project/blob/main/clang/include/clang/Basic/OpenCLExtensions.def#L119
    constexpr std::array<clspv::FeatureMacro, 5> specialDefines{
        clspv::FeatureMacro::__opencl_c_atomic_scope_device,
        clspv::FeatureMacro::__opencl_c_atomic_scope_all_devices,
        clspv::FeatureMacro::__opencl_c_work_group_collective_functions,
        clspv::FeatureMacro::__opencl_c_integer_dot_product_input_4x8bit,
        clspv::FeatureMacro::__opencl_c_integer_dot_product_input_4x8bit_packed,
    };

    const auto featureList = clspv::FeatureMacroList;
    for (auto [feat, str] : featureList) {
      const bool enabled =
          std::find(EnabledFeatureMacros.cbegin(), EnabledFeatureMacros.cend(),
                    feat) != EnabledFeatureMacros.cend();
      Opts[str] = enabled;

      if (std::count(specialDefines.cbegin(), specialDefines.cend(), feat) &&
          enabled) {
        instance.getPreprocessorOpts().addMacroDef(str);
      }
      if (feat == clspv::FeatureMacro::__opencl_c_int64 && !enabled){
        instance.getPreprocessorOpts().addMacroUndef(str);
      }
    }
  }
  return TargetInfo;
}

// Sets |instance|'s options for compiling. Returns 0 if successful.
int SetCompilerInstanceOptions(
    CompilerInstance &instance, const llvm::StringRef &overiddenInputFilename,
    clang::FrontendInputFile &kernelFile, const std::string &program,
    const std::vector<std::pair<std::string, std::string>> &headers,
    std::unique_ptr<llvm::MemoryBuffer> &file_memory_buffer,
    llvm::raw_string_ostream *diagnosticsStream) {
  if (program.empty()) {
    return -1;
  }
  file_memory_buffer =
      llvm::MemoryBuffer::getMemBuffer(program, overiddenInputFilename);

  if (verify) {
    instance.getDiagnosticOpts().VerifyDiagnostics = true;
    instance.getDiagnosticOpts().VerifyPrefixes.push_back("expected");
  }

  clang::LangStandard::Kind standard;
  switch (clspv::Option::Language()) {
  case clspv::Option::SourceLanguage::OpenCL_C_10:
    standard = clang::LangStandard::lang_opencl10;
    break;
  case clspv::Option::SourceLanguage::OpenCL_C_11:
    standard = clang::LangStandard::lang_opencl11;
    break;
  case clspv::Option::SourceLanguage::OpenCL_C_12:
    standard = clang::LangStandard::lang_opencl12;
    break;
  case clspv::Option::SourceLanguage::OpenCL_C_20:
    standard = clang::LangStandard::lang_opencl20;
    break;
  case clspv::Option::SourceLanguage::OpenCL_C_30:
    standard = clang::LangStandard::lang_opencl30;
    break;
  case clspv::Option::SourceLanguage::OpenCL_C_31:
    standard = clang::LangStandard::lang_opencl31;
    break;
  case clspv::Option::SourceLanguage::OpenCL_CPP:
    standard = clang::LangStandard::lang_openclcpp10;
    break;
  case clspv::Option::SourceLanguage::OpenCL_CPP_2021:
    standard = clang::LangStandard::lang_openclcpp2021;
    break;
  default:
    llvm_unreachable("Unknown source language");
  }

  instance.getLangOpts().C99 = true;
  instance.getLangOpts().RTTI = false;
  instance.getLangOpts().RTTIData = false;
  instance.getLangOpts().MathErrno = false;
  instance.getLangOpts().NoBuiltin = true;
  instance.getLangOpts().ModulesSearchAll = false;
  instance.getLangOpts().SinglePrecisionConstants = true;
  instance.getLangOpts().DeclareOpenCLBuiltins = true;
  if (clspv::Option::FP16()) {
    instance.getLangOpts().NativeHalfType = true;
    instance.getLangOpts().NativeHalfArgsAndReturns = true;
  }
  // FP32 denormal mode
  switch (clspv::Option::ExecutionModeDenorm(
      clspv::Option::FloatingPointType::fp32)) {
  case clspv::Option::DenormMode::preserve:
    instance.getCodeGenOpts().FP32DenormalMode = llvm::DenormalMode::getIEEE();
    break;
  case clspv::Option::DenormMode::flush_to_zero:
    instance.getCodeGenOpts().FP32DenormalMode =
        llvm::DenormalMode::getPreserveSign();
    break;
  case clspv::Option::DenormMode::unspecified:
    instance.getCodeGenOpts().FP32DenormalMode =
        llvm::DenormalMode::getDynamic();
    break;
  case clspv::Option::DenormMode::error:
    llvm_unreachable("Invalid DenormMode");
  }

  // FPDenormalMode (for 16 and 64)
  clspv::Option::DenormMode mode = clspv::Option::DenormMode::error;
  auto modefp16 = clspv::Option::ExecutionModeDenorm(
      clspv::Option::FloatingPointType::fp16);
  auto modefp64 = clspv::Option::ExecutionModeDenorm(
      clspv::Option::FloatingPointType::fp64);
  if (modefp16 == modefp64) {
    mode = modefp16;
  } else if (modefp16 == clspv::Option::DenormMode::unspecified) {
    mode = modefp64;
  } else if (modefp64 == clspv::Option::DenormMode::unspecified) {
    mode = modefp16;
  }
  switch (mode) {
  case clspv::Option::DenormMode::preserve:
    instance.getCodeGenOpts().FPDenormalMode = llvm::DenormalMode::getIEEE();
    break;
  case clspv::Option::DenormMode::flush_to_zero:
    instance.getCodeGenOpts().FPDenormalMode =
        llvm::DenormalMode::getPreserveSign();
    break;
  case clspv::Option::DenormMode::unspecified:
    instance.getCodeGenOpts().FPDenormalMode = llvm::DenormalMode::getDynamic();
    break;
  case clspv::Option::DenormMode::error:
    llvm_unreachable("Invalid DenormMode");
  }

  instance.getCodeGenOpts().StackRealignment = true;
  instance.getCodeGenOpts().SimplifyLibCalls = false;
  instance.getCodeGenOpts().EmitOpenCLArgMetadata = false;
  instance.getCodeGenOpts().DisableO0ImplyOptNone = true;
  instance.getDiagnosticOpts().IgnoreWarnings = IgnoreWarnings;
  // We always undef __SPIR__ and __SPIRV__ (see below) so don't warn about it.
  instance.getDiagnosticOpts().Warnings.push_back("no-builtin-macro-redefined");
  // TODO(#995): Re-enable this warning.
  instance.getDiagnosticOpts().Warnings.push_back("no-unsafe-buffer-usage");

  if (clspv::Option::Language() == clspv::Option::SourceLanguage::OpenCL_CPP ||
      clspv::Option::Language() ==
          clspv::Option::SourceLanguage::OpenCL_CPP_2021) {
    instance.getDiagnosticOpts().Warnings.push_back("no-missing-prototypes");
  }
  if (clspv::Option::Language() ==
      clspv::Option::SourceLanguage::OpenCL_CPP_2021) {
    instance.getDiagnosticOpts().Warnings.push_back("no-c++98-compat");
  }

  instance.getLangOpts().SinglePrecisionConstants =
      cl_single_precision_constants;
  // cl_fp32_correctly_rounded_divide_sqrt ignored for now!
  instance.getCodeGenOpts().LessPreciseFPMAD =
      clspv::Option::ClMadEnable() || clspv::Option::UnsafeMath();
  // cl_no_signed_zeros ignored for now!
  instance.getLangOpts().UnsafeFPMath = clspv::Option::UnsafeMath();
  instance.getLangOpts().FastRelaxedMath = clspv::Option::FastRelaxedMath();

  instance.getLangOpts().NoHonorInfs = clspv::Option::FiniteMath();
  instance.getLangOpts().NoHonorNaNs = clspv::Option::FiniteMath();

  // Preprocessor options
  if (!clspv::Option::ImageSupport()) {
    instance.getPreprocessorOpts().addMacroUndef("__IMAGE_SUPPORT__");
  }
  if (clspv::Option::FastRelaxedMath()) {
    instance.getPreprocessorOpts().addMacroDef("__FAST_RELAXED_MATH__");
  }

  if (clspv::Option::SpvVersion() >= clspv::Option::SPIRVVersion::SPIRV_1_3) {
    // TODO remove when extension is added to OpenCLExtensions.def
    // https://github.com/llvm/llvm-project/blob/main/clang/include/clang/Basic/OpenCLExtensions.def
    instance.getPreprocessorOpts().addMacroDef(
        "cl_khr_subgroup_extended_types");
    instance.getPreprocessorOpts().addMacroDef("cl_khr_subgroup_shuffle");
    instance.getPreprocessorOpts().addMacroDef("cl_khr_subgroup_rotate");
    instance.getPreprocessorOpts().addMacroDef("cl_khr_subgroup_ballot");
    instance.getPreprocessorOpts().addMacroDef(
        "cl_khr_subgroup_non_uniform_vote");
  }

  if (clspv::Option::ArmIntegerDotProduct()) {
    instance.getPreprocessorOpts().addMacroDef(
        "cl_arm_integer_dot_product_int8");
    instance.getPreprocessorOpts().addMacroDef(
        "cl_arm_integer_dot_product_accumulate_int8");
    instance.getPreprocessorOpts().addMacroDef(
        "cl_arm_integer_dot_product_accumulate_int16");
    instance.getPreprocessorOpts().addMacroDef(
        "cl_arm_integer_dot_product_accumulate_saturate_int8");
  }
  instance.getPreprocessorOpts().addMacroDef("cl_khr_integer_dot_product");

  for (auto define : Defines) {
    instance.getPreprocessorOpts().addMacroDef(define);
  }

  // Add headers to virtual filesystem
  llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> VFS(
      new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> MemFS(
      new llvm::vfs::InMemoryFileSystem(true));
  llvm::SmallString<128> VirtualRoot;
  llvm::sys::fs::current_path(VirtualRoot);
  llvm::sys::path::append(VirtualRoot, "virtual_clspv_includes");
  for (const auto &header : headers) {
    llvm::SmallString<128> Path = VirtualRoot;
    llvm::sys::path::append(Path, header.first);
    MemFS->addFile(
        Path.str(), 0,
        llvm::MemoryBuffer::getMemBuffer(header.second, header.first));
  }
  VFS->pushOverlay(MemFS);
  Includes.push_back(VirtualRoot.str().str());

  // Header search options
  for (auto include : Includes) {
    instance.getHeaderSearchOpts().AddPath(include, clang::frontend::After,
                                           false, false);
  }

  // We always compile on opt 0 so we preserve as much debug information about
  // the source as possible. We'll run optimization later, once we've had a
  // chance to view the unoptimal code first
  instance.getCodeGenOpts().OptimizationLevel = 0;

  if (clspv::Option::DebugInfo()) {
    instance.getCodeGenOpts().setDebugInfo(llvm::codegenoptions::FullDebugInfo);
  }

  // Select the correct SPIR triple
  llvm::Triple triple{target_arch == SPIRVArch::SPIRV64
                          ? "spirv64-unknown-vulkan"
                          : "spirv32-unknown-vulkan"};

  // We manually include the OpenCL headers below, so this vector is unused.
  std::vector<std::string> includes;

  LangOptions::setLangDefaults(instance.getLangOpts(), clang::Language::OpenCL,
                               triple, includes, standard);

  // Override the C99 inline semantics to accommodate for more OpenCL C
  // programs in the wild.
  instance.getLangOpts().GNUInline = true;

  // Set up diagnostics
  instance.setDiagnostics(CompilerInstance::createDiagnostics(
      *llvm::vfs::getRealFileSystem(), instance.getDiagnosticOpts(),
      new clang::TextDiagnosticPrinter(*diagnosticsStream,
                                       instance.getDiagnosticOpts()),
      true));
  instance.getDiagnostics().setWarningsAsErrors(WarningsAsErrors);
  instance.getDiagnostics().setEnableAllWarnings(true);

  instance.getTargetOpts().Triple = triple.str();

  instance.getCodeGenOpts().MainFileName = overiddenInputFilename.str();
  instance.getLangOpts().PreserveVec3Type = true;
  // Disable generation of lifetime intrinsic.
  instance.getCodeGenOpts().DisableLifetimeMarkers = true;
  if (InputLanguage == clang::Language::OpenCL) {
    instance.getPreprocessorOpts().addRemappedFile(
        overiddenInputFilename, file_memory_buffer.release());
  } else if (!program.empty()) {
    // Can't use preprocessor to do file remapping for LLVM_IR
    kernelFile = clang::FrontendInputFile(*file_memory_buffer,
                                          clang::InputKind(InputLanguage));
  }
  instance.getFrontendOpts().Inputs.push_back(kernelFile);

  std::unique_ptr<llvm::MemoryBuffer> openCLBaseBuiltinMemoryBuffer(
      new OpenCLBuiltinMemoryBuffer(opencl_base_builtins_header_data,
                                    opencl_base_builtins_header_size - 1));

  // TODO this is a hack to get around optional feature macros always being
  // defined in opencl-c-base.h
  instance.getPreprocessorOpts().addMacroUndef("__SPIR__");
  instance.getPreprocessorOpts().addMacroUndef("__SPIRV__");

  instance.getPreprocessorOpts().Includes.push_back("opencl-c-base.h");

  std::unique_ptr<llvm::MemoryBuffer> clspvBuiltinMemoryBuffer(
      new OpenCLBuiltinMemoryBuffer(clspv_builtins_header_data,
                                    clspv_builtins_header_size - 1));

  instance.getPreprocessorOpts().Includes.push_back("clspv-builtins.h");

  // Add the VULKAN macro.
  instance.getPreprocessorOpts().addMacroDef("VULKAN=100");

  // Add the __OPENCL_VERSION__ macro.
  if (standard == clang::LangStandard::lang_opencl20) {
    instance.getPreprocessorOpts().addMacroDef("__OPENCL_VERSION__=200");
  } else if (standard == clang::LangStandard::lang_opencl30) {
    instance.getPreprocessorOpts().addMacroDef("__OPENCL_VERSION__=300");
  } else {
    instance.getPreprocessorOpts().addMacroDef("__OPENCL_VERSION__=120");
  }

  instance.setTarget(PrepareTargetInfo(instance));

  instance.setVirtualFileSystem(VFS);
  instance.createFileManager();
  instance.createSourceManager();

#ifdef _MSC_VER
  std::string includePrefix("include\\");
#else
  std::string includePrefix("include/");
#endif

  auto entry = instance.getFileManager().getVirtualFileRef(
      includePrefix + "clspv-builtins.h",
      clspvBuiltinMemoryBuffer->getBufferSize(), 0);

  instance.getSourceManager().overrideFileContents(
      entry, std::move(clspvBuiltinMemoryBuffer));

  auto base_entry = instance.getFileManager().getVirtualFileRef(
      includePrefix + "opencl-c-base.h",
      openCLBaseBuiltinMemoryBuffer->getBufferSize(), 0);

  instance.getSourceManager().overrideFileContents(
      base_entry, std::move(openCLBaseBuiltinMemoryBuffer));

  return 0;
}

int RunPassPipeline(llvm::Module &M, llvm::raw_svector_ostream *binaryStream,
                    std::string *output_log) {
  llvm::LoopAnalysisManager lam;
  llvm::FunctionAnalysisManager fam;
  llvm::CGSCCAnalysisManager cgam;
  llvm::ModuleAnalysisManager mam;
  llvm::PassInstrumentationCallbacks PIC;
  llvm::StandardInstrumentations si(M.getContext(), false /*DebugLogging*/);
  clspv::RegisterClspvPasses(&PIC);
  si.registerCallbacks(PIC, &mam);
  llvm::PassBuilder pb(nullptr, llvm::PipelineTuningOptions(), std::nullopt,
                       &PIC);
  pb.registerModuleAnalyses(mam);
  pb.registerCGSCCAnalyses(cgam);
  pb.registerFunctionAnalyses(fam);
  pb.registerLoopAnalyses(lam);
  pb.crossRegisterProxies(lam, fam, cgam, mam);

  llvm::ModulePassManager pm;
  llvm::FunctionPassManager fpm;

  llvm::OptimizationLevel level;
  switch (OptimizationLevel) {
  case '0':
    level = llvm::OptimizationLevel::O0;
    break;
  case '1':
    level = llvm::OptimizationLevel::O1;
    break;
  case '2':
    level = llvm::OptimizationLevel::O2;
    break;
  case '3':
    level = llvm::OptimizationLevel::O3;
    break;
  default:
    llvm::errs() << "Unknown optimization level -O" << OptimizationLevel
                 << " specified!\n";
    return -1;
  }

  bool has_error = false;
  // Run the following optimizations prior to the standard LLVM pass pipeline.
  pb.registerPipelineStartEPCallback([](llvm::ModulePassManager &pm,
                                        llvm::OptimizationLevel level) {
    pm.addPass(clspv::AnnotationToMetadataPass());
    pm.addPass(clspv::NativeMathPass());
    pm.addPass(clspv::ZeroInitializeAllocasPass());
    pm.addPass(clspv::KernelArgNamesToMetadataPass());
    pm.addPass(clspv::AddFunctionAttributesPass());

    // Handle physical pointer arguments by converting them to POD integers,
    // and update all uses to bitcast them to a pointer first. This allows these
    // arguments to be handled in later passes as if they were regular PODs.
    // This pass needs to run before an interation of
    // AutoPodArgsPass/DeclarePushConstantsPass/DefineOpenCLWorkItemBuiltinsPass.
    if (clspv::Option::PhysicalStorageBuffers()) {
      pm.addPass(clspv::PhysicalPointerArgsPass());
    }

    pm.addPass(clspv::AutoPodArgsPass());
    pm.addPass(clspv::DeclarePushConstantsPass());
    pm.addPass(clspv::DefineOpenCLWorkItemBuiltinsPass());

    // RewritePackedStructsPass will rewrite packed struct types, and
    // ReplacePointerBitcastPass will lower the new packed struct type. So,
    // RewritePackedStructsPass must come before ReplacePointerBitcastPass.
    if (clspv::Option::RewritePackedStructs()) {
      pm.addPass(clspv::RewritePackedStructs());
    }

    if (clspv::Option::PrintfSupport()) {
      pm.addPass(clspv::PrintfPass());
    }

    if (level != llvm::OptimizationLevel::O0) {
      pm.addPass(clspv::OpenCLInlinerPass());
    }

    pm.addPass(clspv::UndoByvalPass());
    pm.addPass(clspv::UndoSRetPass());

    pm.addPass(llvm::createModuleToFunctionPassAdaptor(
        llvm::InferAddressSpacesPass(clspv::AddressSpace::Generic)));

    // We need to run mem2reg and inst combine early because some of our passes
    // (e.g. ThreeElementVectorLowering and InlineFuncWithBitCastArgsPass)
    // cannot handle the pattern:
    //
    //   %1 = alloca i32 1
    //        store <something> %1
    //   %2 = bitcast float* %1
    //   %3 = load float %2
    pm.addPass(llvm::createModuleToFunctionPassAdaptor(llvm::PromotePass()));
    pm.addPass(clspv::SimplifyPointerBitcastPass());
    pm.addPass(clspv::ClusterPodKernelArgumentsPass());

    pm.addPass(clspv::InlineEntryPointsPass());
    pm.addPass(clspv::FunctionInternalizerPass());
    // This pass needs to be after every inlining to make sure we are capable of
    // removing every addrspacecast. It only needs to run if generic addrspace
    // is used.
    if (clspv::Option::LanguageUsesGenericAddressSpace()) {
      pm.addPass(clspv::ReplaceOpenCLBuiltinPass());
      pm.addPass(clspv::LowerAddrSpaceCastPass());
    }

    // ReplaceOpenCLBuiltinPass can generate vec8 and vec16 elements. It needs
    // to be before the potential LongVectorLoweringPass pass.
    pm.addPass(clspv::ReplaceOpenCLBuiltinPass());
    pm.addPass(clspv::FixupBuiltinsPass());
    pm.addPass(clspv::ThreeElementVectorLoweringPass());

    // Lower longer vectors when requested. Note that this pass depends on
    // ReplaceOpenCLBuiltinPass and expects DeadCodeEliminationPass to be run
    // afterwards.
    if (clspv::Option::LongVectorSupport()) {
      pm.addPass(clspv::LongVectorLoweringPass());
    }

    // Early attempt to normalize global variables before optimizations make
    // reconstructing type information more difficult.
    pm.addPass(clspv::NormalizeGlobalVariablesPass());

    // Try to deal with pointer bitcasts early. This can prevent problems like
    // issue #409 where LLVM is looser about access chain addressing than
    // SPIR-V. This needs to happen before instcombine and after replacing
    // OpenCL builtins.  This run of the pass will not handle all pointer
    // bitcasts that could be handled. It should be run again after other
    // optimizations (e.g InlineFuncWithPointerBitCastArgPass).
    pm.addPass(clspv::SimplifyPointerBitcastPass());
    pm.addPass(clspv::ReplacePointerBitcastPass());
    pm.addPass(llvm::createModuleToFunctionPassAdaptor(llvm::DCEPass()));

    // Hide loads from __constant address space away from instcombine.
    // This prevents us from generating select between pointers-to-__constant.
    // See https://github.com/google/clspv/issues/71
    pm.addPass(clspv::HideConstantLoadsPass());

    pm.addPass(clspv::StructurizeGEPPass());
    pm.addPass(
        llvm::createModuleToFunctionPassAdaptor(llvm::InstCombinePass()));
    pm.addPass(clspv::DestructurizeGEPPass());

    pm.addPass(clspv::InlineFuncWithImageMetadataGetterPass());
    pm.addPass(clspv::InlineFuncWithPointerBitCastArgPass());
    pm.addPass(clspv::InlineFuncWithPointerToFunctionArgPass());
    pm.addPass(clspv::InlineFuncWithSingleCallSitePass());
    pm.addPass(clspv::InlineFuncWithReadImage3DNonLiteralSamplerPass());

    if (clspv::Option::HackLogicalPtrtoint()) {
      pm.addPass(llvm::createModuleToFunctionPassAdaptor(llvm::PromotePass()));
      pm.addPass(clspv::LogicalPointerToIntPass());
    }

    // Mem2Reg pass should be run early because O0 level optimization leaves
    // redundant alloca, load and store instructions from function arguments.
    // clspv needs to remove them ahead of transformation.
    pm.addPass(llvm::createModuleToFunctionPassAdaptor(llvm::PromotePass()));

    // SROA pass is run because it will fold structs/unions that are
    // problematic on Vulkan SPIR-V away.
    pm.addPass(llvm::createModuleToFunctionPassAdaptor(
        llvm::SROAPass(llvm::SROAOptions::PreserveCFG)));

    // InstructionCombining pass folds bitcast and gep instructions which are
    // not supported by Vulkan SPIR-V.
    pm.addPass(clspv::StructurizeGEPPass());
    pm.addPass(
        llvm::createModuleToFunctionPassAdaptor(llvm::InstCombinePass()));
    pm.addPass(clspv::DestructurizeGEPPass());

    pm.addPass(llvm::createModuleToFunctionPassAdaptor(
        llvm::InferAddressSpacesPass(clspv::AddressSpace::Generic)));
    pm.addPass(clspv::StructurizeGEPPass());
  });

  // Run the following passes after the default LLVM pass pipeline.
  pb.registerOptimizerLastEPCallback([binaryStream, &has_error,
                                      output_log](llvm::ModulePassManager &pm,
                                                  llvm::OptimizationLevel,
                                                  llvm::ThinOrFullLTOPhase) {
    pm.addPass(clspv::DestructurizeGEPPass());
    // No point attempting to handle freeze currently so strip them from the
    // IR.
    pm.addPass(clspv::StripFreezePass());

    // Unhide loads from __constant address space.  Undoes the action of
    // HideConstantLoadsPass.
    pm.addPass(clspv::UnhideConstantLoadsPass());

    pm.addPass(clspv::UndoInstCombinePass());
    pm.addPass(clspv::FunctionInternalizerPass());

    // Run SimplifyPointerBitcastPass before ReplaceLLVMInstrinsicsPass to help
    // lower memcpy.
    pm.addPass(clspv::SimplifyPointerBitcastPass());
    pm.addPass(clspv::ReplaceLLVMIntrinsicsPass());
    // Replace LLVM intrinsics can leave dead code around.
    pm.addPass(llvm::createModuleToFunctionPassAdaptor(llvm::DCEPass()));
    pm.addPass(clspv::UndoBoolPass());
    pm.addPass(clspv::UndoTruncateToOddIntegerPass());
    // StructurizeCFG requires LowerSwitch to run first.
    pm.addPass(
        llvm::createModuleToFunctionPassAdaptor(llvm::LowerSwitchPass()));
    pm.addPass(
        llvm::createModuleToFunctionPassAdaptor(llvm::StructurizeCFGPass()));
    // Must be run after structurize cfg.
    pm.addPass(llvm::createModuleToFunctionPassAdaptor(
        clspv::FixupStructuredCFGPass()));
    // Must be run after structured cfg fixup.
    pm.addPass(llvm::createModuleToFunctionPassAdaptor(
        clspv::ReorderBasicBlocksPass()));
    pm.addPass(clspv::UndoGetElementPtrConstantExprPass());
    pm.addPass(clspv::SplatArgPass());
    pm.addPass(clspv::SimplifyPointerBitcastPass());
    pm.addPass(clspv::ReplacePointerBitcastPass());
    pm.addPass(llvm::createModuleToFunctionPassAdaptor(llvm::DCEPass()));
  
    pm.addPass(clspv::UndoTranslateSamplerFoldPass());

    if (clspv::Option::ModuleConstantsInStorageBuffer()) {
      pm.addPass(clspv::ClusterModuleScopeConstantVars());
    }

    pm.addPass(clspv::ShareModuleScopeVariablesPass());
    // Specialize images before assigning descriptors to disambiguate the
    // various types.
    pm.addPass(clspv::SpecializeImageTypesPass());
    // This should be run after LLVM and OpenCL intrinsics are replaced.
    pm.addPass(clspv::AllocateDescriptorsPass());
    pm.addPass(llvm::VerifierPass());
    pm.addPass(clspv::DirectResourceAccessPass());
    // Replacing pointer bitcasts can leave some trivial GEPs
    // that are easy to remove.  Also replace GEPs of GEPS
    // left by replacing indirect buffer accesses.
    pm.addPass(clspv::SimplifyPointerBitcastPass());
    // Run after DRA to clean up parameters and help reduce the need for
    // variable pointers.
    pm.addPass(clspv::RemoveUnusedArguments());
    pm.addPass(llvm::createModuleToFunctionPassAdaptor(llvm::DCEPass()));

    // SPIR-V 1.4 and higher do not need to splat scalar conditions for vector
    // data.
    if (clspv::Option::SpvVersion() < clspv::Option::SPIRVVersion::SPIRV_1_4) {
      pm.addPass(clspv::SplatSelectConditionPass());
    }
    pm.addPass(clspv::SignedCompareFixupPass());
    // This pass generates insertions that need to be rewritten.
    pm.addPass(clspv::ScalarizePass());
    pm.addPass(clspv::RewriteInsertsPass());
    // UBO Transformations
    if (clspv::Option::ConstantArgsInUniformBuffer() &&
        !clspv::Option::InlineEntryPoints()) {
      // MultiVersionUBOFunctionsPass will examine non-kernel functions with
      // UBO arguments and either multi-version them as necessary or inline
      // them if multi-versioning cannot be accomplished.
      pm.addPass(clspv::MultiVersionUBOFunctionsPass());
      // Cleanup passes.
      // Specialization can blindly generate GEP chains that are easily
      // cleaned up by SimplifyPointerBitcastPass.
      pm.addPass(clspv::SimplifyPointerBitcastPass());
      // RemoveUnusedArgumentsPass removes the actual UBO arguments that were
      // problematic to begin with now that they have no uses.
      pm.addPass(clspv::RemoveUnusedArguments());
      // DCE cleans up callers of the specialized functions.
      pm.addPass(llvm::createModuleToFunctionPassAdaptor(llvm::DCEPass()));
    }

    // This pass needs to run before an interation of
    // SimplifyPointerBitcastPass/ReplacePointerBitcastPass.
    pm.addPass(clspv::LowerPrivatePointerPHIPass());

    // Last minute pointer simplification. With opaque pointers, we can often
    // end up in a situation where LLVM has simplified GEPs by removing zero
    // indices where an equivalent address would be computed. These lead to
    // situations that are awkward for clspv. The following passes canonicalize
    // GEPs into forms easier to codegen in SPIR-V, including those more likely
    // to avoid extra functionality (e.g. VariablePointers).
    pm.addPass(clspv::SimplifyPointerBitcastPass());
    pm.addPass(clspv::ReplacePointerBitcastPass());
    pm.addPass(clspv::SimplifyPointerBitcastPass());

    // This pass mucks with types to point where you shouldn't rely on
    // DataLayout anymore so leave this right before SPIR-V generation.
    pm.addPass(clspv::UBOTypeTransformPass());

    // This pass depends on the inlining of the image metadata from
    // InlineFuncWithImageMetadataGetterPass and
    // InlineFuncWithReadImage3DNonLiteralSamplerPass
    pm.addPass(clspv::SetImageMetadataPass());

    // This is needed to remove long vectors created by SROA passes. Especially
    // with vstore_half, which tends to always recreate long vectors after the
    // first iteration of the longvectorlowering pass
    if (clspv::Option::LongVectorSupport()) {
      pm.addPass(clspv::LongVectorLoweringPass());
    }

    pm.addPass(clspv::SPIRVProducerPass(
        binaryStream, OutputFormat == OutputFormatC, &has_error, output_log));
  });

  // Add the default optimizations for the requested optimization level.
  if (level != llvm::OptimizationLevel::O0) {
    auto mpm = pb.buildPerModuleDefaultPipeline(level);
    mpm.run(M, mam);
  } else {
    auto mpm = pb.buildO0DefaultPipeline(level);
    mpm.run(M, mam);
  }

  return has_error ? -1 : 0;
}

int ParseOptions(const int argc, const char *const argv[]) {
  // We need to change how some of the called passes works by spoofing
  // ParseCommandLineOptions with the specific options.
  bool has_pre = false;
  bool has_load_pre = false;
  const std::string pre = "-enable-scalar-pre";
  const std::string load_pre = "-enable-load-pre";
  for (int i = 1; i < argc; ++i) {
    std::string option(argv[i]);
    auto pre_pos = option.find(pre);
    auto load_pos = option.find(load_pre);
    if (pre_pos == 0 || (pre_pos == 1 && option[0] == '-')) {
      has_pre = true;
    } else if (load_pos == 0 || (load_pos == 1 && option[0] == '-')) {
      has_load_pre = true;
    }
  }

  int llvmArgc = 3;
  const char *llvmArgv[6];
  llvmArgv[0] = argv[0];
  llvmArgv[1] = "-simplifycfg-sink-common=false";
  // TODO(#738): find a better solution to this.
  llvmArgv[2] = "-disable-vector-combine";
  if (!has_pre) {
    llvmArgv[llvmArgc++] = "-enable-scalar-pre=0";
  }
  if (!has_load_pre) {
    llvmArgv[llvmArgc++] = "-enable-load-pre=0";
  }

  llvm::cl::ResetAllOptionOccurrences();
  llvm::cl::ParseCommandLineOptions(llvmArgc, llvmArgv);
  llvm::cl::ParseCommandLineOptions(argc, argv);

  if (!clspv::Option::OpaquePointers()) {
    llvm::errs() << "transparent pointer is not supported anymore\n";
    return -1;
  }

  if (clspv::Option::LanguageUsesGenericAddressSpace() &&
      !clspv::Option::InlineEntryPoints()) {
    llvm::errs() << "cannot compile languages that use the generic address "
                    "space (e.g. CLC++, CL2.0) without -inline-entry-points\n";
    return -1;
  }

  if (clspv::Option::ScalarBlockLayout()) {
    llvm::errs() << "scalar block layout support unimplemented\n";
    return -1;
  }

  if (clspv::Option::RewritePackedStructs() && !clspv::Option::Int8Support()) {
    llvm::errs()
        << "Int8 has to be supported with rewrite-packed-structs option";
    return -1;
  }

  // Push constant option validation.
  if (clspv::Option::PodArgsInPushConstants()) {
    if (clspv::Option::PodArgsInUniformBuffer()) {
      llvm::errs() << "POD arguments can only be in either uniform buffers or "
                      "push constants\n";
      return -1;
    }

    if (!clspv::Option::ClusterPodKernelArgs()) {
      llvm::errs() << "POD arguments must be clustered to be passed as push "
                      "constants\n";
      return -1;
    }

    // Conservatively error if a module scope push constant could be used.
    if (clspv::Option::GlobalOffsetPushConstant() ||
        clspv::Option::Language() ==
            clspv::Option::SourceLanguage::OpenCL_C_20 ||
        clspv::Option::Language() ==
            clspv::Option::SourceLanguage::OpenCL_CPP ||
        clspv::Option::Language() ==
            clspv::Option::SourceLanguage::OpenCL_CPP_2021) {
      llvm::errs() << "POD arguments as push constants are not compatible with "
                      "module scope push constants\n";
      return -1;
    }
  }

  if (clspv::Option::ArmNonUniformWorkGroupSize() &&
      clspv::Option::UniformWorkgroupSize()) {
    llvm::errs() << "cannot enable Arm non-uniform workgroup extension support "
                    "and assume uniform workgroup sizes\n";
    return -1;
  }

  if (clspv::Option::Vec3ToVec4() ==
      clspv::Option::Vec3ToVec4SupportClass::vec3ToVec4SupportError) {
    llvm::errs() << "error: -vec3-to-vec4 and -no-vec3-to-vec4 are exclusive "
                    "so they cannot be used together!\n";
    return -1;
  }

  const auto enabled_feature_macros = clspv::Option::EnabledFeatureMacros();
  if (!clspv::Option::FP64() &&
      enabled_feature_macros.count(clspv::FeatureMacro::__opencl_c_fp64)) {
    llvm::errs() << "error: Cannot enabled feature macro __opencl_c_fp64 while "
                    "-fp64 is disabled!\n";
    return -1;
  }

  if (clspv::Option::PhysicalStorageBuffers() &&
      target_arch != SPIRVArch::SPIRV64) {
    llvm::errs() << "error: -physical-storage-buffers can only be used with "
                    "the spirv64 target\n";
    return -1;
  }

  if (!clspv::Option::ImageSupport() &&
      enabled_feature_macros.count(clspv::FeatureMacro::__opencl_c_images)) {
    llvm::errs()
        << "error: Cannot enabled feature macro __opencl_c_images while "
           "-images is disabled!\n";
    return -1;
  }

  if (!clspv::Option::FP16() &&
      ExecutionModeRoundingModeRTE(clspv::Option::FloatingPointType::fp16)) {
    llvm::errs() << "error: Cannot set RoundingModeRTE for fp16 if fp16 is not "
                    "supported\n";
    return -1;
  }
  if (!clspv::Option::FP64() &&
      ExecutionModeRoundingModeRTE(clspv::Option::FloatingPointType::fp64)) {
    llvm::errs() << "error: Cannot set RoundingModeRTE for fp64 if fp64 is not "
                    "supported\n";
    return -1;
  }

  if (clspv::Option::PhysicalStorageBuffers() &&
      clspv::Option::ConstantArgsInUniformBuffer()) {
    llvm::errs() << "error: -physical-storage-buffers and -constant-args-ubo "
                    "are incompatible\n";
    return -1;
  }

  if (clspv::Option::SupportsFmaKHR(16) && !clspv::Option::FP16()) {
    llvm::errs()
        << "error: Cannot set SpvKhrFma for fp16 if fp16 is not supported\n";
    return -1;
  }
  if (clspv::Option::SupportsFmaKHR(64) && !clspv::Option::FP64()) {
    llvm::errs()
        << "error: Cannot set SpvKhrFma for fp64 if fp64 is not supported\n";
    return -1;
  }

  if (clspv::Option::SupportsFmaKHR(32) &&
      (clspv::Option::SupportsFmaKHR(16) || !clspv::Option::FP16()) &&
      (clspv::Option::SupportsFmaKHR(64) || !clspv::Option::FP64())) {
    clspv::Option::AddUseNativeBuiltins(clspv::Builtins::BuiltinType::kFma);
  }

  if (clspv::Option::FP16() &&
      ExecutionModeDenorm(clspv::Option::FloatingPointType::fp16) ==
          clspv::Option::DenormMode::error) {
    llvm::errs()
        << "error: denorm preserve & flush to zero mode are exclusive (fp16)";
    return -1;
  }
  if (ExecutionModeDenorm(clspv::Option::FloatingPointType::fp32) ==
      clspv::Option::DenormMode::error) {
    llvm::errs()
        << "error: denorm preserve & flush to zero mode are exclusive (fp32)";
    return -1;
  }
  if (clspv::Option::FP64() &&
      ExecutionModeDenorm(clspv::Option::FloatingPointType::fp64) ==
          clspv::Option::DenormMode::error) {
    llvm::errs()
        << "error: denorm preserve & flush to zero mode are exclusive (fp64)";
    return -1;
  }
  if (clspv::Option::FP16() && clspv::Option::FP64() &&
      (ExecutionModeDenorm(clspv::Option::FloatingPointType::fp16) !=
       ExecutionModeDenorm(clspv::Option::FloatingPointType::fp64))) {
    llvm::errs() << "error: fp16 & fp64 needs to share the same DenormMode";
    return -1;
  }

  return 0;
}

int WriteOutput(const std::string &output,
                std::vector<uint32_t> *output_buffer) {
  if (!OutputFilename.empty()) {
    std::error_code error;
    llvm::raw_fd_ostream outStream(OutputFilename, error,
                                   llvm::sys::fs::FA_Write);

    if (error) {
      llvm::errs() << "Unable to open output file '" << OutputFilename
                   << "': " << error.message() << '\n';
      return -1;
    }
    outStream << output;
  }
  if (output_buffer) {
    output_buffer->resize((output.size() + sizeof(uint32_t) - 1) /
                          sizeof(uint32_t));
    memcpy(output_buffer->data(), output.data(), output.size());
  }
  return 0;
}

int GenerateIRFile(std::unique_ptr<llvm::Module> &module,
                   std::vector<uint32_t> *output_binary) {
  std::string module_string;
  llvm::raw_string_ostream stream(module_string);
  switch (OutputFormat) {
  case OutputFormatLLVMIRBinary:
    llvm::WriteBitcodeToFile(*module, stream);
    break;
  case OutputFormatLLVMIR:
    stream << *module;
    stream.flush();
    break;
  default:
    llvm_unreachable("unknown LLVM IR Format");
  }

  return WriteOutput(module_string, output_binary);
}

bool GetEquivalentBuiltinsWithoutGenericPointer(llvm::Module *module,
                                                std::string &lib_str) {
  std::string fct_list;
  llvm::raw_string_ostream stream_fct_list(fct_list);
  llvm::raw_string_ostream stream_fct_decl(lib_str);
  bool found = false;
  for (auto &F : module->functions()) {
    auto name = F.getName();
    if (!name.contains("PU3AS4") ||
        !clspv::Builtins::BuiltinWithGenericPointer(name)) {
      continue;
    }

    auto get_fct_decl = [](llvm::Function &F) {
      std::string str;
      llvm::raw_string_ostream stream(str);
      F.print(stream);
      stream.flush();
      return str;
    };
    std::string str = get_fct_decl(F);

    auto add_impl = [&found, &str, &stream_fct_decl, &stream_fct_list,
                     &module](std::string mangling, std::string AS) {
      auto substr = [&str](size_t start, size_t end) {
        return str.substr(start, end - start);
      };
      if (!found) {
        stream_fct_decl << "target datalayout = \""
                        << module->getDataLayoutStr() << "\"";
      }
      std::string mangling_pattern = "PU3AS4";
      auto mangling_start = str.find(mangling_pattern);
      auto mangling_end = mangling_start + mangling_pattern.size();
      std::string AS_pattern = " addrspace(4)";
      auto AS_start = str.find(AS_pattern);
      auto AS_end = AS_start + AS_pattern.size();
      stream_fct_decl << substr(0, mangling_start) << mangling
                      << substr(mangling_end, AS_start) << AS
                      << substr(AS_end, str.find('#', AS_end) - 1) << "\n";

      if (found) {
        stream_fct_list << ", ptr ";
      }
      stream_fct_list << substr(str.find('@'), mangling_start) << mangling
                      << substr(mangling_end, str.find('(', mangling_end));
    };

    add_impl("P", ""); // private
    found = true;
    add_impl("PU3AS1", " addrspace(1)"); // local
    add_impl("PU3AS3", " addrspace(3)"); // global
  }
  if (found) {
    stream_fct_list.flush();
    stream_fct_decl << "@" << clspv::CLSPVBuiltinsUsed()
                    << " = appending global ["
                    << std::count(fct_list.begin(), fct_list.end(), '@')
                    << " x ptr] [ptr " << fct_list
                    << "], section \"llvm.metadata\"";
    stream_fct_decl.flush();
  }
  return found;
}

bool LinkBuiltinLibrary(llvm::Module *module) {
  auto library_data = clspv::PointersAre64Bit(*module)
                          ? clspv64_builtin_library_data
                          : clspv_builtin_library_data;

  auto library_size = clspv::PointersAre64Bit(*module)
                          ? clspv64_builtin_library_size
                          : clspv_builtin_library_size;

  std::unique_ptr<llvm::MemoryBuffer> buffer(
      new OpenCLBuiltinMemoryBuffer(library_data, library_size - 1));

  llvm::SMDiagnostic Err;
  auto library =
      llvm::getLazyIRModule(std::move(buffer), Err, module->getContext());
  if (!library) {
    llvm::errs() << "Failed to parse builtins library:\n";
    llvm::errs() << Err.getMessage();
    return false;
  }

  llvm::Linker L(*module);

  // When clang generates builtins using the generic address space, different
  // builtins are used for pointer-based builtins. Need to do some work to
  // ensure they are kept around.
  // Affects: modf, remquo, lgamma_r, frexp, fract
  std::string additional_library;
  if (GetEquivalentBuiltinsWithoutGenericPointer(module, additional_library)) {
    auto add_buffer = llvm::MemoryBuffer::getMemBuffer(additional_library);
    auto add_library = llvm::parseIR(*add_buffer, Err, module->getContext());
    if (add_library == nullptr) {
      fprintf(stderr, "%s\n", additional_library.c_str());
      Err.print("internal_additional_library:", llvm::errs());
      return false;
    }
    L.linkInModule(std::move(add_library), 0);
  }

  L.linkInModule(std::move(library), Linker::LinkOnlyNeeded);

  return true;
}

std::unique_ptr<llvm::Module>
ProgramToModule(llvm::LLVMContext &context,
                const llvm::StringRef &inputFilename,
                const std::string &program,
                const std::vector<std::pair<std::string, std::string>> &headers,
                std::string *output_log, int *err) {
  clang::CompilerInstance instance;
  clang::FrontendInputFile kernelFile(inputFilename,
                                      clang::InputKind(InputLanguage));
  std::string log;
  llvm::raw_string_ostream diagnosticsStream(log);
  std::unique_ptr<llvm::MemoryBuffer> file_memory_buffer;
  if (auto error = SetCompilerInstanceOptions(
          instance, inputFilename, kernelFile, program, headers,
          file_memory_buffer, &diagnosticsStream)) {
    *err = error;
    return nullptr;
  }

  // Parse.
  clang::EmitLLVMOnlyAction action(&context);

  // Prepare the action for processing kernelFile
  const bool success = action.BeginSourceFile(instance, kernelFile);
  if (!success) {
    *err = -1;
    return nullptr;
  }

  auto result = action.Execute();
  action.EndSourceFile();

  clang::DiagnosticConsumer *const consumer =
      instance.getDiagnostics().getClient();

  auto num_warnings = consumer->getNumWarnings();
  auto num_errors = consumer->getNumErrors();
  if (output_log != nullptr) {
    output_log->append(log);
  } else if ((num_errors > 0) || (num_warnings > 0)) {
    llvm::errs() << log;
  }
  if (result || num_errors > 0) {
    *err = -1;
    return nullptr;
  }

  *err = 0;

  // Don't run the passes or produce any output in verify mode.
  // Clang doesn't always produce a valid module.
  if (verify) {
    return nullptr;
  }

  return action.takeModule();
}

int CompileModule(const llvm::StringRef &input_filename,
                  std::unique_ptr<llvm::Module> &module,
                  std::vector<uint32_t> *output_buffer,
                  std::string *output_log) {
  // Optimize.
  // Create a memory buffer for temporarily writing the result.
  SmallVector<char, 10000> binary;
  llvm::raw_svector_ostream binaryStream(binary);

  // If LLVM IR output format was requested, emit the file and stop
  // compilation.
  if (OutputFormat == OutputFormatLLVMIR ||
      OutputFormat == OutputFormatLLVMIRBinary) {
    return GenerateIRFile(module, output_buffer);
  }

  if (!LinkBuiltinLibrary(module.get())) {
    return -1;
  }

  // Run the passes to produce SPIR-V.
  if (RunPassPipeline(*module, &binaryStream, output_log) != 0) {
    return -1;
  }

  // Wait until now to try writing the file so that we only write it on
  // successful compilation.
  return WriteOutput(binaryStream.str().str(), output_buffer);
}

int CompilePrograms(
    const std::vector<std::string> &programs,
    const std::vector<std::pair<std::string, std::string>> &headers,
    std::vector<uint32_t> *output_buffer, std::string *output_log) {
  std::vector<std::unique_ptr<llvm::Module>> modules;
  modules.reserve(programs.size());

  llvm::LLVMContext context;
  for (auto program : programs) {
    int error;
    modules.push_back(ProgramToModule(context, "source", program, headers,
                                      output_log, &error));
    if (error != 0)
      return error;
  }
  assert(modules.size() > 0 && modules.back() != nullptr);

  std::unique_ptr<llvm::Module> module(modules.back().release());
  modules.pop_back();
  llvm::Linker L(*module);
  for (auto &mod : modules) {
    L.linkInModule(std::move(mod), 0);
  }

  return CompileModule("source", module, output_buffer, output_log);
}

int CompileProgram(const llvm::StringRef &input_filename,
                   const std::string &program,
                   std::vector<uint32_t> *output_buffer,
                   std::string *output_log) {
  int error;
  llvm::LLVMContext context;
  const std::vector<std::pair<std::string, std::string>> headers;
  std::unique_ptr<llvm::Module> module = ProgramToModule(
      context, input_filename, program, headers, output_log, &error);
  if (module == nullptr) {
    return error;
  }

  return CompileModule(input_filename, module, output_buffer, output_log);
}

void TokenizeCommandLine(const std::string &Source, llvm::StringSaver &Saver,
                         llvm::SmallVector<const char *, 20> &NewArgv) {
  NewArgv.push_back(Saver.save("clspv").data());
#ifdef _WIN32
  llvm::cl::TokenizeWindowsCommandLine(Source, Saver, NewArgv);
#else
  llvm::cl::TokenizeGNUCommandLine(Source, Saver, NewArgv);
#endif
}

} // namespace

namespace clspv {

int Compile(const int argc, const char *const argv[]) {
  if (auto error = ParseOptions(argc, argv))
    return error;

  if (OutputFilename.empty()) {
    switch (OutputFormat) {
    case OutputFormatLLVMIR:
      OutputFilename = "a.ll";
      break;
    case OutputFormatLLVMIRBinary:
      OutputFilename = "a.bc";
      break;
    case OutputFormatC:
      OutputFilename = "a.spvinc";
      break;
    case OutputFormatSPIRV:
      OutputFilename = "a.spv";
      break;
    default:
      llvm_unreachable("unknown output format");
    }
  }

  std::ios_base::openmode openMode = std::ios::in;
  if (InputLanguage == clang::Language::LLVM_IR) {
    openMode |= std::ios::binary;
  }

  if (InputsFilename.size() == 0 ||
      (InputsFilename.size() == 1 && InputsFilename[0] == "-")) {
    llvm::StringRef inputFilename;
    switch (InputLanguage) {
    case clang::Language::OpenCL:
      inputFilename = "stdin.cl";
      break;
    case clang::Language::LLVM_IR:
      inputFilename = "stdin.ll";
      break;
    default:
      // Default to fix compiler warnings/errors. Option parsing will reject a
      // bad enum value for the option so there is no need for a message.
      return -1;
    }
    std::string program((std::istreambuf_iterator<char>(std::cin)),
                        std::istreambuf_iterator<char>());
    return CompileProgram(inputFilename, program, nullptr, nullptr);
  } else if (InputsFilename.size() == 1) {
    llvm::StringRef inputFilename = InputsFilename[0];
    std::ifstream stream(inputFilename.str(), openMode);
    if (!stream.is_open()) {
      llvm::errs() << "Failed to open '" << inputFilename << "'\n";
      return -1;
    }
    std::string program((std::istreambuf_iterator<char>(stream)),
                        std::istreambuf_iterator<char>());
    return CompileProgram(inputFilename, program, nullptr, nullptr);
  } else {
    std::vector<std::string> programs;
    programs.reserve(InputsFilename.size());
    for (auto InputFilename : InputsFilename) {
      std::ifstream stream(InputFilename, openMode);
      if (!stream.is_open()) {
        llvm::errs() << "Failed to open '" << InputFilename << "'\n";
        return -1;
      }
      programs.emplace_back(std::istreambuf_iterator<char>(stream),
                            std::istreambuf_iterator<char>());
    }

    const std::vector<std::pair<std::string, std::string>> headers;
    return CompilePrograms(programs, headers, nullptr, nullptr);
  }
}

int CompileFromSourcesStringWithHeaders(
    const std::vector<std::string> &programs,
    const std::vector<std::pair<std::string, std::string>> &headers,
    const std::string &options, std::vector<uint32_t> *output_buffer,
    std::string *output_log) {
  llvm::SmallVector<const char *, 20> argv;
  llvm::BumpPtrAllocator A;
  llvm::StringSaver Saver(A);
  TokenizeCommandLine(options, Saver, argv);
  int argc = static_cast<int>(argv.size());

  if (auto error = ParseOptions(argc, &argv[0]))
    return error;

  return CompilePrograms(programs, headers, output_buffer, output_log);
}

int CompileFromSourcesString(const std::vector<std::string> &programs,
                             const std::string &options,
                             std::vector<uint32_t> *output_buffer,
                             std::string *output_log) {
  const std::vector<std::pair<std::string, std::string>> headers;
  return CompileFromSourcesStringWithHeaders(programs, headers, options,
                                             output_buffer, output_log);
}

int CompileFromSourceString(const std::string &program,
                            const std::string & /*removed*/,
                            const std::string &options,
                            std::vector<uint32_t> *output_binary,
                            std::string *output_log) {

  llvm::SmallVector<const char *, 20> argv;
  llvm::BumpPtrAllocator A;
  llvm::StringSaver Saver(A);
  TokenizeCommandLine(options, Saver, argv);
  int argc = static_cast<int>(argv.size());

  if (auto error = ParseOptions(argc, &argv[0]))
    return error;

  return CompileProgram("source", program, output_binary, output_log);
}
} // namespace clspv

// C API
ClspvError clspvCompileFromSourcesString(
    const size_t program_count, const size_t *program_sizes,
    const char **programs, const char *options, char **output_binary,
    size_t *output_binary_size, char **output_log) {
  if (programs == nullptr || program_count == 0 || output_binary == nullptr ||
      output_binary_size == nullptr) {
    return CLSPV_INVALID_ARG;
  }

  int err = CLSPV_SUCCESS;
  std::string sOptions(options ? options : "");
  std::vector<std::string> vPrograms(program_count);
  for (size_t i = 0; i < program_count; ++i) {
    if (programs[i] == nullptr) {
      return CLSPV_ERROR;
    }
    if (program_sizes && program_sizes[i] != 0) {
      vPrograms[i].assign(programs[i], program_sizes[i]);
    } else {
      vPrograms[i].assign(programs[i]);
    }
  }

  std::string buildLog;
  std::vector<uint32_t> binary;
  err =
      clspv::CompileFromSourcesString(vPrograms, sOptions, &binary, &buildLog);

  if (output_log != NULL) {
    if (!buildLog.empty()) {
      // Alloc and copy backing mem for build log
      *output_log = static_cast<char *>(std::malloc(buildLog.size() + 1));
      if (*output_log == NULL) {
        return CLSPV_OUT_OF_HOST_MEM;
      }
      std::memcpy(static_cast<void *>(*output_log), buildLog.c_str(),
                  buildLog.size() + 1);
    } else {
      *(output_log) = static_cast<char *>(NULL);
    }
  }

  if (err != 0) {
    return CLSPV_ERROR;
  }

  // Alloc and copy backing mem for spv output
  size_t spv_bytes = binary.size() * sizeof(uint32_t);
  if (spv_bytes == 0) {
    /** Early return: when allocation is not needed. */
    *output_binary = static_cast<char *>(NULL);
    return CLSPV_SUCCESS;
  }

  *output_binary = static_cast<char *>(std::malloc(spv_bytes));
  if (*output_binary == NULL) {
    return CLSPV_OUT_OF_HOST_MEM;
  }
  std::memcpy(static_cast<void *>(*output_binary), binary.data(), spv_bytes);
  *output_binary_size = spv_bytes;

  return CLSPV_SUCCESS;
}

void clspvFreeOutputBuildObjs(char *output_binary, char *output_log) {
  free(output_binary);
  output_binary = NULL;
  free(output_log);
  output_log = NULL;
}
