brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.4 KiB · 643c089 Raw
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