192f9852fSVassil Vassilev //===--- IncrementalExecutor.cpp - Incremental Execution --------*- C++ -*-===// 292f9852fSVassil Vassilev // 392f9852fSVassil Vassilev // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 492f9852fSVassil Vassilev // See https://llvm.org/LICENSE.txt for license information. 592f9852fSVassil Vassilev // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 692f9852fSVassil Vassilev // 792f9852fSVassil Vassilev //===----------------------------------------------------------------------===// 892f9852fSVassil Vassilev // 992f9852fSVassil Vassilev // This file implements the class which performs incremental code execution. 1092f9852fSVassil Vassilev // 1192f9852fSVassil Vassilev //===----------------------------------------------------------------------===// 1292f9852fSVassil Vassilev 1392f9852fSVassil Vassilev #include "IncrementalExecutor.h" 1492f9852fSVassil Vassilev 15f22795deSJonas Hahnfeld #include "clang/Basic/TargetInfo.h" 16f22795deSJonas Hahnfeld #include "clang/Basic/TargetOptions.h" 17dea5a9ccSJun Zhang #include "clang/Interpreter/PartialTranslationUnit.h" 1892f9852fSVassil Vassilev #include "llvm/ExecutionEngine/ExecutionEngine.h" 1992f9852fSVassil Vassilev #include "llvm/ExecutionEngine/Orc/CompileUtils.h" 20b2518971SLang Hames #include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h" 2192f9852fSVassil Vassilev #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 2292f9852fSVassil Vassilev #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" 230cf4788dSStefan Gränitz #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" 2492f9852fSVassil Vassilev #include "llvm/ExecutionEngine/Orc/LLJIT.h" 2592f9852fSVassil Vassilev #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" 26310ee08dSVassil Vassilev #include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h" 2792f9852fSVassil Vassilev #include "llvm/ExecutionEngine/SectionMemoryManager.h" 2892f9852fSVassil Vassilev #include "llvm/IR/Module.h" 2992f9852fSVassil Vassilev #include "llvm/Support/ManagedStatic.h" 3092f9852fSVassil Vassilev #include "llvm/Support/TargetSelect.h" 3192f9852fSVassil Vassilev 32310ee08dSVassil Vassilev // Force linking some of the runtimes that helps attaching to a debugger. 33310ee08dSVassil Vassilev LLVM_ATTRIBUTE_USED void linkComponents() { 34310ee08dSVassil Vassilev llvm::errs() << (void *)&llvm_orc_registerJITLoaderGDBWrapper 35310ee08dSVassil Vassilev << (void *)&llvm_orc_registerJITLoaderGDBAllocAction; 36310ee08dSVassil Vassilev } 37310ee08dSVassil Vassilev 3892f9852fSVassil Vassilev namespace clang { 399a9546e3SVassil Vassilev IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC) 409a9546e3SVassil Vassilev : TSCtx(TSC) {} 4192f9852fSVassil Vassilev 420cf4788dSStefan Gränitz llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>> 430cf4788dSStefan Gränitz IncrementalExecutor::createDefaultJITBuilder( 440cf4788dSStefan Gränitz llvm::orc::JITTargetMachineBuilder JTMB) { 450cf4788dSStefan Gränitz auto JITBuilder = std::make_unique<llvm::orc::LLJITBuilder>(); 460cf4788dSStefan Gränitz JITBuilder->setJITTargetMachineBuilder(std::move(JTMB)); 470cf4788dSStefan Gränitz JITBuilder->setPrePlatformSetup([](llvm::orc::LLJIT &J) { 480cf4788dSStefan Gränitz // Try to enable debugging of JIT'd code (only works with JITLink for 490cf4788dSStefan Gränitz // ELF and MachO). 500cf4788dSStefan Gränitz consumeError(llvm::orc::enableDebuggerSupport(J)); 510cf4788dSStefan Gränitz return llvm::Error::success(); 520cf4788dSStefan Gränitz }); 530cf4788dSStefan Gränitz return std::move(JITBuilder); 540cf4788dSStefan Gränitz } 550cf4788dSStefan Gränitz 5692f9852fSVassil Vassilev IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC, 570cf4788dSStefan Gränitz llvm::orc::LLJITBuilder &JITBuilder, 580cf4788dSStefan Gränitz llvm::Error &Err) 5992f9852fSVassil Vassilev : TSCtx(TSC) { 6092f9852fSVassil Vassilev using namespace llvm::orc; 6192f9852fSVassil Vassilev llvm::ErrorAsOutParameter EAO(&Err); 6292f9852fSVassil Vassilev 630cf4788dSStefan Gränitz if (auto JitOrErr = JITBuilder.create()) 6492f9852fSVassil Vassilev Jit = std::move(*JitOrErr); 6592f9852fSVassil Vassilev else { 6692f9852fSVassil Vassilev Err = JitOrErr.takeError(); 6792f9852fSVassil Vassilev return; 6892f9852fSVassil Vassilev } 6992f9852fSVassil Vassilev } 7092f9852fSVassil Vassilev 7192f9852fSVassil Vassilev IncrementalExecutor::~IncrementalExecutor() {} 7292f9852fSVassil Vassilev 73dea5a9ccSJun Zhang llvm::Error IncrementalExecutor::addModule(PartialTranslationUnit &PTU) { 74dea5a9ccSJun Zhang llvm::orc::ResourceTrackerSP RT = 75dea5a9ccSJun Zhang Jit->getMainJITDylib().createResourceTracker(); 76dea5a9ccSJun Zhang ResourceTrackers[&PTU] = RT; 77dea5a9ccSJun Zhang 78dea5a9ccSJun Zhang return Jit->addIRModule(RT, {std::move(PTU.TheModule), TSCtx}); 79dea5a9ccSJun Zhang } 80dea5a9ccSJun Zhang 81dea5a9ccSJun Zhang llvm::Error IncrementalExecutor::removeModule(PartialTranslationUnit &PTU) { 82dea5a9ccSJun Zhang 83dea5a9ccSJun Zhang llvm::orc::ResourceTrackerSP RT = std::move(ResourceTrackers[&PTU]); 84dea5a9ccSJun Zhang if (!RT) 85dea5a9ccSJun Zhang return llvm::Error::success(); 86dea5a9ccSJun Zhang 87dea5a9ccSJun Zhang ResourceTrackers.erase(&PTU); 88dea5a9ccSJun Zhang if (llvm::Error Err = RT->remove()) 89dea5a9ccSJun Zhang return Err; 90dea5a9ccSJun Zhang return llvm::Error::success(); 9192f9852fSVassil Vassilev } 9292f9852fSVassil Vassilev 93c619d4f8SSunho Kim // Clean up the JIT instance. 94c619d4f8SSunho Kim llvm::Error IncrementalExecutor::cleanUp() { 95c619d4f8SSunho Kim // This calls the global dtors of registered modules. 96c619d4f8SSunho Kim return Jit->deinitialize(Jit->getMainJITDylib()); 97c619d4f8SSunho Kim } 98c619d4f8SSunho Kim 9992f9852fSVassil Vassilev llvm::Error IncrementalExecutor::runCtors() const { 10092f9852fSVassil Vassilev return Jit->initialize(Jit->getMainJITDylib()); 10192f9852fSVassil Vassilev } 10292f9852fSVassil Vassilev 103fe1f3445SJun Zhang llvm::Expected<llvm::orc::ExecutorAddr> 1044fb0805cSVassil Vassilev IncrementalExecutor::getSymbolAddress(llvm::StringRef Name, 1054fb0805cSVassil Vassilev SymbolNameKind NameKind) const { 106452cb7f2SVassil Vassilev using namespace llvm::orc; 107452cb7f2SVassil Vassilev auto SO = makeJITDylibSearchOrder({&Jit->getMainJITDylib(), 108452cb7f2SVassil Vassilev Jit->getPlatformJITDylib().get(), 109452cb7f2SVassil Vassilev Jit->getProcessSymbolsJITDylib().get()}); 1104fb0805cSVassil Vassilev 111452cb7f2SVassil Vassilev ExecutionSession &ES = Jit->getExecutionSession(); 112452cb7f2SVassil Vassilev 113452cb7f2SVassil Vassilev auto SymOrErr = 114452cb7f2SVassil Vassilev ES.lookup(SO, (NameKind == LinkerName) ? ES.intern(Name) 115452cb7f2SVassil Vassilev : Jit->mangleAndIntern(Name)); 116452cb7f2SVassil Vassilev if (auto Err = SymOrErr.takeError()) 117452cb7f2SVassil Vassilev return std::move(Err); 118452cb7f2SVassil Vassilev return SymOrErr->getAddress(); 119c24a5808SVassil Vassilev } 120c24a5808SVassil Vassilev 121*a72d7eeaSVassil Vassilev } // namespace clang 122