forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			125 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			125 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===----- 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/ADT/iterator_range.h"
 | |
| #include "llvm/ADT/STLExtras.h"
 | |
| #include "llvm/ExecutionEngine/ExecutionEngine.h"
 | |
| #include "llvm/ExecutionEngine/JITSymbol.h"
 | |
| #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
 | |
| #include "llvm/ExecutionEngine/RuntimeDyld.h"
 | |
| #include "llvm/ExecutionEngine/SectionMemoryManager.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/DataLayout.h"
 | |
| #include "llvm/IR/Mangler.h"
 | |
| #include "llvm/Support/DynamicLibrary.h"
 | |
| #include "llvm/Support/raw_ostream.h"
 | |
| #include "llvm/Target/TargetMachine.h"
 | |
| #include <algorithm>
 | |
| #include <memory>
 | |
| #include <string>
 | |
| #include <vector>
 | |
| 
 | |
| 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 Sym;
 | |
|           return JITSymbol(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(find(ModuleHandles, 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
 |