Skip to content

Commit 023cab5

Browse files
[clang-repl] Expose CreateExecutor() and ResetExecutor()
1 parent 10f8d3e commit 023cab5

File tree

4 files changed

+52
-1
lines changed

4 files changed

+52
-1
lines changed

clang/include/clang/Interpreter/Interpreter.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ class Interpreter {
9696
// An optional parser for CUDA offloading
9797
std::unique_ptr<IncrementalParser> DeviceParser;
9898

99-
llvm::Error CreateExecutor();
10099
unsigned InitPTUSize = 0;
101100

102101
// This member holds the last result of the value printing. It's a class
@@ -114,6 +113,14 @@ class Interpreter {
114113
// That's useful for testing and out-of-tree clients.
115114
Interpreter(std::unique_ptr<CompilerInstance> CI, llvm::Error &Err);
116115

116+
// Create the internal IncrementalExecutor, or re-create it after calling
117+
// ResetExecutor().
118+
llvm::Error CreateExecutor();
119+
120+
// Delete the internal IncrementalExecutor. This causes a hard shutdown of the
121+
// JIT engine. In particular, it doesn't run cleanup or destructors.
122+
void ResetExecutor();
123+
117124
// Lazily construct the RuntimeInterfaceBuilder. The provided instance will be
118125
// used for the entire lifetime of the interpreter. The default implementation
119126
// targets the in-process __clang_Interpreter runtime. Override this to use a

clang/lib/Interpreter/Interpreter.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,11 @@
3636
#include "clang/Lex/PreprocessorOptions.h"
3737
#include "clang/Sema/Lookup.h"
3838
#include "llvm/ExecutionEngine/JITSymbol.h"
39+
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
3940
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
4041
#include "llvm/IR/Module.h"
4142
#include "llvm/Support/Errc.h"
43+
#include "llvm/Support/Error.h"
4244
#include "llvm/Support/ErrorHandling.h"
4345
#include "llvm/Support/raw_ostream.h"
4446
#include "llvm/TargetParser/Host.h"
@@ -368,9 +370,22 @@ Interpreter::Parse(llvm::StringRef Code) {
368370
return IncrParser->Parse(Code);
369371
}
370372

373+
static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
374+
createJITTargetMachineBuilder(const std::string &TT) {
375+
if (TT == llvm::sys::getProcessTriple())
376+
return llvm::orc::JITTargetMachineBuilder::detectHost();
377+
// FIXME: This can fail as well if the target is not registered! We just don't
378+
// catch it yet.
379+
return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
380+
}
381+
371382
llvm::Error Interpreter::CreateExecutor() {
372383
const clang::TargetInfo &TI =
373384
getCompilerInstance()->getASTContext().getTargetInfo();
385+
if (IncrExecutor)
386+
return llvm::make_error<llvm::StringError>("Operation failed. "
387+
"Execution engine exists",
388+
std::error_code());
374389
llvm::Error Err = llvm::Error::success();
375390
auto Executor = std::make_unique<IncrementalExecutor>(*TSCtx, Err, TI);
376391
if (!Err)
@@ -379,6 +394,8 @@ llvm::Error Interpreter::CreateExecutor() {
379394
return Err;
380395
}
381396

397+
void Interpreter::ResetExecutor() { IncrExecutor.reset(); }
398+
382399
llvm::Error Interpreter::Execute(PartialTranslationUnit &T) {
383400
assert(T.TheModule);
384401
if (!IncrExecutor) {

clang/unittests/Interpreter/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
44
OrcJIT
55
Support
66
TargetParser
7+
TestingSupport
78
)
89

910
add_clang_unittest(ClangReplInterpreterTests

clang/unittests/Interpreter/InterpreterExtensionsTest.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,32 @@
2727
using namespace clang;
2828
namespace {
2929

30+
class TestCreateResetExecutor : public Interpreter {
31+
public:
32+
TestCreateResetExecutor(std::unique_ptr<CompilerInstance> CI,
33+
llvm::Error &Err)
34+
: Interpreter(std::move(CI), Err) {}
35+
36+
llvm::Error testCreateExecutor() {
37+
return Interpreter::CreateExecutor();
38+
}
39+
40+
void resetExecutor() { Interpreter::ResetExecutor(); }
41+
};
42+
43+
TEST(InterpreterExtensionsTest, ExecutorCreateReset) {
44+
clang::IncrementalCompilerBuilder CB;
45+
llvm::Error ErrOut = llvm::Error::success();
46+
TestCreateResetExecutor Interp(cantFail(CB.CreateCpp()), ErrOut);
47+
cantFail(std::move(ErrOut));
48+
cantFail(Interp.testCreateExecutor());
49+
Interp.resetExecutor();
50+
cantFail(Interp.testCreateExecutor());
51+
EXPECT_THAT_ERROR(Interp.testCreateExecutor(),
52+
llvm::FailedWithMessage("Operation failed. "
53+
"Execution engine exists"));
54+
}
55+
3056
class RecordRuntimeIBMetrics : public Interpreter {
3157
struct NoopRuntimeInterfaceBuilder : public RuntimeInterfaceBuilder {
3258
NoopRuntimeInterfaceBuilder(Sema &S) : S(S) {}

0 commit comments

Comments
 (0)