[llvm] [opt] Move InitLLVM ownership to the standalone entry point (PR #222559)
Anutosh Bhat via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 10 02:02:15 PDT 2026
https://github.com/anutosh491 created https://github.com/llvm/llvm-project/pull/222559
Please Read: [RFC: Embeddable LLVM tool drivers for long-lived hosts](https://discourse.llvm.org/t/rfc-embeddable-llvm-tool-drivers-for-long-lived-hosts/91754) and [Why `InitLLVM` ownership matters section in the RFC](https://discourse.llvm.org/t/rfc-embeddable-llvm-tool-drivers-for-long-lived-hosts/91754#p-367966-why-initllvm-ownership-matters-7)
`LLVMOptDriver` is already separated from the standalone `opt` executable, but `optMain` currently constructs `InitLLVM` internally. This means its destructor calls `llvm_shutdown()` whenever one driver invocation finishes.
That is appropriate for a standalone executable, but not for a reusable driver called by a long-lived host. For example,
[WasmBolt](https://github.com/anutosh491/WasmBolt) (try [here](https://anutosh21.github.io/WasmBolt/)) invokes `opt`, `llc`, Clang and LLD within one browser-hosted LLVM process and needs the LLVM process state to remain alive between tool invocations.
This patch moves `InitLLVM` ownership into `opt.cpp`:
```text
standalone opt:
main -> InitLLVM -> optMain -> shutdown
embedded host:
host-owned InitLLVM / LLVMToolSession -> optMain
```
Standalone opt therefore keeps the same lifetime and behaviour, while LLVMOptDriver can borrow the lifetime owned by an embedding application.
This patch is independent of the proposed `LLVMToolSession `and `LLVMLlcDriver` changes that I've proposed in the RFC and can be reviewed separately.
>From d7c476470808c69e8aec37cb07d3e07c642d12f8 Mon Sep 17 00:00:00 2001
From: anutosh491 <andersonbhat491 at gmail.com>
Date: Thu, 10 Sep 2026 14:24:46 +0530
Subject: [PATCH] [opt] Move InitLLVM ownership to the standalone entry point
---
llvm/tools/opt/opt.cpp | 6 +++++-
llvm/tools/opt/optdriver.cpp | 3 ---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp
index ad0f8f4ac05f9..3e815a4879a54 100644
--- a/llvm/tools/opt/opt.cpp
+++ b/llvm/tools/opt/opt.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/InitLLVM.h"
#include <functional>
using namespace llvm;
@@ -24,4 +25,7 @@ extern "C" int
optMain(int argc, char **argv,
ArrayRef<std::function<void(PassBuilder &)>> PassBuilderCallbacks);
-int main(int argc, char **argv) { return optMain(argc, argv, {}); }
+int main(int argc, char **argv) {
+ InitLLVM X(argc, argv);
+ return optMain(argc, argv, {});
+}
diff --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp
index 5333825629a27..2a9b567ee7b6d 100644
--- a/llvm/tools/opt/optdriver.cpp
+++ b/llvm/tools/opt/optdriver.cpp
@@ -44,7 +44,6 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/SystemUtils.h"
@@ -401,8 +400,6 @@ static bool shouldForceLegacyPM() {
extern "C" int
optMain(int argc, char **argv,
ArrayRef<std::function<void(PassBuilder &)>> PassBuilderCallbacks) {
- InitLLVM X(argc, argv);
-
// Enable debug stream buffering.
EnableDebugBuffering = true;
More information about the llvm-commits
mailing list