Skip to content

Commit

Permalink
[clang-repl] Expose CreateExecutor() and ResetExecutor() in extended …
Browse files Browse the repository at this point in the history
…Interpreter interface (#84460)

IncrementalExecutor is an implementation detail of the Interpreter. In
order to test extended features properly, we must be able to setup and
tear down the executor manually.
  • Loading branch information
weliveindetail committed Mar 12, 2024
1 parent 871086b commit bde7a6b
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 1 deletion.
9 changes: 8 additions & 1 deletion clang/include/clang/Interpreter/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ class Interpreter {
// An optional parser for CUDA offloading
std::unique_ptr<IncrementalParser> DeviceParser;

llvm::Error CreateExecutor();
unsigned InitPTUSize = 0;

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

// Create the internal IncrementalExecutor, or re-create it after calling
// ResetExecutor().
llvm::Error CreateExecutor();

// Delete the internal IncrementalExecutor. This causes a hard shutdown of the
// JIT engine. In particular, it doesn't run cleanup or destructors.
void ResetExecutor();

// Lazily construct the RuntimeInterfaceBuilder. The provided instance will be
// used for the entire lifetime of the interpreter. The default implementation
// targets the in-process __clang_Interpreter runtime. Override this to use a
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Interpreter/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,10 @@ Interpreter::Parse(llvm::StringRef Code) {
llvm::Error Interpreter::CreateExecutor() {
const clang::TargetInfo &TI =
getCompilerInstance()->getASTContext().getTargetInfo();
if (IncrExecutor)
return llvm::make_error<llvm::StringError>("Operation failed. "
"Execution engine exists",
std::error_code());
llvm::Error Err = llvm::Error::success();
auto Executor = std::make_unique<IncrementalExecutor>(*TSCtx, Err, TI);
if (!Err)
Expand All @@ -383,6 +387,8 @@ llvm::Error Interpreter::CreateExecutor() {
return Err;
}

void Interpreter::ResetExecutor() { IncrExecutor.reset(); }

llvm::Error Interpreter::Execute(PartialTranslationUnit &T) {
assert(T.TheModule);
if (!IncrExecutor) {
Expand Down
1 change: 1 addition & 0 deletions clang/unittests/Interpreter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
OrcJIT
Support
TargetParser
TestingSupport
)

add_clang_unittest(ClangReplInterpreterTests
Expand Down
24 changes: 24 additions & 0 deletions clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,30 @@
using namespace clang;
namespace {

class TestCreateResetExecutor : public Interpreter {
public:
TestCreateResetExecutor(std::unique_ptr<CompilerInstance> CI,
llvm::Error &Err)
: Interpreter(std::move(CI), Err) {}

llvm::Error testCreateExecutor() { return Interpreter::CreateExecutor(); }

void resetExecutor() { Interpreter::ResetExecutor(); }
};

TEST(InterpreterExtensionsTest, ExecutorCreateReset) {
clang::IncrementalCompilerBuilder CB;
llvm::Error ErrOut = llvm::Error::success();
TestCreateResetExecutor Interp(cantFail(CB.CreateCpp()), ErrOut);
cantFail(std::move(ErrOut));
cantFail(Interp.testCreateExecutor());
Interp.resetExecutor();
cantFail(Interp.testCreateExecutor());
EXPECT_THAT_ERROR(Interp.testCreateExecutor(),
llvm::FailedWithMessage("Operation failed. "
"Execution engine exists"));
}

class RecordRuntimeIBMetrics : public Interpreter {
struct NoopRuntimeInterfaceBuilder : public RuntimeInterfaceBuilder {
NoopRuntimeInterfaceBuilder(Sema &S) : S(S) {}
Expand Down

0 comments on commit bde7a6b

Please sign in to comment.