xref: /llvm-project/clang/lib/Interpreter/IncrementalExecutor.cpp (revision a72d7eea5413444249670579fecea6823fb3c564)
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