mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-20 14:29:27 +00:00
[Orc] Add an Orc layer for applying arbitrary transforms to IR, use it to add
debugging output to the LLI orc-lazy JIT, and update the orc-lazy "hello.ll" test to actually test for lazy compilation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234805 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
26117d38cc
commit
597d2b7309
101
include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
Normal file
101
include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
Normal file
@ -0,0 +1,101 @@
|
||||
//===----- IRTransformLayer.h - Run all IR through a functor ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Run all IR passed in through a user supplied functor.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
|
||||
#define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
|
||||
|
||||
#include "JITSymbol.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
/// @brief IR mutating layer.
|
||||
///
|
||||
/// This layer accepts sets of LLVM IR Modules (via addModuleSet). It
|
||||
/// immediately applies the user supplied functor to each module, then adds
|
||||
/// the set of transformed modules to the layer below.
|
||||
template <typename BaseLayerT, typename TransformFtor>
|
||||
class IRTransformLayer {
|
||||
public:
|
||||
/// @brief Handle to a set of added modules.
|
||||
typedef typename BaseLayerT::ModuleSetHandleT ModuleSetHandleT;
|
||||
|
||||
/// @brief Construct an IRTransformLayer with the given BaseLayer
|
||||
IRTransformLayer(BaseLayerT &BaseLayer,
|
||||
TransformFtor Transform = TransformFtor())
|
||||
: BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
|
||||
|
||||
/// @brief Apply the transform functor to each module in the module set, then
|
||||
/// add the resulting set of modules 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) {
|
||||
|
||||
for (auto I = Ms.begin(), E = Ms.end(); I != E; ++I)
|
||||
*I = Transform(std::move(*I));
|
||||
|
||||
return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr),
|
||||
std::move(Resolver));
|
||||
}
|
||||
|
||||
/// @brief Remove the module set associated with the handle H.
|
||||
void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeModuleSet(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
|
||||
/// 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 module set represented by the
|
||||
/// given handle.
|
||||
/// @param H Handle for module set to emit/finalize.
|
||||
void emitAndFinalize(ModuleSetHandleT H) {
|
||||
BaseLayer.emitAndFinalize(H);
|
||||
}
|
||||
|
||||
/// @brief Access the transform functor directly.
|
||||
TransformFtor& getTransform() { return Transform; }
|
||||
|
||||
/// @brief Access the mumate functor directly.
|
||||
const TransformFtor& getTransform() const { return Transform; }
|
||||
|
||||
private:
|
||||
BaseLayerT &BaseLayer;
|
||||
TransformFtor Transform;
|
||||
};
|
||||
|
||||
} // End namespace orc.
|
||||
} // End namespace llvm.
|
||||
|
||||
#endif // LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H
|
@ -1,7 +1,8 @@
|
||||
; RUN: lli -jit-kind=orc-lazy %s | FileCheck %s
|
||||
; RUN: lli -jit-kind=orc-lazy -orc-lazy-debug=funcs-to-stderr %s | FileCheck %s
|
||||
;
|
||||
; CHECK: Hello
|
||||
; CHECK-NEXT: Goodbye
|
||||
; CHECK: [ main$orc_body ]
|
||||
; CHECK: Goodbye
|
||||
|
||||
%class.Foo = type { i8 }
|
||||
|
||||
|
@ -9,26 +9,101 @@
|
||||
|
||||
#include "OrcLazyJIT.h"
|
||||
#include "llvm/ExecutionEngine/Orc/OrcTargetSupport.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
#include <system_error>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
enum class DumpKind { NoDump, DumpFuncsToStdErr, DumpModsToStdErr,
|
||||
DumpModsToDisk };
|
||||
|
||||
cl::opt<DumpKind> OrcDumpKind("orc-lazy-debug",
|
||||
cl::desc("Debug dumping for the orc-lazy JIT."),
|
||||
cl::init(DumpKind::NoDump),
|
||||
cl::values(
|
||||
clEnumValN(DumpKind::NoDump, "no-dump",
|
||||
"Don't dump anything."),
|
||||
clEnumValN(DumpKind::DumpFuncsToStdErr,
|
||||
"funcs-to-stderr",
|
||||
"Dump function names to stderr."),
|
||||
clEnumValN(DumpKind::DumpModsToStdErr,
|
||||
"mods-to-stderr",
|
||||
"Dump modules to stderr."),
|
||||
clEnumValN(DumpKind::DumpModsToDisk,
|
||||
"mods-to-disk",
|
||||
"Dump modules to the current "
|
||||
"working directory. (WARNING: "
|
||||
"will overwrite existing files)."),
|
||||
clEnumValEnd));
|
||||
}
|
||||
|
||||
OrcLazyJIT::CallbackManagerBuilder
|
||||
OrcLazyJIT::createCallbackManagerBuilder(Triple T) {
|
||||
switch (T.getArch()) {
|
||||
default: return nullptr;
|
||||
|
||||
case Triple::x86_64: {
|
||||
typedef orc::JITCompileCallbackManager<CompileLayerT,
|
||||
typedef orc::JITCompileCallbackManager<IRDumpLayerT,
|
||||
orc::OrcX86_64> CCMgrT;
|
||||
return [](CompileLayerT &CompileLayer, RuntimeDyld::MemoryManager &MemMgr,
|
||||
return [](IRDumpLayerT &IRDumpLayer, RuntimeDyld::MemoryManager &MemMgr,
|
||||
LLVMContext &Context) {
|
||||
return make_unique<CCMgrT>(CompileLayer, MemMgr, Context, 0, 64);
|
||||
return make_unique<CCMgrT>(IRDumpLayer, MemMgr, Context, 0, 64);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OrcLazyJIT::TransformFtor OrcLazyJIT::createDebugDumper() {
|
||||
|
||||
switch (OrcDumpKind) {
|
||||
case DumpKind::NoDump:
|
||||
return [](std::unique_ptr<Module> M) { return std::move(M); };
|
||||
|
||||
case DumpKind::DumpFuncsToStdErr:
|
||||
return [](std::unique_ptr<Module> M) {
|
||||
dbgs() << "[ ";
|
||||
|
||||
for (const auto &F : *M) {
|
||||
if (F.isDeclaration())
|
||||
continue;
|
||||
|
||||
if (F.hasName())
|
||||
dbgs() << F.getName() << " ";
|
||||
else
|
||||
dbgs() << "<anon> ";
|
||||
}
|
||||
|
||||
dbgs() << "]\n";
|
||||
return std::move(M);
|
||||
};
|
||||
|
||||
case DumpKind::DumpModsToStdErr:
|
||||
return [](std::unique_ptr<Module> M) {
|
||||
dbgs() << "----- Module Start -----\n" << *M
|
||||
<< "----- Module End -----\n";
|
||||
|
||||
return std::move(M);
|
||||
};
|
||||
|
||||
case DumpKind::DumpModsToDisk:
|
||||
return [](std::unique_ptr<Module> M) {
|
||||
std::error_code EC;
|
||||
raw_fd_ostream Out(M->getModuleIdentifier() + ".ll", EC,
|
||||
sys::fs::F_Text);
|
||||
if (EC) {
|
||||
errs() << "Couldn't open " << M->getModuleIdentifier()
|
||||
<< " for dumping.\nError:" << EC.message() << "\n";
|
||||
exit(1);
|
||||
}
|
||||
Out << *M;
|
||||
return std::move(M);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
int llvm::runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]) {
|
||||
// Add the program's symbols into the JIT's search space.
|
||||
if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
||||
@ -33,13 +34,16 @@ public:
|
||||
typedef orc::JITCompileCallbackManagerBase CompileCallbackMgr;
|
||||
typedef orc::ObjectLinkingLayer<> ObjLayerT;
|
||||
typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
|
||||
typedef orc::LazyEmittingLayer<CompileLayerT> LazyEmitLayerT;
|
||||
typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>
|
||||
TransformFtor;
|
||||
typedef orc::IRTransformLayer<CompileLayerT, TransformFtor> IRDumpLayerT;
|
||||
typedef orc::LazyEmittingLayer<IRDumpLayerT> LazyEmitLayerT;
|
||||
typedef orc::CompileOnDemandLayer<LazyEmitLayerT,
|
||||
CompileCallbackMgr> CODLayerT;
|
||||
typedef CODLayerT::ModuleSetHandleT ModuleHandleT;
|
||||
|
||||
typedef std::function<
|
||||
std::unique_ptr<CompileCallbackMgr>(CompileLayerT&,
|
||||
std::unique_ptr<CompileCallbackMgr>(IRDumpLayerT&,
|
||||
RuntimeDyld::MemoryManager&,
|
||||
LLVMContext&)>
|
||||
CallbackManagerBuilder;
|
||||
@ -52,8 +56,9 @@ public:
|
||||
Mang(this->TM->getDataLayout()),
|
||||
ObjectLayer(),
|
||||
CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)),
|
||||
LazyEmitLayer(CompileLayer),
|
||||
CCMgr(BuildCallbackMgr(CompileLayer, CCMgrMemMgr, Context)),
|
||||
IRDumpLayer(CompileLayer, createDebugDumper()),
|
||||
LazyEmitLayer(IRDumpLayer),
|
||||
CCMgr(BuildCallbackMgr(IRDumpLayer, CCMgrMemMgr, Context)),
|
||||
CODLayer(LazyEmitLayer, *CCMgr),
|
||||
CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {}
|
||||
|
||||
@ -137,12 +142,15 @@ private:
|
||||
return MangledName;
|
||||
}
|
||||
|
||||
static TransformFtor createDebugDumper();
|
||||
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
Mangler Mang;
|
||||
SectionMemoryManager CCMgrMemMgr;
|
||||
|
||||
ObjLayerT ObjectLayer;
|
||||
CompileLayerT CompileLayer;
|
||||
IRDumpLayerT IRDumpLayer;
|
||||
LazyEmitLayerT LazyEmitLayer;
|
||||
std::unique_ptr<CompileCallbackMgr> CCMgr;
|
||||
CODLayerT CODLayer;
|
||||
|
Loading…
x
Reference in New Issue
Block a user