[clang-repl] Expose CreateExecutor() and ResetExecutor() in extended 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.
This commit is contained in:
Stefan Gränitz
2024-03-12 13:55:38 +01:00
committed by GitHub
parent 871086bf7f
commit bde7a6b791
4 changed files with 39 additions and 1 deletions

View File

@@ -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
@@ -114,6 +113,14 @@ protected:
// 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

View File

@@ -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)
@@ -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) {

View File

@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
OrcJIT
Support
TargetParser
TestingSupport
)
add_clang_unittest(ClangReplInterpreterTests

View File

@@ -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) {}