127 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			4.2 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/JITSymbolFlags.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/JITSymbol.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.toRuntimeDyldSymbol();
 | 
						|
          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
 |