github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/jit/OrcLazyJIT.cpp (about)

     1  //===- OrcLazyJIT.cpp - Basic Orc-based JIT for lazy execution ------------===//
     2  //
     3  //                     The LLVM Compiler Infrastructure
     4  //
     5  // This file is distributed under the University of Illinois Open Source
     6  // License. See LICENSE.TXT for details.
     7  //
     8  //===----------------------------------------------------------------------===//
     9  
    10  #include "OrcLazyJIT.h"
    11  #include "jit/jit_exception.h"
    12  #include "llvm/ADT/Triple.h"
    13  #include "llvm/ExecutionEngine/ExecutionEngine.h"
    14  #include "llvm/Support/CodeGen.h"
    15  #include "llvm/Support/CommandLine.h"
    16  #include "llvm/Support/DynamicLibrary.h"
    17  #include "llvm/Support/ErrorHandling.h"
    18  #include "llvm/Support/FileSystem.h"
    19  #include <cstdint>
    20  #include <cstdio>
    21  #include <cstdlib>
    22  #include <iostream>
    23  #include <system_error>
    24  
    25  namespace {
    26  
    27  enum class DumpKind {
    28    NoDump,
    29    DumpFuncsToStdOut,
    30    DumpModsToStdOut,
    31    DumpModsToDisk
    32  };
    33  
    34  } // end anonymous namespace
    35  
    36  llvm::OrcLazyJIT::TransformFtor llvm::OrcLazyJIT::createDebugDumper() {
    37    DumpKind OrcDumpKind = DumpKind::NoDump;
    38    switch (OrcDumpKind) {
    39    case DumpKind::NoDump:
    40      return [](std::shared_ptr<Module> M) { return M; };
    41  
    42    case DumpKind::DumpFuncsToStdOut:
    43      return [](std::shared_ptr<Module> M) {
    44        std::cout << "[ " << std::endl;
    45  
    46        for (const auto &F : *M) {
    47          if (F.isDeclaration()) {
    48            continue;
    49          }
    50  
    51          if (F.hasName()) {
    52            std::string Name(F.getName());
    53            std::cout << Name << std::endl;
    54          } else {
    55            std::cout << "<anon> " << std::endl;
    56          }
    57        }
    58  
    59        std::cout << "]\n" << std::endl;
    60        return M;
    61      };
    62  
    63    case DumpKind::DumpModsToStdOut:
    64      return [](std::shared_ptr<Module> M) {
    65        outs() << "----- Module Start -----\n"
    66               << *M << "----- Module End -----\n";
    67  
    68        return M;
    69      };
    70  
    71    case DumpKind::DumpModsToDisk:
    72      return [](std::shared_ptr<Module> M) {
    73        std::error_code EC;
    74        raw_fd_ostream Out(M->getModuleIdentifier() + ".ll", EC, sys::fs::F_Text);
    75        if (EC) {
    76          errs() << "Couldn't open " << M->getModuleIdentifier()
    77                 << " for dumping.\nError:" << EC.message() << "\n";
    78          exit(1);
    79        }
    80        Out << *M;
    81        return M;
    82      };
    83    }
    84    llvm_unreachable("Unknown DumpKind");
    85  }
    86  
    87  llvm::Error llvm::OrcLazyJIT::addModule(std::shared_ptr<Module> M) {
    88    if (M->getDataLayout().isDefault())
    89      M->setDataLayout(DL);
    90  
    91    // Rename, bump linkage and record static constructors and destructors.
    92    // We have to do this before we hand over ownership of the module to the
    93    // JIT.
    94    std::vector<std::string> CtorNames, DtorNames;
    95    {
    96      unsigned CtorId = 0, DtorId = 0;
    97      for (auto Ctor : orc::getConstructors(*M)) {
    98        std::string NewCtorName = ("$static_ctor." + Twine(CtorId++)).str();
    99        Ctor.Func->setName(NewCtorName);
   100        Ctor.Func->setLinkage(GlobalValue::ExternalLinkage);
   101        Ctor.Func->setVisibility(GlobalValue::HiddenVisibility);
   102        CtorNames.push_back(mangle(NewCtorName));
   103      }
   104      for (auto Dtor : orc::getDestructors(*M)) {
   105        std::string NewDtorName = ("$static_dtor." + Twine(DtorId++)).str();
   106        Dtor.Func->setLinkage(GlobalValue::ExternalLinkage);
   107        Dtor.Func->setVisibility(GlobalValue::HiddenVisibility);
   108        DtorNames.push_back(mangle(Dtor.Func->getName()));
   109        Dtor.Func->setName(NewDtorName);
   110      }
   111    }
   112  
   113    // Symbol resolution order:
   114    //   1) Search the JIT symbols.
   115    //   2) Check for C++ runtime overrides.
   116    //   3) Search the host process (LLI)'s symbol table.
   117    if (!ModulesHandle) {
   118      auto Resolver = orc::createLambdaResolver(
   119          [this](const std::string &Name) -> JITSymbol {
   120            if (auto Sym = CODLayer.findSymbol(Name, true))
   121              return Sym;
   122            return CXXRuntimeOverrides.searchOverrides(Name);
   123          },
   124          [this](const std::string &Name) {
   125            if (auto Addr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
   126              return JITSymbol(Addr, JITSymbolFlags::Exported);
   127            return JITSymbol(nullptr);
   128          });
   129  
   130      // Add the module to the JIT.
   131      if (auto ModulesHandleOrErr =
   132              CODLayer.addModule(std::move(M), std::move(Resolver)))
   133        ModulesHandle = std::move(*ModulesHandleOrErr);
   134      else
   135        return ModulesHandleOrErr.takeError();
   136  
   137    } else if (auto Err = CODLayer.addExtraModule(*ModulesHandle, std::move(M)))
   138      return Err;
   139  
   140    // Run the static constructors, and save the static destructor runner for
   141    // execution when the JIT is torn down.
   142    orc::CtorDtorRunner<CODLayerT> CtorRunner(std::move(CtorNames),
   143                                              *ModulesHandle);
   144    if (auto Err = CtorRunner.runViaLayer(CODLayer))
   145      return Err;
   146  
   147    IRStaticDestructorRunners.emplace_back(std::move(DtorNames), *ModulesHandle);
   148  
   149    return Error::success();
   150  }
   151  
   152  // Defined in lli.cpp.
   153  // CodeGenOpt::Level getOptLevel();
   154  
   155