diff options
Diffstat (limited to 'include/llvm/ExecutionEngine/Orc/CompileUtils.h')
-rw-r--r-- | include/llvm/ExecutionEngine/Orc/CompileUtils.h | 86 |
1 files changed, 52 insertions, 34 deletions
diff --git a/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/include/llvm/ExecutionEngine/Orc/CompileUtils.h index b9f7d6accc30..213a59124c85 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileUtils.h +++ b/include/llvm/ExecutionEngine/Orc/CompileUtils.h @@ -16,13 +16,14 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ExecutionEngine/ObjectCache.h" -#include "llvm/ExecutionEngine/ObjectMemoryBuffer.h" +#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/Object/Binary.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SmallVectorMemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include <algorithm> @@ -35,45 +36,51 @@ class Module; namespace orc { -/// @brief Simple compile functor: Takes a single IR module and returns an -/// ObjectFile. +/// Simple compile functor: Takes a single IR module and returns an ObjectFile. +/// This compiler supports a single compilation thread and LLVMContext only. +/// For multithreaded compilation, use MultiThreadedSimpleCompiler below. class SimpleCompiler { public: + using CompileResult = std::unique_ptr<MemoryBuffer>; - using CompileResult = object::OwningBinary<object::ObjectFile>; - - /// @brief Construct a simple compile functor with the given target. + /// Construct a simple compile functor with the given target. SimpleCompiler(TargetMachine &TM, ObjectCache *ObjCache = nullptr) : TM(TM), ObjCache(ObjCache) {} - /// @brief Set an ObjectCache to query before compiling. + /// Set an ObjectCache to query before compiling. void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; } - /// @brief Compile a Module to an ObjectFile. + /// Compile a Module to an ObjectFile. CompileResult operator()(Module &M) { CompileResult CachedObject = tryToLoadFromObjectCache(M); - if (CachedObject.getBinary()) + if (CachedObject) return CachedObject; SmallVector<char, 0> ObjBufferSV; - raw_svector_ostream ObjStream(ObjBufferSV); - - legacy::PassManager PM; - MCContext *Ctx; - if (TM.addPassesToEmitMC(PM, Ctx, ObjStream)) - llvm_unreachable("Target does not support MC emission."); - PM.run(M); - std::unique_ptr<MemoryBuffer> ObjBuffer( - new ObjectMemoryBuffer(std::move(ObjBufferSV))); - Expected<std::unique_ptr<object::ObjectFile>> Obj = + + { + raw_svector_ostream ObjStream(ObjBufferSV); + + legacy::PassManager PM; + MCContext *Ctx; + if (TM.addPassesToEmitMC(PM, Ctx, ObjStream)) + llvm_unreachable("Target does not support MC emission."); + PM.run(M); + } + + auto ObjBuffer = + llvm::make_unique<SmallVectorMemoryBuffer>(std::move(ObjBufferSV)); + auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); + if (Obj) { notifyObjectCompiled(M, *ObjBuffer); - return CompileResult(std::move(*Obj), std::move(ObjBuffer)); + return std::move(ObjBuffer); } + // TODO: Actually report errors helpfully. consumeError(Obj.takeError()); - return CompileResult(nullptr, nullptr); + return nullptr; } private: @@ -82,19 +89,7 @@ private: if (!ObjCache) return CompileResult(); - std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M); - if (!ObjBuffer) - return CompileResult(); - - Expected<std::unique_ptr<object::ObjectFile>> Obj = - object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); - if (!Obj) { - // TODO: Actually report errors helpfully. - consumeError(Obj.takeError()); - return CompileResult(); - } - - return CompileResult(std::move(*Obj), std::move(ObjBuffer)); + return ObjCache->getObject(&M); } void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer) { @@ -106,6 +101,29 @@ private: ObjectCache *ObjCache = nullptr; }; +/// A thread-safe version of SimpleCompiler. +/// +/// This class creates a new TargetMachine and SimpleCompiler instance for each +/// compile. +class MultiThreadedSimpleCompiler { +public: + MultiThreadedSimpleCompiler(JITTargetMachineBuilder JTMB, + ObjectCache *ObjCache = nullptr) + : JTMB(std::move(JTMB)), ObjCache(ObjCache) {} + + void setObjectCache(ObjectCache *ObjCache) { this->ObjCache = ObjCache; } + + std::unique_ptr<MemoryBuffer> operator()(Module &M) { + auto TM = cantFail(JTMB.createTargetMachine()); + SimpleCompiler C(*TM, ObjCache); + return C(M); + } + +private: + JITTargetMachineBuilder JTMB; + ObjectCache *ObjCache = nullptr; +}; + } // end namespace orc } // end namespace llvm |