1 //===--- IncrementalExecutor.cpp - Incremental Execution --------*- 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the class which performs incremental code execution. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "IncrementalExecutor.h" 14 15 #include "clang/Interpreter/PartialTranslationUnit.h" 16 #include "llvm/ExecutionEngine/ExecutionEngine.h" 17 #include "llvm/ExecutionEngine/Orc/CompileUtils.h" 18 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 19 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" 20 #include "llvm/ExecutionEngine/Orc/LLJIT.h" 21 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" 22 #include "llvm/ExecutionEngine/SectionMemoryManager.h" 23 #include "llvm/IR/Module.h" 24 #include "llvm/Support/ManagedStatic.h" 25 #include "llvm/Support/TargetSelect.h" 26 27 namespace clang { 28 29 IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC, 30 llvm::Error &Err, 31 const llvm::Triple &Triple) 32 : TSCtx(TSC) { 33 using namespace llvm::orc; 34 llvm::ErrorAsOutParameter EAO(&Err); 35 36 auto JTMB = JITTargetMachineBuilder(Triple); 37 if (auto JitOrErr = LLJITBuilder().setJITTargetMachineBuilder(JTMB).create()) 38 Jit = std::move(*JitOrErr); 39 else { 40 Err = JitOrErr.takeError(); 41 return; 42 } 43 44 const char Pref = Jit->getDataLayout().getGlobalPrefix(); 45 // Discover symbols from the process as a fallback. 46 if (auto PSGOrErr = DynamicLibrarySearchGenerator::GetForCurrentProcess(Pref)) 47 Jit->getMainJITDylib().addGenerator(std::move(*PSGOrErr)); 48 else { 49 Err = PSGOrErr.takeError(); 50 return; 51 } 52 } 53 54 IncrementalExecutor::~IncrementalExecutor() {} 55 56 llvm::Error IncrementalExecutor::addModule(PartialTranslationUnit &PTU) { 57 llvm::orc::ResourceTrackerSP RT = 58 Jit->getMainJITDylib().createResourceTracker(); 59 ResourceTrackers[&PTU] = RT; 60 61 return Jit->addIRModule(RT, {std::move(PTU.TheModule), TSCtx}); 62 } 63 64 llvm::Error IncrementalExecutor::removeModule(PartialTranslationUnit &PTU) { 65 66 llvm::orc::ResourceTrackerSP RT = std::move(ResourceTrackers[&PTU]); 67 if (!RT) 68 return llvm::Error::success(); 69 70 ResourceTrackers.erase(&PTU); 71 if (llvm::Error Err = RT->remove()) 72 return Err; 73 return llvm::Error::success(); 74 } 75 76 llvm::Error IncrementalExecutor::runCtors() const { 77 return Jit->initialize(Jit->getMainJITDylib()); 78 } 79 80 llvm::Expected<llvm::JITTargetAddress> 81 IncrementalExecutor::getSymbolAddress(llvm::StringRef Name, 82 SymbolNameKind NameKind) const { 83 auto Sym = (NameKind == LinkerName) ? Jit->lookupLinkerMangled(Name) 84 : Jit->lookup(Name); 85 86 if (!Sym) 87 return Sym.takeError(); 88 return Sym->getValue(); 89 } 90 91 } // end namespace clang 92