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