LLVM  14.0.0git
ParallelCG.cpp
Go to the documentation of this file.
1 //===-- ParallelCG.cpp ----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines functions that can be used for parallel code generation.
10 //
11 //===----------------------------------------------------------------------===//
12 
16 #include "llvm/IR/LLVMContext.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/Support/ErrorOr.h"
24 
25 using namespace llvm;
26 
28  function_ref<std::unique_ptr<TargetMachine>()> TMFactory,
30  std::unique_ptr<TargetMachine> TM = TMFactory();
31  assert(TM && "Failed to create target machine!");
32 
33  legacy::PassManager CodeGenPasses;
34  if (TM->addPassesToEmitFile(CodeGenPasses, OS, nullptr, FileType))
35  report_fatal_error("Failed to setup codegen");
36  CodeGenPasses.run(*M);
37 }
38 
42  const std::function<std::unique_ptr<TargetMachine>()> &TMFactory,
43  CodeGenFileType FileType, bool PreserveLocals) {
44  assert(BCOSs.empty() || BCOSs.size() == OSs.size());
45 
46  if (OSs.size() == 1) {
47  if (!BCOSs.empty())
48  WriteBitcodeToFile(M, *BCOSs[0]);
49  codegen(&M, *OSs[0], TMFactory, FileType);
50  return;
51  }
52 
53  // Create ThreadPool in nested scope so that threads will be joined
54  // on destruction.
55  {
56  ThreadPool CodegenThreadPool(hardware_concurrency(OSs.size()));
57  int ThreadCount = 0;
58 
60  M, OSs.size(),
61  [&](std::unique_ptr<Module> MPart) {
62  // We want to clone the module in a new context to multi-thread the
63  // codegen. We do it by serializing partition modules to bitcode
64  // (while still on the main thread, in order to avoid data races) and
65  // spinning up new threads which deserialize the partitions into
66  // separate contexts.
67  // FIXME: Provide a more direct way to do this in LLVM.
68  SmallString<0> BC;
69  raw_svector_ostream BCOS(BC);
70  WriteBitcodeToFile(*MPart, BCOS);
71 
72  if (!BCOSs.empty()) {
73  BCOSs[ThreadCount]->write(BC.begin(), BC.size());
74  BCOSs[ThreadCount]->flush();
75  }
76 
77  llvm::raw_pwrite_stream *ThreadOS = OSs[ThreadCount++];
78  // Enqueue the task
79  CodegenThreadPool.async(
80  [TMFactory, FileType, ThreadOS](const SmallString<0> &BC) {
81  LLVMContext Ctx;
82  Expected<std::unique_ptr<Module>> MOrErr = parseBitcodeFile(
83  MemoryBufferRef(StringRef(BC.data(), BC.size()),
84  "<split-module>"),
85  Ctx);
86  if (!MOrErr)
87  report_fatal_error("Failed to read bitcode");
88  std::unique_ptr<Module> MPartInCtx = std::move(MOrErr.get());
89 
90  codegen(MPartInCtx.get(), *ThreadOS, TMFactory, FileType);
91  },
92  // Pass BC using std::move to ensure that it get moved rather than
93  // copied into the thread's context.
94  std::move(BC));
95  },
96  PreserveLocals);
97  }
98 }
MemoryBuffer.h
llvm::hardware_concurrency
ThreadPoolStrategy hardware_concurrency(unsigned ThreadCount=0)
Returns a default thread strategy where all available hardware resources are to be used,...
Definition: Threading.h:188
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::ThreadPool
A ThreadPool for asynchronous parallel execution on a defined number of threads.
Definition: ThreadPool.h:37
codegen
static void codegen(Module *M, llvm::raw_pwrite_stream &OS, function_ref< std::unique_ptr< TargetMachine >()> TMFactory, CodeGenFileType FileType)
Definition: ParallelCG.cpp:27
ParallelCG.h
Module.h
LegacyPassManager.h
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:158
TargetMachine.h
BitcodeWriter.h
SplitModule.h
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:143
llvm::SmallString< 0 >
llvm::MachO::FileType
FileType
Defines the file type this file represents.
Definition: InterfaceFile.h:57
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:168
ThreadPool.h
llvm::raw_pwrite_stream
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:417
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
ErrorOr.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::WriteBitcodeToFile
void WriteBitcodeToFile(const Module &M, raw_ostream &Out, bool ShouldPreserveUseListOrder=false, const ModuleSummaryIndex *Index=nullptr, bool GenerateHash=false, ModuleHash *ModHash=nullptr)
Write the specified module to the specified raw output stream.
Definition: BitcodeWriter.cpp:4620
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::CodeGenFileType
CodeGenFileType
These enums are meant to be passed into addPassesToEmitFile to indicate what type of file to emit,...
Definition: CodeGen.h:63
llvm::ThreadPool::async
auto async(Function &&F, Args &&...ArgList)
Asynchronous submission of a task to the pool.
Definition: ThreadPool.h:51
llvm::legacy::PassManager
PassManager manages ModulePassManagers.
Definition: LegacyPassManager.h:52
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
llvm::legacy::PassManager::run
bool run(Module &M)
run - Execute all of the passes scheduled for execution.
Definition: LegacyPassManager.cpp:1680
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
LLVMContext.h
BitcodeReader.h
llvm::SplitModule
void SplitModule(Module &M, unsigned N, function_ref< void(std::unique_ptr< Module > MPart)> ModuleCallback, bool PreserveLocals=false)
Splits the module M into N linkable partitions.
Definition: SplitModule.cpp:251
llvm::splitCodeGen
void splitCodeGen(Module &M, ArrayRef< raw_pwrite_stream * > OSs, ArrayRef< llvm::raw_pwrite_stream * > BCOSs, const std::function< std::unique_ptr< TargetMachine >()> &TMFactory, CodeGenFileType FileType=CGFT_ObjectFile, bool PreserveLocals=false)
Split M into OSs.size() partitions, and generate code for each.
Definition: ParallelCG.cpp:39