//===-- ParallelCG.cpp ----------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines functions that can be used for parallel code generation.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/ParallelCG.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/SplitModule.h"

using namespace llvm;

static void codegen(Module *M, llvm::raw_pwrite_stream &OS,
                    function_ref<std::unique_ptr<TargetMachine>()> TMFactory,
                    TargetMachine::CodeGenFileType FileType) {
  std::unique_ptr<TargetMachine> TM = TMFactory();
  legacy::PassManager CodeGenPasses;
  if (TM->addPassesToEmitFile(CodeGenPasses, OS, FileType))
    report_fatal_error("Failed to setup codegen");
  CodeGenPasses.run(*M);
}

std::unique_ptr<Module> llvm::splitCodeGen(
    std::unique_ptr<Module> M, ArrayRef<llvm::raw_pwrite_stream *> OSs,
    ArrayRef<llvm::raw_pwrite_stream *> BCOSs,
    const std::function<std::unique_ptr<TargetMachine>()> &TMFactory,
    TargetMachine::CodeGenFileType FileType, bool PreserveLocals) {
  assert(BCOSs.empty() || BCOSs.size() == OSs.size());

  if (OSs.size() == 1) {
    if (!BCOSs.empty())
      WriteBitcodeToFile(M.get(), *BCOSs[0]);
    codegen(M.get(), *OSs[0], TMFactory, FileType);
    return M;
  }

  // Create ThreadPool in nested scope so that threads will be joined
  // on destruction.
  {
    ThreadPool CodegenThreadPool(OSs.size());
    int ThreadCount = 0;

    SplitModule(
        std::move(M), OSs.size(),
        [&](std::unique_ptr<Module> MPart) {
          // We want to clone the module in a new context to multi-thread the
          // codegen. We do it by serializing partition modules to bitcode
          // (while still on the main thread, in order to avoid data races) and
          // spinning up new threads which deserialize the partitions into
          // separate contexts.
          // FIXME: Provide a more direct way to do this in LLVM.
          SmallString<0> BC;
          raw_svector_ostream BCOS(BC);
          WriteBitcodeToFile(MPart.get(), BCOS);

          if (!BCOSs.empty()) {
            BCOSs[ThreadCount]->write(BC.begin(), BC.size());
            BCOSs[ThreadCount]->flush();
          }

          llvm::raw_pwrite_stream *ThreadOS = OSs[ThreadCount++];
          // Enqueue the task
          CodegenThreadPool.async(
              [TMFactory, FileType, ThreadOS](const SmallString<0> &BC) {
                LLVMContext Ctx;
                Expected<std::unique_ptr<Module>> MOrErr = parseBitcodeFile(
                    MemoryBufferRef(StringRef(BC.data(), BC.size()),
                                    "<split-module>"),
                    Ctx);
                if (!MOrErr)
                  report_fatal_error("Failed to read bitcode");
                std::unique_ptr<Module> MPartInCtx = std::move(MOrErr.get());

                codegen(MPartInCtx.get(), *ThreadOS, TMFactory, FileType);
              },
              // Pass BC using std::move to ensure that it get moved rather than
              // copied into the thread's context.
              std::move(BC));
        },
        PreserveLocals);
  }

  return {};
}
