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/SectionMemoryManager.h"
25 #include "llvm/IR/Module.h"
26 #include "llvm/Support/ManagedStatic.h"
27 #include "llvm/Support/TargetSelect.h"
31 IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext
&TSC
,
33 const clang::TargetInfo
&TI
)
35 using namespace llvm::orc
;
36 llvm::ErrorAsOutParameter
EAO(&Err
);
38 auto JTMB
= JITTargetMachineBuilder(TI
.getTriple());
39 JTMB
.addFeatures(TI
.getTargetOpts().Features
);
40 if (auto JitOrErr
= LLJITBuilder().setJITTargetMachineBuilder(JTMB
).create())
41 Jit
= std::move(*JitOrErr
);
43 Err
= JitOrErr
.takeError();
47 const char Pref
= Jit
->getDataLayout().getGlobalPrefix();
48 // Discover symbols from the process as a fallback.
49 if (auto PSGOrErr
= DynamicLibrarySearchGenerator::GetForCurrentProcess(Pref
))
50 Jit
->getMainJITDylib().addGenerator(std::move(*PSGOrErr
));
52 Err
= PSGOrErr
.takeError();
57 IncrementalExecutor::~IncrementalExecutor() {}
59 llvm::Error
IncrementalExecutor::addModule(PartialTranslationUnit
&PTU
) {
60 llvm::orc::ResourceTrackerSP RT
=
61 Jit
->getMainJITDylib().createResourceTracker();
62 ResourceTrackers
[&PTU
] = RT
;
64 return Jit
->addIRModule(RT
, {std::move(PTU
.TheModule
), TSCtx
});
67 llvm::Error
IncrementalExecutor::removeModule(PartialTranslationUnit
&PTU
) {
69 llvm::orc::ResourceTrackerSP RT
= std::move(ResourceTrackers
[&PTU
]);
71 return llvm::Error::success();
73 ResourceTrackers
.erase(&PTU
);
74 if (llvm::Error Err
= RT
->remove())
76 return llvm::Error::success();
79 // Clean up the JIT instance.
80 llvm::Error
IncrementalExecutor::cleanUp() {
81 // This calls the global dtors of registered modules.
82 return Jit
->deinitialize(Jit
->getMainJITDylib());
85 llvm::Error
IncrementalExecutor::runCtors() const {
86 return Jit
->initialize(Jit
->getMainJITDylib());
89 llvm::Expected
<llvm::JITTargetAddress
>
90 IncrementalExecutor::getSymbolAddress(llvm::StringRef Name
,
91 SymbolNameKind NameKind
) const {
92 auto Sym
= (NameKind
== LinkerName
) ? Jit
->lookupLinkerMangled(Name
)
96 return Sym
.takeError();
97 return Sym
->getValue();
100 } // end namespace clang