xref: /freebsd-src/contrib/llvm-project/clang/lib/Interpreter/IncrementalExecutor.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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"
20fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
21fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
22fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/LLJIT.h"
23fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
24*06c3fb27SDimitry Andric #include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
25fe6060f1SDimitry Andric #include "llvm/ExecutionEngine/SectionMemoryManager.h"
26fe6060f1SDimitry Andric #include "llvm/IR/Module.h"
27fe6060f1SDimitry Andric #include "llvm/Support/ManagedStatic.h"
28fe6060f1SDimitry Andric #include "llvm/Support/TargetSelect.h"
29fe6060f1SDimitry Andric 
30*06c3fb27SDimitry Andric // Force linking some of the runtimes that helps attaching to a debugger.
31*06c3fb27SDimitry Andric LLVM_ATTRIBUTE_USED void linkComponents() {
32*06c3fb27SDimitry Andric   llvm::errs() << (void *)&llvm_orc_registerJITLoaderGDBWrapper
33*06c3fb27SDimitry Andric                << (void *)&llvm_orc_registerJITLoaderGDBAllocAction;
34*06c3fb27SDimitry Andric }
35*06c3fb27SDimitry Andric 
36fe6060f1SDimitry Andric namespace clang {
37fe6060f1SDimitry Andric 
38fe6060f1SDimitry Andric IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC,
39fe6060f1SDimitry Andric                                          llvm::Error &Err,
4081ad6265SDimitry Andric                                          const clang::TargetInfo &TI)
41fe6060f1SDimitry Andric     : TSCtx(TSC) {
42fe6060f1SDimitry Andric   using namespace llvm::orc;
43fe6060f1SDimitry Andric   llvm::ErrorAsOutParameter EAO(&Err);
44fe6060f1SDimitry Andric 
4581ad6265SDimitry Andric   auto JTMB = JITTargetMachineBuilder(TI.getTriple());
4681ad6265SDimitry Andric   JTMB.addFeatures(TI.getTargetOpts().Features);
47*06c3fb27SDimitry Andric   LLJITBuilder Builder;
48*06c3fb27SDimitry Andric   Builder.setJITTargetMachineBuilder(JTMB);
49*06c3fb27SDimitry Andric   // Enable debugging of JIT'd code (only works on JITLink for ELF and MachO).
50*06c3fb27SDimitry Andric   Builder.setEnableDebuggerSupport(true);
51*06c3fb27SDimitry Andric 
52*06c3fb27SDimitry Andric   if (auto JitOrErr = Builder.create())
53fe6060f1SDimitry Andric     Jit = std::move(*JitOrErr);
54fe6060f1SDimitry Andric   else {
55fe6060f1SDimitry Andric     Err = JitOrErr.takeError();
56fe6060f1SDimitry Andric     return;
57fe6060f1SDimitry Andric   }
58fe6060f1SDimitry Andric }
59fe6060f1SDimitry Andric 
60fe6060f1SDimitry Andric IncrementalExecutor::~IncrementalExecutor() {}
61fe6060f1SDimitry Andric 
6281ad6265SDimitry Andric llvm::Error IncrementalExecutor::addModule(PartialTranslationUnit &PTU) {
6381ad6265SDimitry Andric   llvm::orc::ResourceTrackerSP RT =
6481ad6265SDimitry Andric       Jit->getMainJITDylib().createResourceTracker();
6581ad6265SDimitry Andric   ResourceTrackers[&PTU] = RT;
6681ad6265SDimitry Andric 
6781ad6265SDimitry Andric   return Jit->addIRModule(RT, {std::move(PTU.TheModule), TSCtx});
6881ad6265SDimitry Andric }
6981ad6265SDimitry Andric 
7081ad6265SDimitry Andric llvm::Error IncrementalExecutor::removeModule(PartialTranslationUnit &PTU) {
7181ad6265SDimitry Andric 
7281ad6265SDimitry Andric   llvm::orc::ResourceTrackerSP RT = std::move(ResourceTrackers[&PTU]);
7381ad6265SDimitry Andric   if (!RT)
7481ad6265SDimitry Andric     return llvm::Error::success();
7581ad6265SDimitry Andric 
7681ad6265SDimitry Andric   ResourceTrackers.erase(&PTU);
7781ad6265SDimitry Andric   if (llvm::Error Err = RT->remove())
7881ad6265SDimitry Andric     return Err;
7981ad6265SDimitry Andric   return llvm::Error::success();
80fe6060f1SDimitry Andric }
81fe6060f1SDimitry Andric 
82bdd1243dSDimitry Andric // Clean up the JIT instance.
83bdd1243dSDimitry Andric llvm::Error IncrementalExecutor::cleanUp() {
84bdd1243dSDimitry Andric   // This calls the global dtors of registered modules.
85bdd1243dSDimitry Andric   return Jit->deinitialize(Jit->getMainJITDylib());
86bdd1243dSDimitry Andric }
87bdd1243dSDimitry Andric 
88fe6060f1SDimitry Andric llvm::Error IncrementalExecutor::runCtors() const {
89fe6060f1SDimitry Andric   return Jit->initialize(Jit->getMainJITDylib());
90fe6060f1SDimitry Andric }
91fe6060f1SDimitry Andric 
92*06c3fb27SDimitry Andric llvm::Expected<llvm::orc::ExecutorAddr>
93349cc55cSDimitry Andric IncrementalExecutor::getSymbolAddress(llvm::StringRef Name,
94349cc55cSDimitry Andric                                       SymbolNameKind NameKind) const {
95349cc55cSDimitry Andric   auto Sym = (NameKind == LinkerName) ? Jit->lookupLinkerMangled(Name)
96349cc55cSDimitry Andric                                       : Jit->lookup(Name);
97349cc55cSDimitry Andric 
98349cc55cSDimitry Andric   if (!Sym)
99349cc55cSDimitry Andric     return Sym.takeError();
100*06c3fb27SDimitry Andric   return Sym;
101349cc55cSDimitry Andric }
102349cc55cSDimitry Andric 
103fe6060f1SDimitry Andric } // end namespace clang
104