163 lines · c
1//===- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope --------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Contains a simple JIT definition for use in the kaleidoscope tutorials.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H14#define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H15 16#include "llvm/ADT/StringRef.h"17#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"18#include "llvm/ExecutionEngine/Orc/CompileUtils.h"19#include "llvm/ExecutionEngine/Orc/Core.h"20#include "llvm/ExecutionEngine/Orc/EPCIndirectionUtils.h"21#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"22#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"23#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"24#include "llvm/ExecutionEngine/Orc/IRPartitionLayer.h"25#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"26#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"27#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"28#include "llvm/ExecutionEngine/Orc/SelfExecutorProcessControl.h"29#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"30#include "llvm/ExecutionEngine/SectionMemoryManager.h"31#include "llvm/IR/DataLayout.h"32#include "llvm/IR/LLVMContext.h"33#include "llvm/IR/LegacyPassManager.h"34#include "llvm/Transforms/InstCombine/InstCombine.h"35#include "llvm/Transforms/Scalar.h"36#include "llvm/Transforms/Scalar/GVN.h"37#include <memory>38 39namespace llvm {40namespace orc {41 42class KaleidoscopeJIT {43private:44 std::unique_ptr<ExecutionSession> ES;45 std::unique_ptr<EPCIndirectionUtils> EPCIU;46 47 DataLayout DL;48 MangleAndInterner Mangle;49 50 RTDyldObjectLinkingLayer ObjectLayer;51 IRCompileLayer CompileLayer;52 IRTransformLayer OptimizeLayer;53 IRPartitionLayer IPLayer;54 CompileOnDemandLayer CODLayer;55 56 JITDylib &MainJD;57 58 static void handleLazyCallThroughError() {59 errs() << "LazyCallThrough error: Could not find function body";60 exit(1);61 }62 63public:64 KaleidoscopeJIT(std::unique_ptr<ExecutionSession> ES,65 std::unique_ptr<EPCIndirectionUtils> EPCIU,66 JITTargetMachineBuilder JTMB, DataLayout DL)67 : ES(std::move(ES)), EPCIU(std::move(EPCIU)), DL(std::move(DL)),68 Mangle(*this->ES, this->DL),69 ObjectLayer(*this->ES,70 [](const MemoryBuffer &) {71 return std::make_unique<SectionMemoryManager>();72 }),73 CompileLayer(*this->ES, ObjectLayer,74 std::make_unique<ConcurrentIRCompiler>(std::move(JTMB))),75 OptimizeLayer(*this->ES, CompileLayer, optimizeModule),76 IPLayer(*this->ES, OptimizeLayer),77 CODLayer(*this->ES, IPLayer, this->EPCIU->getLazyCallThroughManager(),78 [this] { return this->EPCIU->createIndirectStubsManager(); }),79 MainJD(this->ES->createBareJITDylib("<main>")) {80 MainJD.addGenerator(81 cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(82 DL.getGlobalPrefix())));83 }84 85 ~KaleidoscopeJIT() {86 if (auto Err = ES->endSession())87 ES->reportError(std::move(Err));88 if (auto Err = EPCIU->cleanup())89 ES->reportError(std::move(Err));90 }91 92 static Expected<std::unique_ptr<KaleidoscopeJIT>> Create() {93 auto EPC = SelfExecutorProcessControl::Create();94 if (!EPC)95 return EPC.takeError();96 97 auto ES = std::make_unique<ExecutionSession>(std::move(*EPC));98 99 auto EPCIU = EPCIndirectionUtils::Create(*ES);100 if (!EPCIU)101 return EPCIU.takeError();102 103 (*EPCIU)->createLazyCallThroughManager(104 *ES, ExecutorAddr::fromPtr(&handleLazyCallThroughError));105 106 if (auto Err = setUpInProcessLCTMReentryViaEPCIU(**EPCIU))107 return std::move(Err);108 109 JITTargetMachineBuilder JTMB(110 ES->getExecutorProcessControl().getTargetTriple());111 112 auto DL = JTMB.getDefaultDataLayoutForTarget();113 if (!DL)114 return DL.takeError();115 116 return std::make_unique<KaleidoscopeJIT>(std::move(ES), std::move(*EPCIU),117 std::move(JTMB), std::move(*DL));118 }119 120 const DataLayout &getDataLayout() const { return DL; }121 122 JITDylib &getMainJITDylib() { return MainJD; }123 124 Error addModule(ThreadSafeModule TSM, ResourceTrackerSP RT = nullptr) {125 if (!RT)126 RT = MainJD.getDefaultResourceTracker();127 128 return CODLayer.add(RT, std::move(TSM));129 }130 131 Expected<ExecutorSymbolDef> lookup(StringRef Name) {132 return ES->lookup({&MainJD}, Mangle(Name.str()));133 }134 135private:136 static Expected<ThreadSafeModule>137 optimizeModule(ThreadSafeModule TSM, const MaterializationResponsibility &R) {138 TSM.withModuleDo([](Module &M) {139 // Create a function pass manager.140 auto FPM = std::make_unique<legacy::FunctionPassManager>(&M);141 142 // Add some optimizations.143 FPM->add(createInstructionCombiningPass());144 FPM->add(createReassociatePass());145 FPM->add(createGVNPass());146 FPM->add(createCFGSimplificationPass());147 FPM->doInitialization();148 149 // Run the optimizations over all functions in the module being added to150 // the JIT.151 for (auto &F : M)152 FPM->run(F);153 });154 155 return std::move(TSM);156 }157};158 159} // end namespace orc160} // end namespace llvm161 162#endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H163