diff options
author | dim <dim@FreeBSD.org> | 2015-12-30 13:13:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-12-30 13:13:10 +0000 |
commit | 9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a (patch) | |
tree | b466a4817f79516eb1df8eae92bccf62ecc84003 /contrib/llvm/lib/LTO | |
parent | f09a28d1de99fda4f5517fb12670fc36552f4927 (diff) | |
parent | e194cd6d03d91631334d9d5e55b506036f423cc8 (diff) | |
download | FreeBSD-src-9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a.zip FreeBSD-src-9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a.tar.gz |
Update llvm to trunk r256633.
Diffstat (limited to 'contrib/llvm/lib/LTO')
-rw-r--r-- | contrib/llvm/lib/LTO/LTOCodeGenerator.cpp | 329 | ||||
-rw-r--r-- | contrib/llvm/lib/LTO/LTOModule.cpp | 155 |
2 files changed, 211 insertions, 273 deletions
diff --git a/contrib/llvm/lib/LTO/LTOCodeGenerator.cpp b/contrib/llvm/lib/LTO/LTOCodeGenerator.cpp index 25ae4ac..6baaaa4 100644 --- a/contrib/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/contrib/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -18,6 +18,7 @@ #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/CodeGen/ParallelCG.h" #include "llvm/CodeGen/RuntimeLibcalls.h" #include "llvm/Config/config.h" #include "llvm/IR/Constants.h" @@ -63,47 +64,15 @@ const char* LTOCodeGenerator::getVersionString() { #endif } -static void handleLTODiagnostic(const DiagnosticInfo &DI) { - DiagnosticPrinterRawOStream DP(errs()); - DI.print(DP); - errs() << "\n"; -} - -LTOCodeGenerator::LTOCodeGenerator() - : Context(getGlobalContext()), IRLinker(new Module("ld-temp.o", Context), - handleLTODiagnostic) { - initializeLTOPasses(); -} - -LTOCodeGenerator::LTOCodeGenerator(std::unique_ptr<LLVMContext> Context) - : OwnedContext(std::move(Context)), Context(*OwnedContext), - IRLinker(new Module("ld-temp.o", *OwnedContext), handleLTODiagnostic) { +LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context) + : Context(Context), MergedModule(new Module("ld-temp.o", Context)), + TheLinker(new Linker(*MergedModule)) { initializeLTOPasses(); } -void LTOCodeGenerator::destroyMergedModule() { - if (OwnedModule) { - assert(IRLinker.getModule() == &OwnedModule->getModule() && - "The linker's module should be the same as the owned module"); - delete OwnedModule; - OwnedModule = nullptr; - } else if (IRLinker.getModule()) - IRLinker.deleteModule(); -} - -LTOCodeGenerator::~LTOCodeGenerator() { - destroyMergedModule(); +LTOCodeGenerator::~LTOCodeGenerator() {} - delete TargetMach; - TargetMach = nullptr; - - for (std::vector<char *>::iterator I = CodegenOptions.begin(), - E = CodegenOptions.end(); - I != E; ++I) - free(*I); -} - -// Initialize LTO passes. Please keep this funciton in sync with +// Initialize LTO passes. Please keep this function in sync with // PassManagerBuilder::populateLTOPassManager(), and make sure all LTO // passes are initialized. void LTOCodeGenerator::initializeLTOPasses() { @@ -120,11 +89,11 @@ void LTOCodeGenerator::initializeLTOPasses() { initializeGlobalDCEPass(R); initializeArgPromotionPass(R); initializeJumpThreadingPass(R); - initializeSROAPass(R); + initializeSROALegacyPassPass(R); initializeSROA_DTPass(R); initializeSROA_SSAUpPass(R); initializeFunctionAttrsPass(R); - initializeGlobalsModRefPass(R); + initializeGlobalsAAWrapperPassPass(R); initializeLICMPass(R); initializeMergedLoadStoreMotionPass(R); initializeGVNPass(R); @@ -133,41 +102,39 @@ void LTOCodeGenerator::initializeLTOPasses() { initializeCFGSimplifyPassPass(R); } -bool LTOCodeGenerator::addModule(LTOModule *mod) { - assert(&mod->getModule().getContext() == &Context && +bool LTOCodeGenerator::addModule(LTOModule *Mod) { + assert(&Mod->getModule().getContext() == &Context && "Expected module in same context"); - bool ret = IRLinker.linkInModule(&mod->getModule()); + bool ret = TheLinker->linkInModule(Mod->takeModule()); - const std::vector<const char*> &undefs = mod->getAsmUndefinedRefs(); + const std::vector<const char *> &undefs = Mod->getAsmUndefinedRefs(); for (int i = 0, e = undefs.size(); i != e; ++i) AsmUndefinedRefs[undefs[i]] = 1; return !ret; } -void LTOCodeGenerator::setModule(LTOModule *Mod) { +void LTOCodeGenerator::setModule(std::unique_ptr<LTOModule> Mod) { assert(&Mod->getModule().getContext() == &Context && "Expected module in same context"); - // Delete the old merged module. - destroyMergedModule(); AsmUndefinedRefs.clear(); - OwnedModule = Mod; - IRLinker.setModule(&Mod->getModule()); + MergedModule = Mod->takeModule(); + TheLinker = make_unique<Linker>(*MergedModule); const std::vector<const char*> &Undefs = Mod->getAsmUndefinedRefs(); for (int I = 0, E = Undefs.size(); I != E; ++I) AsmUndefinedRefs[Undefs[I]] = 1; } -void LTOCodeGenerator::setTargetOptions(TargetOptions options) { - Options = options; +void LTOCodeGenerator::setTargetOptions(TargetOptions Options) { + this->Options = Options; } -void LTOCodeGenerator::setDebugInfo(lto_debug_model debug) { - switch (debug) { +void LTOCodeGenerator::setDebugInfo(lto_debug_model Debug) { + switch (Debug) { case LTO_DEBUG_MODEL_NONE: EmitDwarfDebugInfo = false; return; @@ -179,21 +146,26 @@ void LTOCodeGenerator::setDebugInfo(lto_debug_model debug) { llvm_unreachable("Unknown debug format!"); } -void LTOCodeGenerator::setCodePICModel(lto_codegen_model model) { - switch (model) { - case LTO_CODEGEN_PIC_MODEL_STATIC: - case LTO_CODEGEN_PIC_MODEL_DYNAMIC: - case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: - case LTO_CODEGEN_PIC_MODEL_DEFAULT: - CodeModel = model; - return; +void LTOCodeGenerator::setOptLevel(unsigned Level) { + OptLevel = Level; + switch (OptLevel) { + case 0: + CGOptLevel = CodeGenOpt::None; + break; + case 1: + CGOptLevel = CodeGenOpt::Less; + break; + case 2: + CGOptLevel = CodeGenOpt::Default; + break; + case 3: + CGOptLevel = CodeGenOpt::Aggressive; + break; } - llvm_unreachable("Unknown PIC model!"); } -bool LTOCodeGenerator::writeMergedModules(const char *path, - std::string &errMsg) { - if (!determineTarget(errMsg)) +bool LTOCodeGenerator::writeMergedModules(const char *Path) { + if (!determineTarget()) return false; // mark which symbols can not be internalized @@ -201,20 +173,22 @@ bool LTOCodeGenerator::writeMergedModules(const char *path, // create output file std::error_code EC; - tool_output_file Out(path, EC, sys::fs::F_None); + tool_output_file Out(Path, EC, sys::fs::F_None); if (EC) { - errMsg = "could not open bitcode file for writing: "; - errMsg += path; + std::string ErrMsg = "could not open bitcode file for writing: "; + ErrMsg += Path; + emitError(ErrMsg); return false; } // write bitcode to it - WriteBitcodeToFile(IRLinker.getModule(), Out.os(), ShouldEmbedUselists); + WriteBitcodeToFile(MergedModule.get(), Out.os(), ShouldEmbedUselists); Out.os().close(); if (Out.os().has_error()) { - errMsg = "could not write bitcode file: "; - errMsg += path; + std::string ErrMsg = "could not write bitcode file: "; + ErrMsg += Path; + emitError(ErrMsg); Out.os().clear_error(); return false; } @@ -223,22 +197,25 @@ bool LTOCodeGenerator::writeMergedModules(const char *path, return true; } -bool LTOCodeGenerator::compileOptimizedToFile(const char **name, - std::string &errMsg) { - // make unique temp .o file to put generated object file +bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) { + // make unique temp output file to put generated code SmallString<128> Filename; int FD; + + const char *Extension = + (FileType == TargetMachine::CGFT_AssemblyFile ? "s" : "o"); + std::error_code EC = - sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename); + sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename); if (EC) { - errMsg = EC.message(); + emitError(EC.message()); return false; } // generate object file tool_output_file objFile(Filename.c_str(), FD); - bool genResult = compileOptimized(objFile.os(), errMsg); + bool genResult = compileOptimized(&objFile.os()); objFile.os().close(); if (objFile.os().has_error()) { objFile.os().clear_error(); @@ -253,21 +230,21 @@ bool LTOCodeGenerator::compileOptimizedToFile(const char **name, } NativeObjectPath = Filename.c_str(); - *name = NativeObjectPath.c_str(); + *Name = NativeObjectPath.c_str(); return true; } std::unique_ptr<MemoryBuffer> -LTOCodeGenerator::compileOptimized(std::string &errMsg) { +LTOCodeGenerator::compileOptimized() { const char *name; - if (!compileOptimizedToFile(&name, errMsg)) + if (!compileOptimizedToFile(&name)) return nullptr; // read .o file into memory buffer ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFile(name, -1, false); if (std::error_code EC = BufferOrErr.getError()) { - errMsg = EC.message(); + emitError(EC.message()); sys::fs::remove(NativeObjectPath); return nullptr; } @@ -278,66 +255,51 @@ LTOCodeGenerator::compileOptimized(std::string &errMsg) { return std::move(*BufferOrErr); } - -bool LTOCodeGenerator::compile_to_file(const char **name, - bool disableInline, - bool disableGVNLoadPRE, - bool disableVectorization, - std::string &errMsg) { - if (!optimize(disableInline, disableGVNLoadPRE, - disableVectorization, errMsg)) +bool LTOCodeGenerator::compile_to_file(const char **Name, bool DisableVerify, + bool DisableInline, + bool DisableGVNLoadPRE, + bool DisableVectorization) { + if (!optimize(DisableVerify, DisableInline, DisableGVNLoadPRE, + DisableVectorization)) return false; - return compileOptimizedToFile(name, errMsg); + return compileOptimizedToFile(Name); } std::unique_ptr<MemoryBuffer> -LTOCodeGenerator::compile(bool disableInline, bool disableGVNLoadPRE, - bool disableVectorization, std::string &errMsg) { - if (!optimize(disableInline, disableGVNLoadPRE, - disableVectorization, errMsg)) +LTOCodeGenerator::compile(bool DisableVerify, bool DisableInline, + bool DisableGVNLoadPRE, bool DisableVectorization) { + if (!optimize(DisableVerify, DisableInline, DisableGVNLoadPRE, + DisableVectorization)) return nullptr; - return compileOptimized(errMsg); + return compileOptimized(); } -bool LTOCodeGenerator::determineTarget(std::string &errMsg) { +bool LTOCodeGenerator::determineTarget() { if (TargetMach) return true; - std::string TripleStr = IRLinker.getModule()->getTargetTriple(); - if (TripleStr.empty()) + std::string TripleStr = MergedModule->getTargetTriple(); + if (TripleStr.empty()) { TripleStr = sys::getDefaultTargetTriple(); + MergedModule->setTargetTriple(TripleStr); + } llvm::Triple Triple(TripleStr); // create target machine from info for merged modules - const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg); - if (!march) + std::string ErrMsg; + const Target *march = TargetRegistry::lookupTarget(TripleStr, ErrMsg); + if (!march) { + emitError(ErrMsg); return false; - - // The relocation model is actually a static member of TargetMachine and - // needs to be set before the TargetMachine is instantiated. - Reloc::Model RelocModel = Reloc::Default; - switch (CodeModel) { - case LTO_CODEGEN_PIC_MODEL_STATIC: - RelocModel = Reloc::Static; - break; - case LTO_CODEGEN_PIC_MODEL_DYNAMIC: - RelocModel = Reloc::PIC_; - break; - case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: - RelocModel = Reloc::DynamicNoPIC; - break; - case LTO_CODEGEN_PIC_MODEL_DEFAULT: - // RelocModel is already the default, so leave it that way. - break; } // Construct LTOModule, hand over ownership of module and target. Use MAttr as // the default set of features. SubtargetFeatures Features(MAttr); Features.getDefaultSubtargetFeatures(Triple); - std::string FeatureStr = Features.getString(); + FeatureStr = Features.getString(); // Set a default CPU for Darwin triples. if (MCpu.empty() && Triple.isOSDarwin()) { if (Triple.getArch() == llvm::Triple::x86_64) @@ -348,25 +310,9 @@ bool LTOCodeGenerator::determineTarget(std::string &errMsg) { MCpu = "cyclone"; } - CodeGenOpt::Level CGOptLevel; - switch (OptLevel) { - case 0: - CGOptLevel = CodeGenOpt::None; - break; - case 1: - CGOptLevel = CodeGenOpt::Less; - break; - case 2: - CGOptLevel = CodeGenOpt::Default; - break; - case 3: - CGOptLevel = CodeGenOpt::Aggressive; - break; - } - - TargetMach = march->createTargetMachine(TripleStr, MCpu, FeatureStr, Options, - RelocModel, CodeModel::Default, - CGOptLevel); + TargetMach.reset(march->createTargetMachine(TripleStr, MCpu, FeatureStr, + Options, RelocModel, + CodeModel::Default, CGOptLevel)); return true; } @@ -453,7 +399,6 @@ static void accumulateAndSortLibcalls(std::vector<StringRef> &Libcalls, void LTOCodeGenerator::applyScopeRestrictions() { if (ScopeRestrictionsDone || !ShouldInternalize) return; - Module *mergedModule = IRLinker.getModule(); // Start off with a verification pass. legacy::PassManager passes; @@ -467,20 +412,17 @@ void LTOCodeGenerator::applyScopeRestrictions() { TargetLibraryInfoImpl TLII(Triple(TargetMach->getTargetTriple())); TargetLibraryInfo TLI(TLII); - accumulateAndSortLibcalls(Libcalls, TLI, *mergedModule, *TargetMach); + accumulateAndSortLibcalls(Libcalls, TLI, *MergedModule, *TargetMach); - for (Module::iterator f = mergedModule->begin(), - e = mergedModule->end(); f != e; ++f) - applyRestriction(*f, Libcalls, MustPreserveList, AsmUsed, Mangler); - for (Module::global_iterator v = mergedModule->global_begin(), - e = mergedModule->global_end(); v != e; ++v) - applyRestriction(*v, Libcalls, MustPreserveList, AsmUsed, Mangler); - for (Module::alias_iterator a = mergedModule->alias_begin(), - e = mergedModule->alias_end(); a != e; ++a) - applyRestriction(*a, Libcalls, MustPreserveList, AsmUsed, Mangler); + for (Function &f : *MergedModule) + applyRestriction(f, Libcalls, MustPreserveList, AsmUsed, Mangler); + for (GlobalVariable &v : MergedModule->globals()) + applyRestriction(v, Libcalls, MustPreserveList, AsmUsed, Mangler); + for (GlobalAlias &a : MergedModule->aliases()) + applyRestriction(a, Libcalls, MustPreserveList, AsmUsed, Mangler); GlobalVariable *LLVMCompilerUsed = - mergedModule->getGlobalVariable("llvm.compiler.used"); + MergedModule->getGlobalVariable("llvm.compiler.used"); findUsedValues(LLVMCompilerUsed, AsmUsed); if (LLVMCompilerUsed) LLVMCompilerUsed->eraseFromParent(); @@ -495,7 +437,7 @@ void LTOCodeGenerator::applyScopeRestrictions() { llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size()); LLVMCompilerUsed = - new llvm::GlobalVariable(*mergedModule, ATy, false, + new llvm::GlobalVariable(*MergedModule, ATy, false, llvm::GlobalValue::AppendingLinkage, llvm::ConstantArray::get(ATy, asmUsed2), "llvm.compiler.used"); @@ -506,21 +448,18 @@ void LTOCodeGenerator::applyScopeRestrictions() { passes.add(createInternalizePass(MustPreserveList)); // apply scope restrictions - passes.run(*mergedModule); + passes.run(*MergedModule); ScopeRestrictionsDone = true; } /// Optimize merged modules using various IPO passes -bool LTOCodeGenerator::optimize(bool DisableInline, +bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline, bool DisableGVNLoadPRE, - bool DisableVectorization, - std::string &errMsg) { - if (!this->determineTarget(errMsg)) + bool DisableVectorization) { + if (!this->determineTarget()) return false; - Module *mergedModule = IRLinker.getModule(); - // Mark which symbols can not be internalized this->applyScopeRestrictions(); @@ -528,7 +467,7 @@ bool LTOCodeGenerator::optimize(bool DisableInline, legacy::PassManager passes; // Add an appropriate DataLayout instance for this module... - mergedModule->setDataLayout(*TargetMach->getDataLayout()); + MergedModule->setDataLayout(TargetMach->createDataLayout()); passes.add( createTargetTransformInfoWrapperPass(TargetMach->getTargetIRAnalysis())); @@ -542,60 +481,57 @@ bool LTOCodeGenerator::optimize(bool DisableInline, PMB.Inliner = createFunctionInliningPass(); PMB.LibraryInfo = new TargetLibraryInfoImpl(TargetTriple); PMB.OptLevel = OptLevel; - PMB.VerifyInput = true; - PMB.VerifyOutput = true; + PMB.VerifyInput = !DisableVerify; + PMB.VerifyOutput = !DisableVerify; PMB.populateLTOPassManager(passes); // Run our queue of passes all at once now, efficiently. - passes.run(*mergedModule); + passes.run(*MergedModule); return true; } -bool LTOCodeGenerator::compileOptimized(raw_pwrite_stream &out, - std::string &errMsg) { - if (!this->determineTarget(errMsg)) +bool LTOCodeGenerator::compileOptimized(ArrayRef<raw_pwrite_stream *> Out) { + if (!this->determineTarget()) return false; - Module *mergedModule = IRLinker.getModule(); - - legacy::PassManager codeGenPasses; + legacy::PassManager preCodeGenPasses; // If the bitcode files contain ARC code and were compiled with optimization, // the ObjCARCContractPass must be run, so do it unconditionally here. - codeGenPasses.add(createObjCARCContractPass()); - - if (TargetMach->addPassesToEmitFile(codeGenPasses, out, - TargetMachine::CGFT_ObjectFile)) { - errMsg = "target file type not supported"; - return false; - } - - // Run the code generator, and write assembly file - codeGenPasses.run(*mergedModule); + preCodeGenPasses.add(createObjCARCContractPass()); + preCodeGenPasses.run(*MergedModule); + + // Do code generation. We need to preserve the module in case the client calls + // writeMergedModules() after compilation, but we only need to allow this at + // parallelism level 1. This is achieved by having splitCodeGen return the + // original module at parallelism level 1 which we then assign back to + // MergedModule. + MergedModule = + splitCodeGen(std::move(MergedModule), Out, MCpu, FeatureStr, Options, + RelocModel, CodeModel::Default, CGOptLevel, FileType); return true; } /// setCodeGenDebugOptions - Set codegen debugging options to aid in debugging /// LTO problems. -void LTOCodeGenerator::setCodeGenDebugOptions(const char *options) { - for (std::pair<StringRef, StringRef> o = getToken(options); - !o.first.empty(); o = getToken(o.second)) { - // ParseCommandLineOptions() expects argv[0] to be program name. Lazily add - // that. - if (CodegenOptions.empty()) - CodegenOptions.push_back(strdup("libLLVMLTO")); - CodegenOptions.push_back(strdup(o.first.str().c_str())); - } +void LTOCodeGenerator::setCodeGenDebugOptions(const char *Options) { + for (std::pair<StringRef, StringRef> o = getToken(Options); !o.first.empty(); + o = getToken(o.second)) + CodegenOptions.push_back(o.first); } void LTOCodeGenerator::parseCodeGenDebugOptions() { // if options were requested, set them - if (!CodegenOptions.empty()) - cl::ParseCommandLineOptions(CodegenOptions.size(), - const_cast<char **>(&CodegenOptions[0])); + if (!CodegenOptions.empty()) { + // ParseCommandLineOptions() expects argv[0] to be program name. + std::vector<const char *> CodegenArgv(1, "libLLVMLTO"); + for (std::string &Arg : CodegenOptions) + CodegenArgv.push_back(Arg.c_str()); + cl::ParseCommandLineOptions(CodegenArgv.size(), CodegenArgv.data()); + } } void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI, @@ -645,3 +581,20 @@ LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler, Context.setDiagnosticHandler(LTOCodeGenerator::DiagnosticHandler, this, /* RespectFilters */ true); } + +namespace { +class LTODiagnosticInfo : public DiagnosticInfo { + const Twine &Msg; +public: + LTODiagnosticInfo(const Twine &DiagMsg, DiagnosticSeverity Severity=DS_Error) + : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {} + void print(DiagnosticPrinter &DP) const override { DP << Msg; } +}; +} + +void LTOCodeGenerator::emitError(const std::string &ErrMsg) { + if (DiagHandler) + (*DiagHandler)(LTO_DS_ERROR, ErrMsg.c_str(), DiagContext); + else + Context.diagnose(LTODiagnosticInfo(ErrMsg)); +} diff --git a/contrib/llvm/lib/LTO/LTOModule.cpp b/contrib/llvm/lib/LTO/LTOModule.cpp index 53ed417..409b949 100644 --- a/contrib/llvm/lib/LTO/LTOModule.cpp +++ b/contrib/llvm/lib/LTO/LTOModule.cpp @@ -91,106 +91,97 @@ bool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer, return StringRef(Triple).startswith(TriplePrefix); } -LTOModule *LTOModule::createFromFile(const char *path, TargetOptions options, - std::string &errMsg) { +std::string LTOModule::getProducerString(MemoryBuffer *Buffer) { + ErrorOr<MemoryBufferRef> BCOrErr = + IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef()); + if (!BCOrErr) + return ""; + LLVMContext Context; + return getBitcodeProducerString(*BCOrErr, Context); +} + +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::createFromFile(LLVMContext &Context, const char *path, + TargetOptions options) { ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFile(path); - if (std::error_code EC = BufferOrErr.getError()) { - errMsg = EC.message(); - return nullptr; - } + if (std::error_code EC = BufferOrErr.getError()) + return EC; std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get()); - return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg, - &getGlobalContext()); + return makeLTOModule(Buffer->getMemBufferRef(), options, &Context); } -LTOModule *LTOModule::createFromOpenFile(int fd, const char *path, size_t size, - TargetOptions options, - std::string &errMsg) { - return createFromOpenFileSlice(fd, path, size, 0, options, errMsg); +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::createFromOpenFile(LLVMContext &Context, int fd, const char *path, + size_t size, TargetOptions options) { + return createFromOpenFileSlice(Context, fd, path, size, 0, options); } -LTOModule *LTOModule::createFromOpenFileSlice(int fd, const char *path, - size_t map_size, off_t offset, - TargetOptions options, - std::string &errMsg) { +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::createFromOpenFileSlice(LLVMContext &Context, int fd, + const char *path, size_t map_size, + off_t offset, TargetOptions options) { ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getOpenFileSlice(fd, path, map_size, offset); - if (std::error_code EC = BufferOrErr.getError()) { - errMsg = EC.message(); - return nullptr; - } + if (std::error_code EC = BufferOrErr.getError()) + return EC; std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get()); - return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg, - &getGlobalContext()); + return makeLTOModule(Buffer->getMemBufferRef(), options, &Context); } -LTOModule *LTOModule::createFromBuffer(const void *mem, size_t length, - TargetOptions options, - std::string &errMsg, StringRef path) { - return createInContext(mem, length, options, errMsg, path, - &getGlobalContext()); +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::createFromBuffer(LLVMContext &Context, const void *mem, + size_t length, TargetOptions options, + StringRef path) { + return createInContext(mem, length, options, path, &Context); } -LTOModule *LTOModule::createInLocalContext(const void *mem, size_t length, - TargetOptions options, - std::string &errMsg, - StringRef path) { - return createInContext(mem, length, options, errMsg, path, nullptr); +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::createInLocalContext(const void *mem, size_t length, + TargetOptions options, StringRef path) { + return createInContext(mem, length, options, path, nullptr); } -LTOModule *LTOModule::createInContext(const void *mem, size_t length, - TargetOptions options, - std::string &errMsg, StringRef path, - LLVMContext *Context) { +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::createInContext(const void *mem, size_t length, + TargetOptions options, StringRef path, + LLVMContext *Context) { StringRef Data((const char *)mem, length); MemoryBufferRef Buffer(Data, path); - return makeLTOModule(Buffer, options, errMsg, Context); + return makeLTOModule(Buffer, options, Context); } -static std::unique_ptr<Module> parseBitcodeFileImpl(MemoryBufferRef Buffer, - LLVMContext &Context, - bool ShouldBeLazy, - std::string &ErrMsg) { +static ErrorOr<std::unique_ptr<Module>> +parseBitcodeFileImpl(MemoryBufferRef Buffer, LLVMContext &Context, + bool ShouldBeLazy) { // Find the buffer. ErrorOr<MemoryBufferRef> MBOrErr = IRObjectFile::findBitcodeInMemBuffer(Buffer); - if (std::error_code EC = MBOrErr.getError()) { - ErrMsg = EC.message(); - return nullptr; - } - - std::function<void(const DiagnosticInfo &)> DiagnosticHandler = - [&ErrMsg](const DiagnosticInfo &DI) { - raw_string_ostream Stream(ErrMsg); - DiagnosticPrinterRawOStream DP(Stream); - DI.print(DP); - }; + if (std::error_code EC = MBOrErr.getError()) + return EC; if (!ShouldBeLazy) { // Parse the full file. - ErrorOr<std::unique_ptr<Module>> M = - parseBitcodeFile(*MBOrErr, Context, DiagnosticHandler); - if (!M) - return nullptr; + ErrorOr<std::unique_ptr<Module>> M = parseBitcodeFile(*MBOrErr, Context); + if (std::error_code EC = M.getError()) + return EC; return std::move(*M); } // Parse lazily. std::unique_ptr<MemoryBuffer> LightweightBuf = MemoryBuffer::getMemBuffer(*MBOrErr, false); - ErrorOr<std::unique_ptr<Module>> M = - getLazyBitcodeModule(std::move(LightweightBuf), Context, - DiagnosticHandler, true /*ShouldLazyLoadMetadata*/); - if (!M) - return nullptr; + ErrorOr<std::unique_ptr<Module>> M = getLazyBitcodeModule( + std::move(LightweightBuf), Context, true /*ShouldLazyLoadMetadata*/); + if (std::error_code EC = M.getError()) + return EC; return std::move(*M); } -LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, - TargetOptions options, std::string &errMsg, - LLVMContext *Context) { +ErrorOr<std::unique_ptr<LTOModule>> +LTOModule::makeLTOModule(MemoryBufferRef Buffer, TargetOptions options, + LLVMContext *Context) { std::unique_ptr<LLVMContext> OwnedContext; if (!Context) { OwnedContext = llvm::make_unique<LLVMContext>(); @@ -199,11 +190,12 @@ LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, // If we own a context, we know this is being used only for symbol // extraction, not linking. Be lazy in that case. - std::unique_ptr<Module> M = parseBitcodeFileImpl( - Buffer, *Context, - /* ShouldBeLazy */ static_cast<bool>(OwnedContext), errMsg); - if (!M) - return nullptr; + ErrorOr<std::unique_ptr<Module>> MOrErr = + parseBitcodeFileImpl(Buffer, *Context, + /* ShouldBeLazy */ static_cast<bool>(OwnedContext)); + if (std::error_code EC = MOrErr.getError()) + return EC; + std::unique_ptr<Module> &M = *MOrErr; std::string TripleStr = M->getTargetTriple(); if (TripleStr.empty()) @@ -211,9 +203,10 @@ LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, llvm::Triple Triple(TripleStr); // find machine architecture for this module + std::string errMsg; const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg); if (!march) - return nullptr; + return std::unique_ptr<LTOModule>(nullptr); // construct LTOModule, hand over ownership of module and target SubtargetFeatures Features; @@ -232,25 +225,21 @@ LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr, options); - M->setDataLayout(*target->getDataLayout()); + M->setDataLayout(target->createDataLayout()); std::unique_ptr<object::IRObjectFile> IRObj( new object::IRObjectFile(Buffer, std::move(M))); - LTOModule *Ret; + std::unique_ptr<LTOModule> Ret; if (OwnedContext) - Ret = new LTOModule(std::move(IRObj), target, std::move(OwnedContext)); + Ret.reset(new LTOModule(std::move(IRObj), target, std::move(OwnedContext))); else - Ret = new LTOModule(std::move(IRObj), target); - - if (Ret->parseSymbols(errMsg)) { - delete Ret; - return nullptr; - } + Ret.reset(new LTOModule(std::move(IRObj), target)); + Ret->parseSymbols(); Ret->parseMetadata(); - return Ret; + return std::move(Ret); } /// Create a MemoryBuffer from a memory range with an optional name. @@ -583,9 +572,7 @@ void LTOModule::addPotentialUndefinedSymbol(const object::BasicSymbolRef &Sym, info.symbol = decl; } -/// parseSymbols - Parse the symbols from the module and model-level ASM and add -/// them to either the defined or undefined lists. -bool LTOModule::parseSymbols(std::string &errMsg) { +void LTOModule::parseSymbols() { for (auto &Sym : IRFile->symbols()) { const GlobalValue *GV = IRFile->getSymbolGV(Sym.getRawDataRefImpl()); uint32_t Flags = Sym.getFlags(); @@ -640,8 +627,6 @@ bool LTOModule::parseSymbols(std::string &errMsg) { NameAndAttributes info = u->getValue(); _symbols.push_back(info); } - - return false; } /// parseMetadata - Parse metadata from the module |