1*9880d681SAndroid Build Coastguard Worker //===----- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope ----*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // Contains a simple JIT definition for use in the kaleidoscope tutorials. 11*9880d681SAndroid Build Coastguard Worker // 12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H 15*9880d681SAndroid Build Coastguard Worker #define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h" 18*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/ExecutionEngine.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/RuntimeDyld.h" 20*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/SectionMemoryManager.h" 21*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" 22*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/CompileUtils.h" 23*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/JITSymbol.h" 24*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" 25*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h" 26*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/LambdaResolver.h" 27*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 28*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h" 29*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Mangler.h" 30*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/DynamicLibrary.h" 31*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h" 32*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h" 33*9880d681SAndroid Build Coastguard Worker #include <algorithm> 34*9880d681SAndroid Build Coastguard Worker #include <memory> 35*9880d681SAndroid Build Coastguard Worker #include <string> 36*9880d681SAndroid Build Coastguard Worker #include <vector> 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker namespace llvm { 39*9880d681SAndroid Build Coastguard Worker namespace orc { 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Worker class KaleidoscopeJIT { 42*9880d681SAndroid Build Coastguard Worker private: 43*9880d681SAndroid Build Coastguard Worker std::unique_ptr<TargetMachine> TM; 44*9880d681SAndroid Build Coastguard Worker const DataLayout DL; 45*9880d681SAndroid Build Coastguard Worker std::unique_ptr<JITCompileCallbackManager> CompileCallbackManager; 46*9880d681SAndroid Build Coastguard Worker ObjectLinkingLayer<> ObjectLayer; 47*9880d681SAndroid Build Coastguard Worker IRCompileLayer<decltype(ObjectLayer)> CompileLayer; 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)> 50*9880d681SAndroid Build Coastguard Worker OptimizeFunction; 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer; 53*9880d681SAndroid Build Coastguard Worker CompileOnDemandLayer<decltype(OptimizeLayer)> CODLayer; 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard Worker public: 56*9880d681SAndroid Build Coastguard Worker typedef decltype(CODLayer)::ModuleSetHandleT ModuleHandle; 57*9880d681SAndroid Build Coastguard Worker KaleidoscopeJIT()58*9880d681SAndroid Build Coastguard Worker KaleidoscopeJIT() 59*9880d681SAndroid Build Coastguard Worker : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), 60*9880d681SAndroid Build Coastguard Worker CompileCallbackManager( 61*9880d681SAndroid Build Coastguard Worker orc::createLocalCompileCallbackManager(TM->getTargetTriple(), 0)), 62*9880d681SAndroid Build Coastguard Worker CompileLayer(ObjectLayer, SimpleCompiler(*TM)), 63*9880d681SAndroid Build Coastguard Worker OptimizeLayer(CompileLayer, 64*9880d681SAndroid Build Coastguard Worker [this](std::unique_ptr<Module> M) { 65*9880d681SAndroid Build Coastguard Worker return optimizeModule(std::move(M)); 66*9880d681SAndroid Build Coastguard Worker }), 67*9880d681SAndroid Build Coastguard Worker CODLayer(OptimizeLayer, 68*9880d681SAndroid Build Coastguard Worker [this](Function &F) { return std::set<Function*>({&F}); }, 69*9880d681SAndroid Build Coastguard Worker *CompileCallbackManager, 70*9880d681SAndroid Build Coastguard Worker orc::createLocalIndirectStubsManagerBuilder( 71*9880d681SAndroid Build Coastguard Worker TM->getTargetTriple())) { 72*9880d681SAndroid Build Coastguard Worker llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr); 73*9880d681SAndroid Build Coastguard Worker } 74*9880d681SAndroid Build Coastguard Worker getTargetMachine()75*9880d681SAndroid Build Coastguard Worker TargetMachine &getTargetMachine() { return *TM; } 76*9880d681SAndroid Build Coastguard Worker addModule(std::unique_ptr<Module> M)77*9880d681SAndroid Build Coastguard Worker ModuleHandle addModule(std::unique_ptr<Module> M) { 78*9880d681SAndroid Build Coastguard Worker // Build our symbol resolver: 79*9880d681SAndroid Build Coastguard Worker // Lambda 1: Look back into the JIT itself to find symbols that are part of 80*9880d681SAndroid Build Coastguard Worker // the same "logical dylib". 81*9880d681SAndroid Build Coastguard Worker // Lambda 2: Search for external symbols in the host process. 82*9880d681SAndroid Build Coastguard Worker auto Resolver = createLambdaResolver( 83*9880d681SAndroid Build Coastguard Worker [&](const std::string &Name) { 84*9880d681SAndroid Build Coastguard Worker if (auto Sym = CODLayer.findSymbol(Name, false)) 85*9880d681SAndroid Build Coastguard Worker return Sym.toRuntimeDyldSymbol(); 86*9880d681SAndroid Build Coastguard Worker return RuntimeDyld::SymbolInfo(nullptr); 87*9880d681SAndroid Build Coastguard Worker }, 88*9880d681SAndroid Build Coastguard Worker [](const std::string &Name) { 89*9880d681SAndroid Build Coastguard Worker if (auto SymAddr = 90*9880d681SAndroid Build Coastguard Worker RTDyldMemoryManager::getSymbolAddressInProcess(Name)) 91*9880d681SAndroid Build Coastguard Worker return RuntimeDyld::SymbolInfo(SymAddr, JITSymbolFlags::Exported); 92*9880d681SAndroid Build Coastguard Worker return RuntimeDyld::SymbolInfo(nullptr); 93*9880d681SAndroid Build Coastguard Worker }); 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Worker // Build a singlton module set to hold our module. 96*9880d681SAndroid Build Coastguard Worker std::vector<std::unique_ptr<Module>> Ms; 97*9880d681SAndroid Build Coastguard Worker Ms.push_back(std::move(M)); 98*9880d681SAndroid Build Coastguard Worker 99*9880d681SAndroid Build Coastguard Worker // Add the set to the JIT with the resolver we created above and a newly 100*9880d681SAndroid Build Coastguard Worker // created SectionMemoryManager. 101*9880d681SAndroid Build Coastguard Worker return CODLayer.addModuleSet(std::move(Ms), 102*9880d681SAndroid Build Coastguard Worker make_unique<SectionMemoryManager>(), 103*9880d681SAndroid Build Coastguard Worker std::move(Resolver)); 104*9880d681SAndroid Build Coastguard Worker } 105*9880d681SAndroid Build Coastguard Worker findSymbol(const std::string Name)106*9880d681SAndroid Build Coastguard Worker JITSymbol findSymbol(const std::string Name) { 107*9880d681SAndroid Build Coastguard Worker std::string MangledName; 108*9880d681SAndroid Build Coastguard Worker raw_string_ostream MangledNameStream(MangledName); 109*9880d681SAndroid Build Coastguard Worker Mangler::getNameWithPrefix(MangledNameStream, Name, DL); 110*9880d681SAndroid Build Coastguard Worker return CODLayer.findSymbol(MangledNameStream.str(), true); 111*9880d681SAndroid Build Coastguard Worker } 112*9880d681SAndroid Build Coastguard Worker removeModule(ModuleHandle H)113*9880d681SAndroid Build Coastguard Worker void removeModule(ModuleHandle H) { 114*9880d681SAndroid Build Coastguard Worker CODLayer.removeModuleSet(H); 115*9880d681SAndroid Build Coastguard Worker } 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Worker private: 118*9880d681SAndroid Build Coastguard Worker optimizeModule(std::unique_ptr<Module> M)119*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) { 120*9880d681SAndroid Build Coastguard Worker // Create a function pass manager. 121*9880d681SAndroid Build Coastguard Worker auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get()); 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker // Add some optimizations. 124*9880d681SAndroid Build Coastguard Worker FPM->add(createInstructionCombiningPass()); 125*9880d681SAndroid Build Coastguard Worker FPM->add(createReassociatePass()); 126*9880d681SAndroid Build Coastguard Worker FPM->add(createGVNPass()); 127*9880d681SAndroid Build Coastguard Worker FPM->add(createCFGSimplificationPass()); 128*9880d681SAndroid Build Coastguard Worker FPM->doInitialization(); 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Worker // Run the optimizations over all functions in the module being added to 131*9880d681SAndroid Build Coastguard Worker // the JIT. 132*9880d681SAndroid Build Coastguard Worker for (auto &F : *M) 133*9880d681SAndroid Build Coastguard Worker FPM->run(F); 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Worker return M; 136*9880d681SAndroid Build Coastguard Worker } 137*9880d681SAndroid Build Coastguard Worker 138*9880d681SAndroid Build Coastguard Worker }; 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Worker } // end namespace orc 141*9880d681SAndroid Build Coastguard Worker } // end namespace llvm 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Worker #endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H 144