1fe6060f1SDimitry Andric //===--- IncrementalExecutor.cpp - Incremental Execution --------*- C++ -*-===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric // 9fe6060f1SDimitry Andric // This file implements the class which performs incremental code execution. 10fe6060f1SDimitry Andric // 11fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 12fe6060f1SDimitry Andric 13fe6060f1SDimitry Andric #include "IncrementalExecutor.h" 14fe6060f1SDimitry Andric 1581ad6265SDimitry Andric #include "clang/Basic/TargetInfo.h" 1681ad6265SDimitry Andric #include "clang/Basic/TargetOptions.h" 1781ad6265SDimitry Andric #include "clang/Interpreter/PartialTranslationUnit.h" 18fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/ExecutionEngine.h" 19fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/CompileUtils.h" 205f757f3fSDimitry Andric #include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h" 21fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 22fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" 23*0fca6ea1SDimitry Andric #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" 24fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/LLJIT.h" 25fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" 2606c3fb27SDimitry Andric #include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h" 27fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/SectionMemoryManager.h" 28fe6060f1SDimitry Andric #include "llvm/IR/Module.h" 29fe6060f1SDimitry Andric #include "llvm/Support/ManagedStatic.h" 30fe6060f1SDimitry Andric #include "llvm/Support/TargetSelect.h" 31fe6060f1SDimitry Andric 3206c3fb27SDimitry Andric // Force linking some of the runtimes that helps attaching to a debugger. 3306c3fb27SDimitry Andric LLVM_ATTRIBUTE_USED void linkComponents() { 3406c3fb27SDimitry Andric llvm::errs() << (void *)&llvm_orc_registerJITLoaderGDBWrapper 3506c3fb27SDimitry Andric << (void *)&llvm_orc_registerJITLoaderGDBAllocAction; 3606c3fb27SDimitry Andric } 3706c3fb27SDimitry Andric 38fe6060f1SDimitry Andric namespace clang { 39*0fca6ea1SDimitry Andric IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC) 40*0fca6ea1SDimitry Andric : TSCtx(TSC) {} 41*0fca6ea1SDimitry Andric 42*0fca6ea1SDimitry Andric llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>> 43*0fca6ea1SDimitry Andric IncrementalExecutor::createDefaultJITBuilder( 44*0fca6ea1SDimitry Andric llvm::orc::JITTargetMachineBuilder JTMB) { 45*0fca6ea1SDimitry Andric auto JITBuilder = std::make_unique<llvm::orc::LLJITBuilder>(); 46*0fca6ea1SDimitry Andric JITBuilder->setJITTargetMachineBuilder(std::move(JTMB)); 47*0fca6ea1SDimitry Andric JITBuilder->setPrePlatformSetup([](llvm::orc::LLJIT &J) { 48*0fca6ea1SDimitry Andric // Try to enable debugging of JIT'd code (only works with JITLink for 49*0fca6ea1SDimitry Andric // ELF and MachO). 50*0fca6ea1SDimitry Andric consumeError(llvm::orc::enableDebuggerSupport(J)); 51*0fca6ea1SDimitry Andric return llvm::Error::success(); 52*0fca6ea1SDimitry Andric }); 53*0fca6ea1SDimitry Andric return std::move(JITBuilder); 54*0fca6ea1SDimitry Andric } 55fe6060f1SDimitry Andric 56fe6060f1SDimitry Andric IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC, 57*0fca6ea1SDimitry Andric llvm::orc::LLJITBuilder &JITBuilder, 58*0fca6ea1SDimitry Andric llvm::Error &Err) 59fe6060f1SDimitry Andric : TSCtx(TSC) { 60fe6060f1SDimitry Andric using namespace llvm::orc; 61fe6060f1SDimitry Andric llvm::ErrorAsOutParameter EAO(&Err); 62fe6060f1SDimitry Andric 63*0fca6ea1SDimitry Andric if (auto JitOrErr = JITBuilder.create()) 64fe6060f1SDimitry Andric Jit = std::move(*JitOrErr); 65fe6060f1SDimitry Andric else { 66fe6060f1SDimitry Andric Err = JitOrErr.takeError(); 67fe6060f1SDimitry Andric return; 68fe6060f1SDimitry Andric } 69fe6060f1SDimitry Andric } 70fe6060f1SDimitry Andric 71fe6060f1SDimitry Andric IncrementalExecutor::~IncrementalExecutor() {} 72fe6060f1SDimitry Andric 7381ad6265SDimitry Andric llvm::Error IncrementalExecutor::addModule(PartialTranslationUnit &PTU) { 7481ad6265SDimitry Andric llvm::orc::ResourceTrackerSP RT = 7581ad6265SDimitry Andric Jit->getMainJITDylib().createResourceTracker(); 7681ad6265SDimitry Andric ResourceTrackers[&PTU] = RT; 7781ad6265SDimitry Andric 7881ad6265SDimitry Andric return Jit->addIRModule(RT, {std::move(PTU.TheModule), TSCtx}); 7981ad6265SDimitry Andric } 8081ad6265SDimitry Andric 8181ad6265SDimitry Andric llvm::Error IncrementalExecutor::removeModule(PartialTranslationUnit &PTU) { 8281ad6265SDimitry Andric 8381ad6265SDimitry Andric llvm::orc::ResourceTrackerSP RT = std::move(ResourceTrackers[&PTU]); 8481ad6265SDimitry Andric if (!RT) 8581ad6265SDimitry Andric return llvm::Error::success(); 8681ad6265SDimitry Andric 8781ad6265SDimitry Andric ResourceTrackers.erase(&PTU); 8881ad6265SDimitry Andric if (llvm::Error Err = RT->remove()) 8981ad6265SDimitry Andric return Err; 9081ad6265SDimitry Andric return llvm::Error::success(); 91fe6060f1SDimitry Andric } 92fe6060f1SDimitry Andric 93bdd1243dSDimitry Andric // Clean up the JIT instance. 94bdd1243dSDimitry Andric llvm::Error IncrementalExecutor::cleanUp() { 95bdd1243dSDimitry Andric // This calls the global dtors of registered modules. 96bdd1243dSDimitry Andric return Jit->deinitialize(Jit->getMainJITDylib()); 97bdd1243dSDimitry Andric } 98bdd1243dSDimitry Andric 99fe6060f1SDimitry Andric llvm::Error IncrementalExecutor::runCtors() const { 100fe6060f1SDimitry Andric return Jit->initialize(Jit->getMainJITDylib()); 101fe6060f1SDimitry Andric } 102fe6060f1SDimitry Andric 10306c3fb27SDimitry Andric llvm::Expected<llvm::orc::ExecutorAddr> 104349cc55cSDimitry Andric IncrementalExecutor::getSymbolAddress(llvm::StringRef Name, 105349cc55cSDimitry Andric SymbolNameKind NameKind) const { 1068a4dda33SDimitry Andric using namespace llvm::orc; 1078a4dda33SDimitry Andric auto SO = makeJITDylibSearchOrder({&Jit->getMainJITDylib(), 1088a4dda33SDimitry Andric Jit->getPlatformJITDylib().get(), 1098a4dda33SDimitry Andric Jit->getProcessSymbolsJITDylib().get()}); 110349cc55cSDimitry Andric 1118a4dda33SDimitry Andric ExecutionSession &ES = Jit->getExecutionSession(); 1128a4dda33SDimitry Andric 1138a4dda33SDimitry Andric auto SymOrErr = 1148a4dda33SDimitry Andric ES.lookup(SO, (NameKind == LinkerName) ? ES.intern(Name) 1158a4dda33SDimitry Andric : Jit->mangleAndIntern(Name)); 1168a4dda33SDimitry Andric if (auto Err = SymOrErr.takeError()) 1178a4dda33SDimitry Andric return std::move(Err); 1188a4dda33SDimitry Andric return SymOrErr->getAddress(); 119349cc55cSDimitry Andric } 120349cc55cSDimitry Andric 121fe6060f1SDimitry Andric } // end namespace clang 122