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 class PrototypeAST; 39*9880d681SAndroid Build Coastguard Worker class ExprAST; 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Worker /// FunctionAST - This class represents a function definition itself. 42*9880d681SAndroid Build Coastguard Worker class FunctionAST { 43*9880d681SAndroid Build Coastguard Worker std::unique_ptr<PrototypeAST> Proto; 44*9880d681SAndroid Build Coastguard Worker std::unique_ptr<ExprAST> Body; 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker public: FunctionAST(std::unique_ptr<PrototypeAST> Proto,std::unique_ptr<ExprAST> Body)47*9880d681SAndroid Build Coastguard Worker FunctionAST(std::unique_ptr<PrototypeAST> Proto, 48*9880d681SAndroid Build Coastguard Worker std::unique_ptr<ExprAST> Body) 49*9880d681SAndroid Build Coastguard Worker : Proto(std::move(Proto)), Body(std::move(Body)) {} 50*9880d681SAndroid Build Coastguard Worker const PrototypeAST& getProto() const; 51*9880d681SAndroid Build Coastguard Worker const std::string& getName() const; 52*9880d681SAndroid Build Coastguard Worker llvm::Function *codegen(); 53*9880d681SAndroid Build Coastguard Worker }; 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard Worker /// This will compile FnAST to IR, rename the function to add the given 56*9880d681SAndroid Build Coastguard Worker /// suffix (needed to prevent a name-clash with the function's stub), 57*9880d681SAndroid Build Coastguard Worker /// and then take ownership of the module that the function was compiled 58*9880d681SAndroid Build Coastguard Worker /// into. 59*9880d681SAndroid Build Coastguard Worker std::unique_ptr<llvm::Module> 60*9880d681SAndroid Build Coastguard Worker irgenAndTakeOwnership(FunctionAST &FnAST, const std::string &Suffix); 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker namespace llvm { 63*9880d681SAndroid Build Coastguard Worker namespace orc { 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker class KaleidoscopeJIT { 66*9880d681SAndroid Build Coastguard Worker private: 67*9880d681SAndroid Build Coastguard Worker std::unique_ptr<TargetMachine> TM; 68*9880d681SAndroid Build Coastguard Worker const DataLayout DL; 69*9880d681SAndroid Build Coastguard Worker std::unique_ptr<JITCompileCallbackManager> CompileCallbackMgr; 70*9880d681SAndroid Build Coastguard Worker std::unique_ptr<IndirectStubsManager> IndirectStubsMgr; 71*9880d681SAndroid Build Coastguard Worker ObjectLinkingLayer<> ObjectLayer; 72*9880d681SAndroid Build Coastguard Worker IRCompileLayer<decltype(ObjectLayer)> CompileLayer; 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)> 75*9880d681SAndroid Build Coastguard Worker OptimizeFunction; 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer; 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker public: 80*9880d681SAndroid Build Coastguard Worker typedef decltype(OptimizeLayer)::ModuleSetHandleT ModuleHandle; 81*9880d681SAndroid Build Coastguard Worker KaleidoscopeJIT()82*9880d681SAndroid Build Coastguard Worker KaleidoscopeJIT() 83*9880d681SAndroid Build Coastguard Worker : TM(EngineBuilder().selectTarget()), 84*9880d681SAndroid Build Coastguard Worker DL(TM->createDataLayout()), 85*9880d681SAndroid Build Coastguard Worker CompileCallbackMgr( 86*9880d681SAndroid Build Coastguard Worker orc::createLocalCompileCallbackManager(TM->getTargetTriple(), 0)), 87*9880d681SAndroid Build Coastguard Worker CompileLayer(ObjectLayer, SimpleCompiler(*TM)), 88*9880d681SAndroid Build Coastguard Worker OptimizeLayer(CompileLayer, 89*9880d681SAndroid Build Coastguard Worker [this](std::unique_ptr<Module> M) { 90*9880d681SAndroid Build Coastguard Worker return optimizeModule(std::move(M)); 91*9880d681SAndroid Build Coastguard Worker }) { 92*9880d681SAndroid Build Coastguard Worker auto IndirectStubsMgrBuilder = 93*9880d681SAndroid Build Coastguard Worker orc::createLocalIndirectStubsManagerBuilder(TM->getTargetTriple()); 94*9880d681SAndroid Build Coastguard Worker IndirectStubsMgr = IndirectStubsMgrBuilder(); 95*9880d681SAndroid Build Coastguard Worker llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr); 96*9880d681SAndroid Build Coastguard Worker } 97*9880d681SAndroid Build Coastguard Worker getTargetMachine()98*9880d681SAndroid Build Coastguard Worker TargetMachine &getTargetMachine() { return *TM; } 99*9880d681SAndroid Build Coastguard Worker addModule(std::unique_ptr<Module> M)100*9880d681SAndroid Build Coastguard Worker ModuleHandle addModule(std::unique_ptr<Module> M) { 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Worker // Build our symbol resolver: 103*9880d681SAndroid Build Coastguard Worker // Lambda 1: Look back into the JIT itself to find symbols that are part of 104*9880d681SAndroid Build Coastguard Worker // the same "logical dylib". 105*9880d681SAndroid Build Coastguard Worker // Lambda 2: Search for external symbols in the host process. 106*9880d681SAndroid Build Coastguard Worker auto Resolver = createLambdaResolver( 107*9880d681SAndroid Build Coastguard Worker [&](const std::string &Name) { 108*9880d681SAndroid Build Coastguard Worker if (auto Sym = IndirectStubsMgr->findStub(Name, false)) 109*9880d681SAndroid Build Coastguard Worker return Sym.toRuntimeDyldSymbol(); 110*9880d681SAndroid Build Coastguard Worker if (auto Sym = OptimizeLayer.findSymbol(Name, false)) 111*9880d681SAndroid Build Coastguard Worker return Sym.toRuntimeDyldSymbol(); 112*9880d681SAndroid Build Coastguard Worker return RuntimeDyld::SymbolInfo(nullptr); 113*9880d681SAndroid Build Coastguard Worker }, 114*9880d681SAndroid Build Coastguard Worker [](const std::string &Name) { 115*9880d681SAndroid Build Coastguard Worker if (auto SymAddr = 116*9880d681SAndroid Build Coastguard Worker RTDyldMemoryManager::getSymbolAddressInProcess(Name)) 117*9880d681SAndroid Build Coastguard Worker return RuntimeDyld::SymbolInfo(SymAddr, JITSymbolFlags::Exported); 118*9880d681SAndroid Build Coastguard Worker return RuntimeDyld::SymbolInfo(nullptr); 119*9880d681SAndroid Build Coastguard Worker }); 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Worker // Build a singlton module set to hold our module. 122*9880d681SAndroid Build Coastguard Worker std::vector<std::unique_ptr<Module>> Ms; 123*9880d681SAndroid Build Coastguard Worker Ms.push_back(std::move(M)); 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Worker // Add the set to the JIT with the resolver we created above and a newly 126*9880d681SAndroid Build Coastguard Worker // created SectionMemoryManager. 127*9880d681SAndroid Build Coastguard Worker return OptimizeLayer.addModuleSet(std::move(Ms), 128*9880d681SAndroid Build Coastguard Worker make_unique<SectionMemoryManager>(), 129*9880d681SAndroid Build Coastguard Worker std::move(Resolver)); 130*9880d681SAndroid Build Coastguard Worker } 131*9880d681SAndroid Build Coastguard Worker addFunctionAST(std::unique_ptr<FunctionAST> FnAST)132*9880d681SAndroid Build Coastguard Worker Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) { 133*9880d681SAndroid Build Coastguard Worker // Create a CompileCallback - this is the re-entry point into the compiler 134*9880d681SAndroid Build Coastguard Worker // for functions that haven't been compiled yet. 135*9880d681SAndroid Build Coastguard Worker auto CCInfo = CompileCallbackMgr->getCompileCallback(); 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Worker // Create an indirect stub. This serves as the functions "canonical 138*9880d681SAndroid Build Coastguard Worker // definition" - an unchanging (constant address) entry point to the 139*9880d681SAndroid Build Coastguard Worker // function implementation. 140*9880d681SAndroid Build Coastguard Worker // Initially we point the stub's function-pointer at the compile callback 141*9880d681SAndroid Build Coastguard Worker // that we just created. In the compile action for the callback (see below) 142*9880d681SAndroid Build Coastguard Worker // we will update the stub's function pointer to point at the function 143*9880d681SAndroid Build Coastguard Worker // implementation that we just implemented. 144*9880d681SAndroid Build Coastguard Worker if (auto Err = IndirectStubsMgr->createStub(mangle(FnAST->getName()), 145*9880d681SAndroid Build Coastguard Worker CCInfo.getAddress(), 146*9880d681SAndroid Build Coastguard Worker JITSymbolFlags::Exported)) 147*9880d681SAndroid Build Coastguard Worker return Err; 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker // Move ownership of FnAST to a shared pointer - C++11 lambdas don't support 150*9880d681SAndroid Build Coastguard Worker // capture-by-move, which is be required for unique_ptr. 151*9880d681SAndroid Build Coastguard Worker auto SharedFnAST = std::shared_ptr<FunctionAST>(std::move(FnAST)); 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Worker // Set the action to compile our AST. This lambda will be run if/when 154*9880d681SAndroid Build Coastguard Worker // execution hits the compile callback (via the stub). 155*9880d681SAndroid Build Coastguard Worker // 156*9880d681SAndroid Build Coastguard Worker // The steps to compile are: 157*9880d681SAndroid Build Coastguard Worker // (1) IRGen the function. 158*9880d681SAndroid Build Coastguard Worker // (2) Add the IR module to the JIT to make it executable like any other 159*9880d681SAndroid Build Coastguard Worker // module. 160*9880d681SAndroid Build Coastguard Worker // (3) Use findSymbol to get the address of the compiled function. 161*9880d681SAndroid Build Coastguard Worker // (4) Update the stub pointer to point at the implementation so that 162*9880d681SAndroid Build Coastguard Worker /// subsequent calls go directly to it and bypass the compiler. 163*9880d681SAndroid Build Coastguard Worker // (5) Return the address of the implementation: this lambda will actually 164*9880d681SAndroid Build Coastguard Worker // be run inside an attempted call to the function, and we need to 165*9880d681SAndroid Build Coastguard Worker // continue on to the implementation to complete the attempted call. 166*9880d681SAndroid Build Coastguard Worker // The JIT runtime (the resolver block) will use the return address of 167*9880d681SAndroid Build Coastguard Worker // this function as the address to continue at once it has reset the 168*9880d681SAndroid Build Coastguard Worker // CPU state to what it was immediately before the call. 169*9880d681SAndroid Build Coastguard Worker CCInfo.setCompileAction( 170*9880d681SAndroid Build Coastguard Worker [this, SharedFnAST]() { 171*9880d681SAndroid Build Coastguard Worker auto M = irgenAndTakeOwnership(*SharedFnAST, "$impl"); 172*9880d681SAndroid Build Coastguard Worker addModule(std::move(M)); 173*9880d681SAndroid Build Coastguard Worker auto Sym = findSymbol(SharedFnAST->getName() + "$impl"); 174*9880d681SAndroid Build Coastguard Worker assert(Sym && "Couldn't find compiled function?"); 175*9880d681SAndroid Build Coastguard Worker TargetAddress SymAddr = Sym.getAddress(); 176*9880d681SAndroid Build Coastguard Worker if (auto Err = 177*9880d681SAndroid Build Coastguard Worker IndirectStubsMgr->updatePointer(mangle(SharedFnAST->getName()), 178*9880d681SAndroid Build Coastguard Worker SymAddr)) { 179*9880d681SAndroid Build Coastguard Worker logAllUnhandledErrors(std::move(Err), errs(), 180*9880d681SAndroid Build Coastguard Worker "Error updating function pointer: "); 181*9880d681SAndroid Build Coastguard Worker exit(1); 182*9880d681SAndroid Build Coastguard Worker } 183*9880d681SAndroid Build Coastguard Worker 184*9880d681SAndroid Build Coastguard Worker return SymAddr; 185*9880d681SAndroid Build Coastguard Worker }); 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Worker return Error::success(); 188*9880d681SAndroid Build Coastguard Worker } 189*9880d681SAndroid Build Coastguard Worker findSymbol(const std::string Name)190*9880d681SAndroid Build Coastguard Worker JITSymbol findSymbol(const std::string Name) { 191*9880d681SAndroid Build Coastguard Worker return OptimizeLayer.findSymbol(mangle(Name), true); 192*9880d681SAndroid Build Coastguard Worker } 193*9880d681SAndroid Build Coastguard Worker removeModule(ModuleHandle H)194*9880d681SAndroid Build Coastguard Worker void removeModule(ModuleHandle H) { 195*9880d681SAndroid Build Coastguard Worker OptimizeLayer.removeModuleSet(H); 196*9880d681SAndroid Build Coastguard Worker } 197*9880d681SAndroid Build Coastguard Worker 198*9880d681SAndroid Build Coastguard Worker private: 199*9880d681SAndroid Build Coastguard Worker mangle(const std::string & Name)200*9880d681SAndroid Build Coastguard Worker std::string mangle(const std::string &Name) { 201*9880d681SAndroid Build Coastguard Worker std::string MangledName; 202*9880d681SAndroid Build Coastguard Worker raw_string_ostream MangledNameStream(MangledName); 203*9880d681SAndroid Build Coastguard Worker Mangler::getNameWithPrefix(MangledNameStream, Name, DL); 204*9880d681SAndroid Build Coastguard Worker return MangledNameStream.str(); 205*9880d681SAndroid Build Coastguard Worker } 206*9880d681SAndroid Build Coastguard Worker optimizeModule(std::unique_ptr<Module> M)207*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) { 208*9880d681SAndroid Build Coastguard Worker // Create a function pass manager. 209*9880d681SAndroid Build Coastguard Worker auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get()); 210*9880d681SAndroid Build Coastguard Worker 211*9880d681SAndroid Build Coastguard Worker // Add some optimizations. 212*9880d681SAndroid Build Coastguard Worker FPM->add(createInstructionCombiningPass()); 213*9880d681SAndroid Build Coastguard Worker FPM->add(createReassociatePass()); 214*9880d681SAndroid Build Coastguard Worker FPM->add(createGVNPass()); 215*9880d681SAndroid Build Coastguard Worker FPM->add(createCFGSimplificationPass()); 216*9880d681SAndroid Build Coastguard Worker FPM->doInitialization(); 217*9880d681SAndroid Build Coastguard Worker 218*9880d681SAndroid Build Coastguard Worker // Run the optimizations over all functions in the module being added to 219*9880d681SAndroid Build Coastguard Worker // the JIT. 220*9880d681SAndroid Build Coastguard Worker for (auto &F : *M) 221*9880d681SAndroid Build Coastguard Worker FPM->run(F); 222*9880d681SAndroid Build Coastguard Worker 223*9880d681SAndroid Build Coastguard Worker return M; 224*9880d681SAndroid Build Coastguard Worker } 225*9880d681SAndroid Build Coastguard Worker 226*9880d681SAndroid Build Coastguard Worker }; 227*9880d681SAndroid Build Coastguard Worker 228*9880d681SAndroid Build Coastguard Worker } // end namespace orc 229*9880d681SAndroid Build Coastguard Worker } // end namespace llvm 230*9880d681SAndroid Build Coastguard Worker 231*9880d681SAndroid Build Coastguard Worker #endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H 232