Skip to content

Commit 3183b3a

Browse files
authored
[Clang-Repl] Add support for out-of-process execution. (llvm#110418)
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 0e52a07 commit 3183b3a

File tree

8 files changed

+553
-10
lines changed

8 files changed

+553
-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>
@@ -129,10 +130,14 @@ class Interpreter {
129130
public:
130131
virtual ~Interpreter();
131132
static llvm::Expected<std::unique_ptr<Interpreter>>
132-
create(std::unique_ptr<CompilerInstance> CI);
133+
create(std::unique_ptr<CompilerInstance> CI,
134+
std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder = nullptr);
133135
static llvm::Expected<std::unique_ptr<Interpreter>>
134136
createWithCUDA(std::unique_ptr<CompilerInstance> CI,
135137
std::unique_ptr<CompilerInstance> DCI);
138+
static llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
139+
createLLJITBuilder(std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC,
140+
llvm::StringRef OrcRuntimePath);
136141
const ASTContext &getASTContext() const;
137142
ASTContext &getASTContext();
138143
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
@@ -25,6 +25,7 @@ add_clang_library(clangInterpreter
2525
Interpreter.cpp
2626
InterpreterValuePrinter.cpp
2727
InterpreterUtils.cpp
28+
RemoteJITUtils.cpp
2829
Value.cpp
2930
${WASM_SRC}
3031
PARTIAL_SOURCES_INTENDED

clang/lib/Interpreter/Interpreter.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "clang/Sema/Lookup.h"
4545
#include "clang/Serialization/ObjectFilePCHContainerReader.h"
4646
#include "llvm/ExecutionEngine/JITSymbol.h"
47+
#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
4748
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
4849
#include "llvm/IR/Module.h"
4950
#include "llvm/Support/Errc.h"
@@ -456,10 +457,11 @@ const char *const Runtimes = R"(
456457
)";
457458

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

@@ -578,6 +580,25 @@ createJITTargetMachineBuilder(const std::string &TT) {
578580
return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
579581
}
580582

583+
llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
584+
Interpreter::createLLJITBuilder(
585+
std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC,
586+
llvm::StringRef OrcRuntimePath) {
587+
const std::string &TT = EPC->getTargetTriple().getTriple();
588+
auto JTMB = createJITTargetMachineBuilder(TT);
589+
if (!JTMB)
590+
return JTMB.takeError();
591+
auto JB = IncrementalExecutor::createDefaultJITBuilder(std::move(*JTMB));
592+
if (!JB)
593+
return JB.takeError();
594+
595+
(*JB)->setExecutorProcessControl(std::move(EPC));
596+
(*JB)->setPlatformSetUp(
597+
llvm::orc::ExecutorNativePlatform(OrcRuntimePath.str()));
598+
599+
return std::move(*JB);
600+
}
601+
581602
llvm::Error Interpreter::CreateExecutor() {
582603
if (IncrExecutor)
583604
return llvm::make_error<llvm::StringError>("Operation failed. "
@@ -702,11 +723,11 @@ llvm::Error Interpreter::LoadDynamicLibrary(const char *name) {
702723
if (!EE)
703724
return EE.takeError();
704725

705-
auto &DL = EE->getDataLayout();
706-
707-
if (auto DLSG = llvm::orc::DynamicLibrarySearchGenerator::Load(
708-
name, DL.getGlobalPrefix()))
709-
EE->getMainJITDylib().addGenerator(std::move(*DLSG));
726+
if (auto DLSG = llvm::orc::EPCDynamicLibrarySearchGenerator::Load(
727+
EE->getExecutionSession(), name))
728+
// FIXME: Eventually we should put each library in its own JITDylib and
729+
// turn off process symbols by default.
730+
EE->getProcessSymbolsJITDylib()->addGenerator(std::move(*DLSG));
710731
else
711732
return DLSG.takeError();
712733

0 commit comments

Comments
 (0)