[llvm] [orc-rt] Connect ogre to a controller via a ConnectionSpec (PR #225400)
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 06:48:04 PDT 2026
https://github.com/lhames created https://github.com/llvm/llvm-project/pull/225400
ogre now takes a connection spec as its one positional argument, builds a Session with the bootstrap services registered, registers the "socket:adopt" connector, connects, and runs until the controller disconnects. Arguments after "--" are reserved for the program to run and are not consumed yet.
init.test becomes "ogre --help", since ogre now needs a spec to do anything and has nothing to connect to under lit yet.
>From cfe3e50ab9a980fc59f6aeb3e98f338230ece1bd Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Tue, 22 Sep 2026 18:12:29 +1000
Subject: [PATCH] [orc-rt] Connect ogre to a controller via a ConnectionSpec
ogre now takes a connection spec as its one positional argument, builds
a Session with the bootstrap services registered, registers the
"socket:adopt" connector, connects, and runs until the controller
disconnects. Arguments after "--" are reserved for the program to run
and are not consumed yet.
init.test becomes "ogre --help", since ogre now needs a spec to do
anything and has nothing to connect to under lit yet.
---
orc-rt/test/regression/init.test | 2 +-
orc-rt/tools/ogre/ogre.cpp | 151 +++++++++++++++++++++++++++----
2 files changed, 134 insertions(+), 19 deletions(-)
diff --git a/orc-rt/test/regression/init.test b/orc-rt/test/regression/init.test
index 4bd17014ca979..15c934d27e698 100644
--- a/orc-rt/test/regression/init.test
+++ b/orc-rt/test/regression/init.test
@@ -1 +1 @@
-RUN: ogre %s %s
+RUN: ogre --help
diff --git a/orc-rt/tools/ogre/ogre.cpp b/orc-rt/tools/ogre/ogre.cpp
index bf5ccb0d79033..1fbef3087e79c 100644
--- a/orc-rt/tools/ogre/ogre.cpp
+++ b/orc-rt/tools/ogre/ogre.cpp
@@ -12,17 +12,30 @@
//===----------------------------------------------------------------------===//
#include "orc-rt-internal/tools/OptionParser.h"
+#include "orc-rt/bedrock/ConnectionSpec.h"
+#include "orc-rt/bedrock/ConnectorRegistry.h"
+#include "orc-rt/bedrock/NativeDylibManager.h"
+#include "orc-rt/bedrock/Session.h"
+#include "orc-rt/bedrock/SimpleNativeMemoryMap.h"
+#include "orc-rt/bedrock/SocketConnector.h"
+#include "orc-rt/bedrock/ThreadPoolRunner.h"
+#include "orc-rt/bedrock/sps/AllSPSCI.h"
-#include <optional>
-#include <stdio.h>
+#include <cstdio>
+#include <cstring>
+#include <future>
+#include <variant>
using namespace orc_rt;
struct Options {
+ ConnectionSpec ConnSpec;
bool Verbose = false;
};
-static std::optional<Options> parseArgs(int argc, char *argv[]) noexcept {
+/// Parse and handle options. Return the parsed options struct on success, or an
+/// int error code to return from main otherwise.
+static std::variant<Options, int> parseArgs(int argc, char *argv[]) noexcept {
Options O;
bool ShowHelp = false;
@@ -30,31 +43,133 @@ static std::optional<Options> parseArgs(int argc, char *argv[]) noexcept {
P.addFlag("verbose", "Print verbose output", false, O.Verbose, 'v')
.addFlag("help", "Display this help message", false, ShowHelp, 'h');
- auto PrintHelp = [&]() -> std::nullopt_t {
+ auto PrintHelp = [&](Error Err) -> int {
+ bool Failed = !!Err;
+ if (Err)
+ fprintf(stderr, "error: %s\n", toString(std::move(Err)).c_str());
const char *ProgName = argc != 0 ? argv[0] : "ogre";
- fprintf(stderr, "%s usage:\n%s\n", ProgName,
- P.formatHelp(ProgName).c_str());
- return std::nullopt;
+ fprintf(stderr, "%s", P.formatHelp(ProgName).c_str());
+ return Failed;
};
- if (auto Err = P.parseAsMainArgs(argc, argv)) {
- fprintf(stderr, "error: %s\n", toString(std::move(Err)).c_str());
- return PrintHelp();
- }
+ // ogre options end at the first '--', or at argc if no '--' is present.
+ int OgreOptsEnd;
+ for (OgreOptsEnd = 0; OgreOptsEnd != argc; ++OgreOptsEnd)
+ if (strcmp(argv[OgreOptsEnd], "--") == 0)
+ break;
+
+ if (auto Err = P.parseAsMainArgs(OgreOptsEnd, argv))
+ return PrintHelp(std::move(Err));
if (ShowHelp)
- return PrintHelp();
+ return PrintHelp(Error::success());
+
+ if (P.positionals().size() != 1)
+ return PrintHelp(
+ make_error<StringError>("expected one positional argument"));
+
+ if (auto ConnSpec = ConnectionSpec::parse(P.positionals().front()))
+ O.ConnSpec = std::move(*ConnSpec);
+ else
+ return PrintHelp(ConnSpec.takeError());
return O;
}
-int main(int argc, char *argv[]) {
- auto Opts = parseArgs(argc, argv);
- if (!Opts)
- return 1;
+void reportError(Error Err) noexcept {
+ fprintf(stderr, "reported error: %s\n", toString(std::move(Err)).c_str());
+}
+
+void printExecutorProcessInfo(const ExecutorProcessInfo &EPI) noexcept {
+ fprintf(stderr,
+ "executor info: triple = \"%s\", page-size = %zu, "
+ "cpu-features = \"%s\"\n",
+ EPI.targetTriple().c_str(), EPI.pageSize(),
+ EPI.targetCPUFeatures().c_str());
+}
+
+Error setupSession(Session &S, const Options &Opts,
+ BootstrapInfo &BI) noexcept {
+ if (auto Err = sps_ci::addAll(BI.symbols()))
+ return Err;
+
+ if (auto Err = S.tryCreateService<SimpleNativeMemoryMap>(S, BI.symbols())
+ .takeError())
+ return Err;
+
+ if (auto Err =
+ S.tryCreateService<NativeDylibManager>(S, BI.symbols()).takeError())
+ return Err;
+
+ return Error::success();
+}
+
+Error trySetupAndConnect(Session &S, const Options &Opts) noexcept {
+ ConnectorRegistry ConnRegistry;
+ if (auto Err = registerSocketConnector(ConnRegistry))
+ return Err;
+ // registerTCPConnect(ConnRegistry);
+
+ auto BI = BootstrapInfo::CreateDefault(S);
+ if (!BI)
+ return BI.takeError();
- if (Opts->Verbose)
- printf("*unintelligible grunts*\n");
+ if (auto Err = setupSession(S, Opts, *BI))
+ return Err;
+
+ return ConnRegistry.connect(
+ [&]() noexcept -> Expected<ConnectorRegistry::AttachInfo> {
+ return ConnectorRegistry::AttachInfo{S, std::move(*BI)};
+ },
+ Opts.ConnSpec);
+}
+
+Expected<int> runOgre(const Options &Opts) noexcept {
+ // Get the process info.
+ auto EPI = ExecutorProcessInfo::Detect();
+ if (!EPI)
+ return EPI.takeError();
+ if (Opts.Verbose)
+ printExecutorProcessInfo(*EPI);
+
+ // Build the session.
+ ThreadPoolRunner Run(4);
+ Session S(
+ std::move(*EPI), [&Run](Session::Task T) { Run(std::move(T)); },
+ reportError);
+
+ std::promise<void> StopP;
+ auto StopF = StopP.get_future();
+ S.setOnDisconnect([StopP = std::move(StopP)](Error Err) mutable {
+ if (Err)
+ reportError(std::move(Err));
+ StopP.set_value();
+ });
+
+ if (auto Err = trySetupAndConnect(S, Opts))
+ return Err;
+
+ StopF.get();
return 0;
}
+
+int main(int argc, char *argv[]) {
+ auto OptsOrResult = parseArgs(argc, argv);
+
+ // If parseArgs returned an int then we should just exit with that return
+ // code.
+ if (int *Result = std::get_if<int>(&OptsOrResult))
+ return *Result;
+
+ if (auto *Opts = std::get_if<Options>(&OptsOrResult)) {
+ if (auto Result = runOgre(*Opts))
+ return *Result;
+ else {
+ fprintf(stderr, "error: %s\n", toString(Result.takeError()).c_str());
+ return 1;
+ }
+ }
+
+ ORC_RT_UNREACHABLE("OptsOrResult held unexpected type?");
+}
More information about the llvm-commits
mailing list