Skip to content

Commit 3f53155

Browse files
authored
[REAPPLY][Clang-Repl] Add support for out-of-process execution. llvm#110418 (llvm#144064)
This PR introduces out-of-process (OOP) execution support for Clang-Repl. With this enhancement, two new flags, oop-executor and oop-executor-connect, are added to the Clang-Repl interface. These flags enable the launch of an external executor (llvm-jitlink-executor), which handles code execution in a separate process.
1 parent ac9204d commit 3f53155

File tree

9 files changed

+581
-10
lines changed

9 files changed

+581
-10
lines changed

clang/include/clang/Interpreter/Interpreter.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "llvm/ADT/DenseMap.h"
2222
#include "llvm/ExecutionEngine/JITSymbol.h"
23+
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
2324
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
2425
#include "llvm/Support/Error.h"
2526
#include <memory>
@@ -136,10 +137,14 @@ class Interpreter {
136137
public:
137138
virtual ~Interpreter();
138139
static llvm::Expected<std::unique_ptr<Interpreter>>
139-
create(std::unique_ptr<CompilerInstance> CI);
140+
create(std::unique_ptr<CompilerInstance> CI,
141+
std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder = nullptr);
140142
static llvm::Expected<std::unique_ptr<Interpreter>>
141143
createWithCUDA(std::unique_ptr<CompilerInstance> CI,
142144
std::unique_ptr<CompilerInstance> DCI);
145+
static llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
146+
createLLJITBuilder(std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC,
147+
llvm::StringRef OrcRuntimePath);
143148
const ASTContext &getASTContext() const;
144149
ASTContext &getASTContext();
145150
const CompilerInstance *getCompilerInstance() const;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===-- RemoteJITUtils.h - Utilities for remote-JITing ----------*- C++ -*-===//
2+
//
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
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Utilities for ExecutorProcessControl-based remote JITing with Orc and
10+
// JITLink.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_CLANG_INTERPRETER_REMOTEJITUTILS_H
15+
#define LLVM_CLANG_INTERPRETER_REMOTEJITUTILS_H
16+
17+
#include "llvm/ADT/StringRef.h"
18+
#include "llvm/ExecutionEngine/Orc/Core.h"
19+
#include "llvm/ExecutionEngine/Orc/Layer.h"
20+
#include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
21+
#include "llvm/Support/Error.h"
22+
23+
#include <cstdint>
24+
#include <memory>
25+
#include <string>
26+
27+
llvm::Expected<std::unique_ptr<llvm::orc::SimpleRemoteEPC>>
28+
launchExecutor(llvm::StringRef ExecutablePath, bool UseSharedMemory,
29+
llvm::StringRef SlabAllocateSizeString);
30+
31+
/// Create a JITLinkExecutor that connects to the given network address
32+
/// through a TCP socket. A valid NetworkAddress provides hostname and port,
33+
/// e.g. localhost:20000.
34+
llvm::Expected<std::unique_ptr<llvm::orc::SimpleRemoteEPC>>
35+
connectTCPSocket(llvm::StringRef NetworkAddress, bool UseSharedMemory,
36+
llvm::StringRef SlabAllocateSizeString);
37+
38+
#endif // LLVM_CLANG_INTERPRETER_REMOTEJITUTILS_H

clang/lib/Interpreter/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ add_clang_library(clangInterpreter
2727
Interpreter.cpp
2828
InterpreterValuePrinter.cpp
2929
InterpreterUtils.cpp
30+
RemoteJITUtils.cpp
3031
Value.cpp
3132
${WASM_SRC}
3233
PARTIAL_SOURCES_INTENDED

clang/lib/Interpreter/Interpreter.cpp

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "clang/Sema/Lookup.h"
4747
#include "clang/Serialization/ObjectFilePCHContainerReader.h"
4848
#include "llvm/ExecutionEngine/JITSymbol.h"
49+
#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
4950
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
5051
#include "llvm/IR/Module.h"
5152
#include "llvm/Support/Errc.h"
@@ -455,10 +456,11 @@ const char *const Runtimes = R"(
455456
)";
456457

457458
llvm::Expected<std::unique_ptr<Interpreter>>
458-
Interpreter::create(std::unique_ptr<CompilerInstance> CI) {
459+
Interpreter::create(std::unique_ptr<CompilerInstance> CI,
460+
std::unique_ptr<llvm::orc::LLJITBuilder> JB) {
459461
llvm::Error Err = llvm::Error::success();
460-
auto Interp =
461-
std::unique_ptr<Interpreter>(new Interpreter(std::move(CI), Err));
462+
auto Interp = std::unique_ptr<Interpreter>(
463+
new Interpreter(std::move(CI), Err, JB ? std::move(JB) : nullptr));
462464
if (Err)
463465
return std::move(Err);
464466

@@ -617,6 +619,25 @@ createJITTargetMachineBuilder(const std::string &TT) {
617619
return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
618620
}
619621

622+
llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
623+
Interpreter::createLLJITBuilder(
624+
std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC,
625+
llvm::StringRef OrcRuntimePath) {
626+
const std::string &TT = EPC->getTargetTriple().getTriple();
627+
auto JTMB = createJITTargetMachineBuilder(TT);
628+
if (!JTMB)
629+
return JTMB.takeError();
630+
auto JB = IncrementalExecutor::createDefaultJITBuilder(std::move(*JTMB));
631+
if (!JB)
632+
return JB.takeError();
633+
634+
(*JB)->setExecutorProcessControl(std::move(EPC));
635+
(*JB)->setPlatformSetUp(
636+
llvm::orc::ExecutorNativePlatform(OrcRuntimePath.str()));
637+
638+
return std::move(*JB);
639+
}
640+
620641
llvm::Error Interpreter::CreateExecutor() {
621642
if (IncrExecutor)
622643
return llvm::make_error<llvm::StringError>("Operation failed. "
@@ -756,11 +777,13 @@ llvm::Error Interpreter::LoadDynamicLibrary(const char *name) {
756777
if (!EE)
757778
return EE.takeError();
758779

759-
auto &DL = EE->getDataLayout();
760-
761-
if (auto DLSG = llvm::orc::DynamicLibrarySearchGenerator::Load(
762-
name, DL.getGlobalPrefix()))
763-
EE->getMainJITDylib().addGenerator(std::move(*DLSG));
780+
if (llvm::Expected<
781+
std::unique_ptr<llvm::orc::EPCDynamicLibrarySearchGenerator>>
782+
DLSG = llvm::orc::EPCDynamicLibrarySearchGenerator::Load(
783+
EE->getExecutionSession(), name))
784+
// FIXME: Eventually we should put each library in its own JITDylib and
785+
// turn off process symbols by default.
786+
EE->getProcessSymbolsJITDylib()->addGenerator(std::move(*DLSG));
764787
else
765788
return DLSG.takeError();
766789
#endif

0 commit comments

Comments
 (0)