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