|
@@ -0,0 +1,114 @@
|
|
|
+//===----- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope ----*- C++ -*-===//
|
|
|
+//
|
|
|
+// The LLVM Compiler Infrastructure
|
|
|
+//
|
|
|
+// This file is distributed under the University of Illinois Open Source
|
|
|
+// License. See LICENSE.TXT for details.
|
|
|
+//
|
|
|
+//===----------------------------------------------------------------------===//
|
|
|
+//
|
|
|
+// Contains a simple JIT definition for use in the kaleidoscope tutorials.
|
|
|
+//
|
|
|
+//===----------------------------------------------------------------------===//
|
|
|
+
|
|
|
+#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
|
|
|
+#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
|
|
|
+
|
|
|
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
|
|
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
|
|
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
|
|
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
|
|
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
|
|
|
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
|
|
|
+#include "llvm/IR/Mangler.h"
|
|
|
+#include "llvm/Support/DynamicLibrary.h"
|
|
|
+
|
|
|
+namespace llvm {
|
|
|
+namespace orc {
|
|
|
+
|
|
|
+class KaleidoscopeJIT {
|
|
|
+public:
|
|
|
+ typedef ObjectLinkingLayer<> ObjLayerT;
|
|
|
+ typedef IRCompileLayer<ObjLayerT> CompileLayerT;
|
|
|
+ typedef CompileLayerT::ModuleSetHandleT ModuleHandleT;
|
|
|
+
|
|
|
+ KaleidoscopeJIT()
|
|
|
+ : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
|
|
|
+ CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
|
|
|
+ llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
|
|
|
+ }
|
|
|
+
|
|
|
+ TargetMachine &getTargetMachine() { return *TM; }
|
|
|
+
|
|
|
+ ModuleHandleT addModule(std::unique_ptr<Module> M) {
|
|
|
+ // We need a memory manager to allocate memory and resolve symbols for this
|
|
|
+ // new module. Create one that resolves symbols by looking back into the
|
|
|
+ // JIT.
|
|
|
+ auto Resolver = createLambdaResolver(
|
|
|
+ [&](const std::string &Name) {
|
|
|
+ if (auto Sym = findMangledSymbol(Name))
|
|
|
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
|
|
|
+ return RuntimeDyld::SymbolInfo(nullptr);
|
|
|
+ },
|
|
|
+ [](const std::string &S) { return nullptr; });
|
|
|
+ auto H = CompileLayer.addModuleSet(singletonSet(std::move(M)),
|
|
|
+ make_unique<SectionMemoryManager>(),
|
|
|
+ std::move(Resolver));
|
|
|
+
|
|
|
+ ModuleHandles.push_back(H);
|
|
|
+ return H;
|
|
|
+ }
|
|
|
+
|
|
|
+ void removeModule(ModuleHandleT H) {
|
|
|
+ ModuleHandles.erase(
|
|
|
+ std::find(ModuleHandles.begin(), ModuleHandles.end(), H));
|
|
|
+ CompileLayer.removeModuleSet(H);
|
|
|
+ }
|
|
|
+
|
|
|
+ JITSymbol findSymbol(const std::string Name) {
|
|
|
+ return findMangledSymbol(mangle(Name));
|
|
|
+ }
|
|
|
+
|
|
|
+private:
|
|
|
+
|
|
|
+ std::string mangle(const std::string &Name) {
|
|
|
+ std::string MangledName;
|
|
|
+ {
|
|
|
+ raw_string_ostream MangledNameStream(MangledName);
|
|
|
+ Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
|
|
|
+ }
|
|
|
+ return MangledName;
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename T> static std::vector<T> singletonSet(T t) {
|
|
|
+ std::vector<T> Vec;
|
|
|
+ Vec.push_back(std::move(t));
|
|
|
+ return Vec;
|
|
|
+ }
|
|
|
+
|
|
|
+ JITSymbol findMangledSymbol(const std::string &Name) {
|
|
|
+ // Search modules in reverse order: from last added to first added.
|
|
|
+ // This is the opposite of the usual search order for dlsym, but makes more
|
|
|
+ // sense in a REPL where we want to bind to the newest available definition.
|
|
|
+ for (auto H : make_range(ModuleHandles.rbegin(), ModuleHandles.rend()))
|
|
|
+ if (auto Sym = CompileLayer.findSymbolIn(H, Name, true))
|
|
|
+ return Sym;
|
|
|
+
|
|
|
+ // If we can't find the symbol in the JIT, try looking in the host process.
|
|
|
+ if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
|
|
|
+ return JITSymbol(SymAddr, JITSymbolFlags::Exported);
|
|
|
+
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::unique_ptr<TargetMachine> TM;
|
|
|
+ const DataLayout DL;
|
|
|
+ ObjLayerT ObjectLayer;
|
|
|
+ CompileLayerT CompileLayer;
|
|
|
+ std::vector<ModuleHandleT> ModuleHandles;
|
|
|
+};
|
|
|
+
|
|
|
+} // End namespace orc.
|
|
|
+} // End namespace llvm
|
|
|
+
|
|
|
+#endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
|