mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
8d353ae157
NFC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230143 91177308-0d34-0410-b5e6-96231b3b80d8
147 lines
5.3 KiB
C++
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 "JITSymbol.h"
|
|
#include "llvm/ExecutionEngine/ObjectCache.h"
|
|
#include "llvm/ExecutionEngine/RTDyldMemoryManager.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;
|
|
|
|
typedef std::vector<std::unique_ptr<object::ObjectFile>> OwningObjectVec;
|
|
typedef std::vector<std::unique_ptr<MemoryBuffer>> OwningBufferVec;
|
|
|
|
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 then add the
|
|
/// resulting set of objects to the base layer, along with the memory
|
|
// manager MM.
|
|
///
|
|
/// @return A handle for the added modules.
|
|
template <typename ModuleSetT>
|
|
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
|
|
std::unique_ptr<RTDyldMemoryManager> MM) {
|
|
OwningObjectVec Objects;
|
|
OwningBufferVec Buffers;
|
|
|
|
for (const auto &M : Ms) {
|
|
std::unique_ptr<object::ObjectFile> Object;
|
|
std::unique_ptr<MemoryBuffer> Buffer;
|
|
|
|
if (ObjCache)
|
|
std::tie(Object, Buffer) = tryToLoadFromObjectCache(*M).takeBinary();
|
|
|
|
if (!Object) {
|
|
std::tie(Object, Buffer) = Compile(*M).takeBinary();
|
|
if (ObjCache)
|
|
ObjCache->notifyObjectCompiled(&*M, Buffer->getMemBufferRef());
|
|
}
|
|
|
|
Objects.push_back(std::move(Object));
|
|
Buffers.push_back(std::move(Buffer));
|
|
}
|
|
|
|
ModuleSetHandleT H =
|
|
BaseLayer.addObjectSet(Objects, std::move(MM));
|
|
|
|
BaseLayer.takeOwnershipOfBuffers(H, std::move(Buffers));
|
|
|
|
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>();
|
|
|
|
ErrorOr<std::unique_ptr<object::ObjectFile>> Obj =
|
|
object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
|
|
if (!Obj)
|
|
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
|