Skip to content

Commit 0589351

Browse files
[Orc][examples] Adopt ExecutorProcessControl API and re-enable LLJITWithRemoteDebugging
The API change originated from D104694. The LLJITWithRemoteDebugging example and the test for it were disabled while it was in the works.
1 parent e427077 commit 0589351

File tree

6 files changed

+50
-43
lines changed

6 files changed

+50
-43
lines changed

llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/CMakeLists.txt

+1-4
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,12 @@ set(LLVM_LINK_COMPONENTS
1010
nativecodegen
1111
)
1212

13-
if (LLVM_INCLUDE_UTILS AND NOT LLVM_INCLUDE_UTILS)
13+
if (LLVM_INCLUDE_UTILS)
1414
add_llvm_example(LLJITWithRemoteDebugging
1515
LLJITWithRemoteDebugging.cpp
1616
RemoteJITUtils.cpp
1717

1818
DEPENDS
1919
llvm-jitlink-executor
2020
)
21-
else()
22-
# Use a temporary no-op target until D104694 lands.
23-
add_custom_target(LLJITWithRemoteDebugging)
2421
endif()

llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/LLJITWithRemoteDebugging.cpp

+7-9
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,12 @@ static cl::opt<bool>
133133

134134
ExitOnError ExitOnErr;
135135

136-
static std::unique_ptr<JITLinkExecutor> connectExecutor(const char *Argv0,
137-
ExecutionSession &ES) {
136+
static std::unique_ptr<JITLinkExecutor> connectExecutor(const char *Argv0) {
138137
// Connect to a running out-of-process executor through a TCP socket.
139138
if (!OOPExecutorConnect.empty()) {
140139
std::unique_ptr<TCPSocketJITLinkExecutor> Exec =
141-
ExitOnErr(JITLinkExecutor::ConnectTCPSocket(OOPExecutorConnect, ES));
140+
ExitOnErr(JITLinkExecutor::ConnectTCPSocket(OOPExecutorConnect,
141+
std::ref(ExitOnErr)));
142142

143143
outs() << "Connected to executor at " << OOPExecutorConnect << "\n";
144144
if (WaitForDebugger) {
@@ -157,7 +157,7 @@ static std::unique_ptr<JITLinkExecutor> connectExecutor(const char *Argv0,
157157

158158
outs() << "Found out-of-process executor: " << Exec->getPath() << "\n";
159159

160-
ExitOnErr(Exec->launch(ES));
160+
ExitOnErr(Exec->launch(std::ref(ExitOnErr)));
161161
if (WaitForDebugger) {
162162
outs() << "Launched executor in subprocess: " << Exec->getPID() << "\n"
163163
<< "Attach a debugger and press any key to continue.\n";
@@ -177,11 +177,8 @@ int main(int argc, char *argv[]) {
177177
ExitOnErr.setBanner(std::string(argv[0]) + ": ");
178178
cl::ParseCommandLineOptions(argc, argv, "LLJITWithRemoteDebugging");
179179

180-
auto ES = std::make_unique<ExecutionSession>();
181-
ES->setErrorReporter([&](Error Err) { ExitOnErr(std::move(Err)); });
182-
183180
// Launch/connect the out-of-process executor.
184-
std::unique_ptr<JITLinkExecutor> Executor = connectExecutor(argv[0], *ES);
181+
std::unique_ptr<JITLinkExecutor> Executor = connectExecutor(argv[0]);
185182

186183
// Load the given IR files.
187184
std::vector<ThreadSafeModule> TSMs;
@@ -215,6 +212,8 @@ int main(int argc, char *argv[]) {
215212

216213
// Create LLJIT and destroy it before disconnecting the target process.
217214
{
215+
std::unique_ptr<ExecutionSession> ES = Executor->startSession();
216+
218217
outs() << "Initializing LLJIT for remote executor\n";
219218
auto J = ExitOnErr(LLJITBuilder()
220219
.setExecutionSession(std::move(ES))
@@ -253,6 +252,5 @@ int main(int argc, char *argv[]) {
253252
outs() << "Exit code: " << Result << "\n";
254253
}
255254

256-
ExitOnErr(Executor->disconnect());
257255
return 0;
258256
}

llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.cpp

+28-18
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ class RemoteExecutorProcessControl
4747
public:
4848
using BaseT::initializeORCRPCEPCBase;
4949

50-
RemoteExecutorProcessControl(ExecutionSession &ES,
51-
std::unique_ptr<RPCChannel> Channel,
52-
std::unique_ptr<RPCEndpoint> Endpoint);
50+
RemoteExecutorProcessControl(std::unique_ptr<RPCChannel> Channel,
51+
std::unique_ptr<RPCEndpoint> Endpoint,
52+
BaseT::ErrorReporter ReportError);
5353

5454
void initializeMemoryManagement();
5555
Error disconnect() override;
@@ -64,10 +64,10 @@ class RemoteExecutorProcessControl
6464
};
6565

6666
RemoteExecutorProcessControl::RemoteExecutorProcessControl(
67-
ExecutionSession &ES, std::unique_ptr<RPCChannel> Channel,
68-
std::unique_ptr<RPCEndpoint> Endpoint)
69-
: BaseT(ES.getSymbolStringPool(), *Endpoint,
70-
[&ES](Error Err) { ES.reportError(std::move(Err)); }),
67+
std::unique_ptr<RPCChannel> Channel, std::unique_ptr<RPCEndpoint> Endpoint,
68+
BaseT::ErrorReporter ReportError)
69+
: BaseT(std::make_shared<SymbolStringPool>(), *Endpoint,
70+
std::move(ReportError)),
7171
Channel(std::move(Channel)), Endpoint(std::move(Endpoint)) {
7272

7373
ListenerThread = std::thread([&]() {
@@ -109,11 +109,17 @@ JITLinkExecutor::~JITLinkExecutor() = default;
109109

110110
Expected<std::unique_ptr<ObjectLayer>>
111111
JITLinkExecutor::operator()(ExecutionSession &ES, const Triple &TT) {
112+
assert(EPC && "RemoteExecutorProcessControl must be initialized");
112113
return std::make_unique<ObjectLinkingLayer>(ES, EPC->getMemMgr());
113114
}
114115

116+
std::unique_ptr<ExecutionSession> JITLinkExecutor::startSession() {
117+
assert(OwnedEPC && "RemoteExecutorProcessControl must be initialized");
118+
return std::make_unique<ExecutionSession>(std::move(OwnedEPC));
119+
}
120+
115121
Error JITLinkExecutor::addDebugSupport(ObjectLayer &ObjLayer) {
116-
auto Registrar = createJITLoaderGDBRegistrar(*EPC);
122+
auto Registrar = createJITLoaderGDBRegistrar(EPC->getExecutionSession());
117123
if (!Registrar)
118124
return Registrar.takeError();
119125

@@ -127,7 +133,8 @@ Error JITLinkExecutor::addDebugSupport(ObjectLayer &ObjLayer) {
127133
Expected<std::unique_ptr<DefinitionGenerator>>
128134
JITLinkExecutor::loadDylib(StringRef RemotePath) {
129135
if (auto Handle = EPC->loadDylib(RemotePath.data()))
130-
return std::make_unique<EPCDynamicLibrarySearchGenerator>(*EPC, *Handle);
136+
return std::make_unique<EPCDynamicLibrarySearchGenerator>(
137+
EPC->getExecutionSession(), *Handle);
131138
else
132139
return Handle.takeError();
133140
}
@@ -174,7 +181,8 @@ JITLinkExecutor::CreateLocal(std::string ExecutablePath) {
174181

175182
TCPSocketJITLinkExecutor::TCPSocketJITLinkExecutor(
176183
std::unique_ptr<RemoteExecutorProcessControl> EPC) {
177-
this->EPC = std::move(EPC);
184+
this->OwnedEPC = std::move(EPC);
185+
this->EPC = this->OwnedEPC.get();
178186
}
179187

180188
#ifndef LLVM_ON_UNIX
@@ -197,7 +205,8 @@ JITLinkExecutor::ConnectTCPSocket(StringRef NetworkAddress,
197205

198206
#else
199207

200-
Error ChildProcessJITLinkExecutor::launch(ExecutionSession &ES) {
208+
Error ChildProcessJITLinkExecutor::launch(
209+
unique_function<void(Error)> ErrorReporter) {
201210
constexpr int ReadEnd = 0;
202211
constexpr int WriteEnd = 1;
203212

@@ -252,13 +261,14 @@ Error ChildProcessJITLinkExecutor::launch(ExecutionSession &ES) {
252261
auto Endpoint = std::make_unique<RemoteExecutorProcessControl::RPCEndpoint>(
253262
*Channel, true);
254263

255-
EPC = std::make_unique<RemoteExecutorProcessControl>(ES, std::move(Channel),
256-
std::move(Endpoint));
264+
OwnedEPC = std::make_unique<RemoteExecutorProcessControl>(
265+
std::move(Channel), std::move(Endpoint), std::move(ErrorReporter));
257266

258-
if (auto Err = EPC->initializeORCRPCEPCBase())
259-
return joinErrors(std::move(Err), EPC->disconnect());
267+
if (auto Err = OwnedEPC->initializeORCRPCEPCBase())
268+
return joinErrors(std::move(Err), OwnedEPC->disconnect());
260269

261-
EPC->initializeMemoryManagement();
270+
OwnedEPC->initializeMemoryManagement();
271+
EPC = OwnedEPC.get();
262272

263273
shared::registerStringError<RPCChannel>();
264274
return Error::success();
@@ -305,7 +315,7 @@ static Expected<int> connectTCPSocketImpl(std::string Host,
305315

306316
Expected<std::unique_ptr<TCPSocketJITLinkExecutor>>
307317
JITLinkExecutor::ConnectTCPSocket(StringRef NetworkAddress,
308-
ExecutionSession &ES) {
318+
unique_function<void(Error)> ErrorReporter) {
309319
auto CreateErr = [NetworkAddress](StringRef Details) {
310320
return make_error<StringError>(
311321
formatv("Failed to connect TCP socket '{0}': {1}", NetworkAddress,
@@ -332,7 +342,7 @@ JITLinkExecutor::ConnectTCPSocket(StringRef NetworkAddress,
332342
*Channel, true);
333343

334344
auto EPC = std::make_unique<RemoteExecutorProcessControl>(
335-
ES, std::move(Channel), std::move(Endpoint));
345+
std::move(Channel), std::move(Endpoint), std::move(ErrorReporter));
336346

337347
if (auto Err = EPC->initializeORCRPCEPCBase())
338348
return joinErrors(std::move(Err), EPC->disconnect());

llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -56,33 +56,37 @@ class JITLinkExecutor {
5656
/// through a TCP socket. A valid NetworkAddress provides hostname and port,
5757
/// e.g. localhost:20000.
5858
static Expected<std::unique_ptr<TCPSocketJITLinkExecutor>>
59-
ConnectTCPSocket(StringRef NetworkAddress, ExecutionSession &ES);
59+
ConnectTCPSocket(StringRef NetworkAddress,
60+
unique_function<void(Error)> ErrorReporter);
6061

6162
// Implement ObjectLinkingLayerCreator
6263
Expected<std::unique_ptr<ObjectLayer>> operator()(ExecutionSession &,
6364
const Triple &);
6465

66+
std::unique_ptr<ExecutionSession> startSession();
67+
Error disconnect();
68+
6569
Error addDebugSupport(ObjectLayer &ObjLayer);
6670

6771
Expected<std::unique_ptr<DefinitionGenerator>>
6872
loadDylib(StringRef RemotePath);
6973

7074
Expected<int> runAsMain(JITEvaluatedSymbol MainSym,
7175
ArrayRef<std::string> Args);
72-
Error disconnect();
7376

7477
virtual ~JITLinkExecutor();
7578

7679
protected:
77-
std::unique_ptr<RemoteExecutorProcessControl> EPC;
80+
std::unique_ptr<RemoteExecutorProcessControl> OwnedEPC{nullptr};
81+
RemoteExecutorProcessControl *EPC{nullptr};
7882

7983
JITLinkExecutor();
8084
};
8185

8286
/// JITLinkExecutor that runs in a child process on the local machine.
8387
class ChildProcessJITLinkExecutor : public JITLinkExecutor {
8488
public:
85-
Error launch(ExecutionSession &ES);
89+
Error launch(unique_function<void(Error)> ErrorReporter);
8690

8791
pid_t getPID() const { return ProcessID; }
8892
StringRef getPath() const { return ExecutablePath; }

llvm/test/Examples/OrcV2Examples/lljit-with-remote-debugging.test

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# This test makes sure that the example builds and executes as expected.
22
# Instructions for debugging can be found in LLJITWithRemoteDebugging.cpp
33

4-
# RUN: LLJITWithRemoteDebugging %p/Inputs/argc_sub1_elf.ll | FileCheck --check-prefix=CHECK1 %s
5-
# CHECK1: Parsing input IR code from: {{.*}}/Inputs/argc_sub1_elf.ll
6-
# CHECK1: Running: main()
7-
# CHECK1: Exit code: 0
4+
# RUN: LLJITWithRemoteDebugging %p/Inputs/argc_sub1_elf.ll | FileCheck --check-prefix=CHECK0 %s
5+
# CHECK0: Parsing input IR code from: {{.*}}/Inputs/argc_sub1_elf.ll
6+
# CHECK0: Running: main()
7+
# CHECK0: Exit code: 0
88

99
# RUN: LLJITWithRemoteDebugging %p/Inputs/argc_sub1_elf.ll --args 2nd 3rd 4th | FileCheck --check-prefix=CHECK3 %s
1010
# CHECK3: Parsing input IR code from: {{.*}}/Inputs/argc_sub1_elf.ll

llvm/test/Examples/lit.local.cfg

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
#if not config.build_examples or sys.platform in ['win32']:
2-
3-
# Mark both lljit-with-* tests unsupported until D104694 lands.
4-
config.unsupported = True
1+
if not config.build_examples or sys.platform in ['win32']:
2+
config.unsupported = True
53

64
# Test discovery should ignore subdirectories that contain test inputs.
75
config.excludes = ['Inputs']

0 commit comments

Comments
 (0)