From 0b57cec536236d46e3dba9bd041533462f33dbb7 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Fri, 20 Dec 2019 19:53:05 +0000 Subject: Move all sources from the llvm project into contrib/llvm-project. This uses the new layout of the upstream repository, which was recently migrated to GitHub, and converted into a "monorepo". That is, most of the earlier separate sub-projects with their own branches and tags were consolidated into one top-level directory, and are now branched and tagged together. Updating the vendor area to match this layout is next. --- .../llvm-project/llvm/lib/CodeGen/ParallelCG.cpp | 98 ++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 contrib/llvm-project/llvm/lib/CodeGen/ParallelCG.cpp (limited to 'contrib/llvm-project/llvm/lib/CodeGen/ParallelCG.cpp') diff --git a/contrib/llvm-project/llvm/lib/CodeGen/ParallelCG.cpp b/contrib/llvm-project/llvm/lib/CodeGen/ParallelCG.cpp new file mode 100644 index 000000000000..e4c73658cb4f --- /dev/null +++ b/contrib/llvm-project/llvm/lib/CodeGen/ParallelCG.cpp @@ -0,0 +1,98 @@ +//===-- ParallelCG.cpp ----------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// 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/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()> TMFactory, + TargetMachine::CodeGenFileType FileType) { + std::unique_ptr TM = TMFactory(); + legacy::PassManager CodeGenPasses; + if (TM->addPassesToEmitFile(CodeGenPasses, OS, nullptr, FileType)) + report_fatal_error("Failed to setup codegen"); + CodeGenPasses.run(*M); +} + +std::unique_ptr llvm::splitCodeGen( + std::unique_ptr M, ArrayRef OSs, + ArrayRef BCOSs, + const std::function()> &TMFactory, + TargetMachine::CodeGenFileType FileType, bool PreserveLocals) { + assert(BCOSs.empty() || BCOSs.size() == OSs.size()); + + if (OSs.size() == 1) { + if (!BCOSs.empty()) + WriteBitcodeToFile(*M, *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 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, 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> MOrErr = parseBitcodeFile( + MemoryBufferRef(StringRef(BC.data(), BC.size()), + ""), + Ctx); + if (!MOrErr) + report_fatal_error("Failed to read bitcode"); + std::unique_ptr 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 {}; +} -- cgit v1.2.3