forked from OSchip/llvm-project
[ParallelCG] Add a new splitCodeGen() API which takes a TargetMachineFactory.
This is a recommit of r266390 with a fix that will allow tests to pass (hopefully). Before we got a StringRef to M->getTargetTriple() and right after we moved the Module so we were referencing a dangling object. llvm-svn: 266456
This commit is contained in:
parent
dca3812252
commit
7950b12957
|
@ -18,6 +18,8 @@
|
|||
#include "llvm/Support/CodeGen.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Module;
|
||||
|
@ -43,6 +45,18 @@ splitCodeGen(std::unique_ptr<Module> M, ArrayRef<raw_pwrite_stream *> OSs,
|
|||
TargetMachine::CodeGenFileType FT = TargetMachine::CGFT_ObjectFile,
|
||||
bool PreserveLocals = false);
|
||||
|
||||
/// Split M into OSs.size() partitions, and generate code for each.
|
||||
/// It is a variant that takes a factory function for the TargetMachine
|
||||
/// TMFactory. See the other splitCodeGen() for a more detailed description.
|
||||
///
|
||||
/// \returns M if OSs.size() == 1, otherwise returns std::unique_ptr<Module>().
|
||||
std::unique_ptr<Module>
|
||||
splitCodeGen(std::unique_ptr<Module> M, ArrayRef<raw_pwrite_stream *> OSs,
|
||||
ArrayRef<llvm::raw_pwrite_stream *> BCOSs,
|
||||
const std::function<std::unique_ptr<TargetMachine>()> &TMFactory,
|
||||
TargetMachine::CodeGenFileType FT = TargetMachine::CGFT_ObjectFile,
|
||||
bool PreserveLocals = false);
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,39 +25,47 @@
|
|||
|
||||
using namespace llvm;
|
||||
|
||||
static void codegen(Module *M, llvm::raw_pwrite_stream &OS,
|
||||
const Target *TheTarget, StringRef CPU, StringRef Features,
|
||||
const TargetOptions &Options, Reloc::Model RM,
|
||||
CodeModel::Model CM, CodeGenOpt::Level OL,
|
||||
TargetMachine::CodeGenFileType FileType) {
|
||||
std::unique_ptr<TargetMachine> TM(TheTarget->createTargetMachine(
|
||||
M->getTargetTriple(), CPU, Features, Options, RM, CM, OL));
|
||||
|
||||
static void
|
||||
codegen(Module *M, llvm::raw_pwrite_stream &OS,
|
||||
std::function<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, StringRef CPU,
|
||||
StringRef Features, const TargetOptions &Options, Reloc::Model RM,
|
||||
CodeModel::Model CM, CodeGenOpt::Level OL,
|
||||
TargetMachine::CodeGenFileType FileType, bool PreserveLocals) {
|
||||
StringRef TripleStr = M->getTargetTriple();
|
||||
std::unique_ptr<Module>
|
||||
llvm::splitCodeGen(std::unique_ptr<Module> M, ArrayRef<raw_pwrite_stream *> OSs,
|
||||
ArrayRef<llvm::raw_pwrite_stream *> BCOSs, StringRef CPU,
|
||||
StringRef Features, const TargetOptions &Options,
|
||||
Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL,
|
||||
TargetMachine::CodeGenFileType FileType,
|
||||
bool PreserveLocals) {
|
||||
std::string TripleStr = M->getTargetTriple();
|
||||
std::string ErrMsg;
|
||||
|
||||
const Target *TheTarget = TargetRegistry::lookupTarget(TripleStr, ErrMsg);
|
||||
if (!TheTarget)
|
||||
report_fatal_error(Twine("Target not found: ") + ErrMsg);
|
||||
return splitCodeGen(std::move(M), OSs, BCOSs, [&]() {
|
||||
return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
|
||||
TripleStr, CPU, Features, Options, RM, CM, OL));
|
||||
}, FileType, PreserveLocals);
|
||||
}
|
||||
|
||||
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], TheTarget, CPU, Features, Options, RM, CM, OL,
|
||||
FileType);
|
||||
codegen(M.get(), *OSs[0], TMFactory, FileType);
|
||||
return M;
|
||||
}
|
||||
|
||||
|
@ -88,8 +96,7 @@ std::unique_ptr<Module> llvm::splitCodeGen(
|
|||
llvm::raw_pwrite_stream *ThreadOS = OSs[ThreadCount++];
|
||||
// Enqueue the task
|
||||
CodegenThreadPool.async(
|
||||
[TheTarget, CPU, Features, Options, RM, CM, OL, FileType,
|
||||
ThreadOS](const SmallVector<char, 0> &BC) {
|
||||
[TMFactory, FileType, ThreadOS](const SmallVector<char, 0> &BC) {
|
||||
LLVMContext Ctx;
|
||||
ErrorOr<std::unique_ptr<Module>> MOrErr = parseBitcodeFile(
|
||||
MemoryBufferRef(StringRef(BC.data(), BC.size()),
|
||||
|
@ -99,8 +106,7 @@ std::unique_ptr<Module> llvm::splitCodeGen(
|
|||
report_fatal_error("Failed to read bitcode");
|
||||
std::unique_ptr<Module> MPartInCtx = std::move(MOrErr.get());
|
||||
|
||||
codegen(MPartInCtx.get(), *ThreadOS, TheTarget, CPU, Features,
|
||||
Options, RM, CM, OL, FileType);
|
||||
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.
|
||||
|
|
Loading…
Reference in New Issue