1a9ac8606Spatrick //===--- IncrementalExecutor.cpp - Incremental Execution --------*- C++ -*-===// 2a9ac8606Spatrick // 3a9ac8606Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a9ac8606Spatrick // See https://llvm.org/LICENSE.txt for license information. 5a9ac8606Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a9ac8606Spatrick // 7a9ac8606Spatrick //===----------------------------------------------------------------------===// 8a9ac8606Spatrick // 9a9ac8606Spatrick // This file implements the class which performs incremental code execution. 10a9ac8606Spatrick // 11a9ac8606Spatrick //===----------------------------------------------------------------------===// 12a9ac8606Spatrick 13a9ac8606Spatrick #include "IncrementalExecutor.h" 14a9ac8606Spatrick 15*12c85518Srobert #include "clang/Basic/TargetInfo.h" 16*12c85518Srobert #include "clang/Basic/TargetOptions.h" 17*12c85518Srobert #include "clang/Interpreter/PartialTranslationUnit.h" 18a9ac8606Spatrick #include "llvm/ExecutionEngine/ExecutionEngine.h" 19a9ac8606Spatrick #include "llvm/ExecutionEngine/Orc/CompileUtils.h" 20a9ac8606Spatrick #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 21a9ac8606Spatrick #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" 22a9ac8606Spatrick #include "llvm/ExecutionEngine/Orc/LLJIT.h" 23a9ac8606Spatrick #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" 24a9ac8606Spatrick #include "llvm/ExecutionEngine/SectionMemoryManager.h" 25a9ac8606Spatrick #include "llvm/IR/Module.h" 26a9ac8606Spatrick #include "llvm/Support/ManagedStatic.h" 27a9ac8606Spatrick #include "llvm/Support/TargetSelect.h" 28a9ac8606Spatrick 29a9ac8606Spatrick namespace clang { 30a9ac8606Spatrick IncrementalExecutor(llvm::orc::ThreadSafeContext & TSC,llvm::Error & Err,const clang::TargetInfo & TI)31a9ac8606SpatrickIncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC, 32a9ac8606Spatrick llvm::Error &Err, 33*12c85518Srobert const clang::TargetInfo &TI) 34a9ac8606Spatrick : TSCtx(TSC) { 35a9ac8606Spatrick using namespace llvm::orc; 36a9ac8606Spatrick llvm::ErrorAsOutParameter EAO(&Err); 37a9ac8606Spatrick 38*12c85518Srobert auto JTMB = JITTargetMachineBuilder(TI.getTriple()); 39*12c85518Srobert JTMB.addFeatures(TI.getTargetOpts().Features); 40a9ac8606Spatrick if (auto JitOrErr = LLJITBuilder().setJITTargetMachineBuilder(JTMB).create()) 41a9ac8606Spatrick Jit = std::move(*JitOrErr); 42a9ac8606Spatrick else { 43a9ac8606Spatrick Err = JitOrErr.takeError(); 44a9ac8606Spatrick return; 45a9ac8606Spatrick } 46a9ac8606Spatrick 47a9ac8606Spatrick const char Pref = Jit->getDataLayout().getGlobalPrefix(); 48a9ac8606Spatrick // Discover symbols from the process as a fallback. 49a9ac8606Spatrick if (auto PSGOrErr = DynamicLibrarySearchGenerator::GetForCurrentProcess(Pref)) 50a9ac8606Spatrick Jit->getMainJITDylib().addGenerator(std::move(*PSGOrErr)); 51a9ac8606Spatrick else { 52a9ac8606Spatrick Err = PSGOrErr.takeError(); 53a9ac8606Spatrick return; 54a9ac8606Spatrick } 55a9ac8606Spatrick } 56a9ac8606Spatrick ~IncrementalExecutor()57a9ac8606SpatrickIncrementalExecutor::~IncrementalExecutor() {} 58a9ac8606Spatrick addModule(PartialTranslationUnit & PTU)59*12c85518Srobertllvm::Error IncrementalExecutor::addModule(PartialTranslationUnit &PTU) { 60*12c85518Srobert llvm::orc::ResourceTrackerSP RT = 61*12c85518Srobert Jit->getMainJITDylib().createResourceTracker(); 62*12c85518Srobert ResourceTrackers[&PTU] = RT; 63*12c85518Srobert 64*12c85518Srobert return Jit->addIRModule(RT, {std::move(PTU.TheModule), TSCtx}); 65*12c85518Srobert } 66*12c85518Srobert removeModule(PartialTranslationUnit & PTU)67*12c85518Srobertllvm::Error IncrementalExecutor::removeModule(PartialTranslationUnit &PTU) { 68*12c85518Srobert 69*12c85518Srobert llvm::orc::ResourceTrackerSP RT = std::move(ResourceTrackers[&PTU]); 70*12c85518Srobert if (!RT) 71*12c85518Srobert return llvm::Error::success(); 72*12c85518Srobert 73*12c85518Srobert ResourceTrackers.erase(&PTU); 74*12c85518Srobert if (llvm::Error Err = RT->remove()) 75*12c85518Srobert return Err; 76*12c85518Srobert return llvm::Error::success(); 77*12c85518Srobert } 78*12c85518Srobert 79*12c85518Srobert // Clean up the JIT instance. cleanUp()80*12c85518Srobertllvm::Error IncrementalExecutor::cleanUp() { 81*12c85518Srobert // This calls the global dtors of registered modules. 82*12c85518Srobert return Jit->deinitialize(Jit->getMainJITDylib()); 83a9ac8606Spatrick } 84a9ac8606Spatrick runCtors() const85a9ac8606Spatrickllvm::Error IncrementalExecutor::runCtors() const { 86a9ac8606Spatrick return Jit->initialize(Jit->getMainJITDylib()); 87a9ac8606Spatrick } 88a9ac8606Spatrick 89*12c85518Srobert llvm::Expected<llvm::JITTargetAddress> getSymbolAddress(llvm::StringRef Name,SymbolNameKind NameKind) const90*12c85518SrobertIncrementalExecutor::getSymbolAddress(llvm::StringRef Name, 91*12c85518Srobert SymbolNameKind NameKind) const { 92*12c85518Srobert auto Sym = (NameKind == LinkerName) ? Jit->lookupLinkerMangled(Name) 93*12c85518Srobert : Jit->lookup(Name); 94*12c85518Srobert 95*12c85518Srobert if (!Sym) 96*12c85518Srobert return Sym.takeError(); 97*12c85518Srobert return Sym->getValue(); 98*12c85518Srobert } 99*12c85518Srobert 100a9ac8606Spatrick } // end namespace clang 101