1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-21 03:53:04 +02:00
llvm-mirror/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
Lang Hames 9a3ce89b6d [ExecutionEngine][MCJIT][Orc] Replace RuntimeDyld::SymbolInfo with JITSymbol.
This patch replaces RuntimeDyld::SymbolInfo with JITSymbol: A symbol class
that is capable of lazy materialization (i.e. the symbol definition needn't be
emitted until the address is requested). This can be used to support common
and weak symbols in the JIT (though this is not implemented in this patch).

For consistency, RuntimeDyld::SymbolResolver is renamed to JITSymbolResolver.

For space efficiency a new class, JITEvaluatedSymbol, is introduced that
behaves like the old RuntimeDyld::SymbolInfo - i.e. it is just a pair of an
address and symbol flags. Instances of JITEvaluatedSymbol can be used in
symbol-tables to avoid paying the space cost of the materializer.

llvm-svn: 277386
2016-08-01 20:49:11 +00:00

147 lines
5.3 KiB
C++

//===------ IRCompileLayer.h -- Eagerly compile IR for JIT ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Contains the definition for a basic, eagerly compiling layer of the JIT.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
#define LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/Object/ObjectFile.h"
#include <memory>
namespace llvm {
namespace orc {
/// @brief Eager IR compiling layer.
///
/// This layer accepts sets of LLVM IR Modules (via addModuleSet). It
/// immediately compiles each IR module to an object file (each IR Module is
/// compiled separately). The resulting set of object files is then added to
/// the layer below, which must implement the object layer concept.
template <typename BaseLayerT> class IRCompileLayer {
public:
typedef std::function<object::OwningBinary<object::ObjectFile>(Module &)>
CompileFtor;
private:
typedef typename BaseLayerT::ObjSetHandleT ObjSetHandleT;
public:
/// @brief Handle to a set of compiled modules.
typedef ObjSetHandleT ModuleSetHandleT;
/// @brief Construct an IRCompileLayer with the given BaseLayer, which must
/// implement the ObjectLayer concept.
IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile)
: BaseLayer(BaseLayer), Compile(std::move(Compile)), ObjCache(nullptr) {}
/// @brief Set an ObjectCache to query before compiling.
void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
/// @brief Compile each module in the given module set, then add the resulting
/// set of objects to the base layer along with the memory manager and
/// symbol resolver.
///
/// @return A handle for the added modules.
template <typename ModuleSetT, typename MemoryManagerPtrT,
typename SymbolResolverPtrT>
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
std::vector<std::unique_ptr<object::OwningBinary<object::ObjectFile>>>
Objects;
for (const auto &M : Ms) {
auto Object =
llvm::make_unique<object::OwningBinary<object::ObjectFile>>();
if (ObjCache)
*Object = tryToLoadFromObjectCache(*M);
if (!Object->getBinary()) {
*Object = Compile(*M);
if (ObjCache)
ObjCache->notifyObjectCompiled(&*M,
Object->getBinary()->getMemoryBufferRef());
}
Objects.push_back(std::move(Object));
}
ModuleSetHandleT H =
BaseLayer.addObjectSet(std::move(Objects), std::move(MemMgr),
std::move(Resolver));
return H;
}
/// @brief Remove the module set associated with the handle H.
void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); }
/// @brief Search for the given named symbol.
/// @param Name The name of the symbol to search for.
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it exists.
JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
/// @brief Get the address of the given symbol in the context of the set of
/// compiled modules represented by the handle H. This call is
/// forwarded to the base layer's implementation.
/// @param H The handle for the module set to search in.
/// @param Name The name of the symbol to search for.
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it is found in the
/// given module set.
JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
}
/// @brief Immediately emit and finalize the moduleOB set represented by the
/// given handle.
/// @param H Handle for module set to emit/finalize.
void emitAndFinalize(ModuleSetHandleT H) {
BaseLayer.emitAndFinalize(H);
}
private:
object::OwningBinary<object::ObjectFile>
tryToLoadFromObjectCache(const Module &M) {
std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M);
if (!ObjBuffer)
return object::OwningBinary<object::ObjectFile>();
Expected<std::unique_ptr<object::ObjectFile>> Obj =
object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
if (!Obj) {
// TODO: Actually report errors helpfully.
consumeError(Obj.takeError());
return object::OwningBinary<object::ObjectFile>();
}
return object::OwningBinary<object::ObjectFile>(std::move(*Obj),
std::move(ObjBuffer));
}
BaseLayerT &BaseLayer;
CompileFtor Compile;
ObjectCache *ObjCache;
};
} // End namespace orc.
} // End namespace llvm.
#endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H