1 //===--- IncrementalExecutor.cpp - Incremental Execution --------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements the class which performs incremental code execution.
11 //===----------------------------------------------------------------------===//
13 #include "IncrementalExecutor.h"
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/Orc/TargetProcess/JITLoaderGDB.h"
25 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
26 #include "llvm/IR/Module.h"
27 #include "llvm/Support/ManagedStatic.h"
28 #include "llvm/Support/TargetSelect.h"
30 // Force linking some of the runtimes that helps attaching to a debugger.
31 LLVM_ATTRIBUTE_USED
void linkComponents() {
32 llvm::errs() << (void *)&llvm_orc_registerJITLoaderGDBWrapper
33 << (void *)&llvm_orc_registerJITLoaderGDBAllocAction
;
38 IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext
&TSC
,
40 const clang::TargetInfo
&TI
)
42 using namespace llvm::orc
;
43 llvm::ErrorAsOutParameter
EAO(&Err
);
45 auto JTMB
= JITTargetMachineBuilder(TI
.getTriple());
46 JTMB
.addFeatures(TI
.getTargetOpts().Features
);
48 Builder
.setJITTargetMachineBuilder(JTMB
);
49 // Enable debugging of JIT'd code (only works on JITLink for ELF and MachO).
50 Builder
.setEnableDebuggerSupport(true);
52 if (auto JitOrErr
= Builder
.create())
53 Jit
= std::move(*JitOrErr
);
55 Err
= JitOrErr
.takeError();
60 IncrementalExecutor::~IncrementalExecutor() {}
62 llvm::Error
IncrementalExecutor::addModule(PartialTranslationUnit
&PTU
) {
63 llvm::orc::ResourceTrackerSP RT
=
64 Jit
->getMainJITDylib().createResourceTracker();
65 ResourceTrackers
[&PTU
] = RT
;
67 return Jit
->addIRModule(RT
, {std::move(PTU
.TheModule
), TSCtx
});
70 llvm::Error
IncrementalExecutor::removeModule(PartialTranslationUnit
&PTU
) {
72 llvm::orc::ResourceTrackerSP RT
= std::move(ResourceTrackers
[&PTU
]);
74 return llvm::Error::success();
76 ResourceTrackers
.erase(&PTU
);
77 if (llvm::Error Err
= RT
->remove())
79 return llvm::Error::success();
82 // Clean up the JIT instance.
83 llvm::Error
IncrementalExecutor::cleanUp() {
84 // This calls the global dtors of registered modules.
85 return Jit
->deinitialize(Jit
->getMainJITDylib());
88 llvm::Error
IncrementalExecutor::runCtors() const {
89 return Jit
->initialize(Jit
->getMainJITDylib());
92 llvm::Expected
<llvm::orc::ExecutorAddr
>
93 IncrementalExecutor::getSymbolAddress(llvm::StringRef Name
,
94 SymbolNameKind NameKind
) const {
95 auto Sym
= (NameKind
== LinkerName
) ? Jit
->lookupLinkerMangled(Name
)
99 return Sym
.takeError();
103 } // end namespace clang