[llvm] [Opt] Enable statically-linked plugin support (PR #79227)

William Moses via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 24 18:06:36 PST 2024


https://github.com/wsmoses updated https://github.com/llvm/llvm-project/pull/79227

>From 4aaf28fc286d97df491f5f78f55d7f4811b1d821 Mon Sep 17 00:00:00 2001
From: "William S. Moses" <gh at wsmoses.com>
Date: Tue, 23 Jan 2024 18:33:53 -0500
Subject: [PATCH 1/2] [Opt] Enable support for statically linked plugins

---
 llvm/lib/Passes/PassPlugin.cpp            | 31 ++++++++---
 llvm/test/Feature/load_staticextension.ll | 15 ++++++
 llvm/tools/opt/CMakeLists.txt             | 13 +++++
 llvm/tools/opt/PrintPlugin.cpp            | 63 +++++++++++++++++++++++
 4 files changed, 115 insertions(+), 7 deletions(-)
 create mode 100644 llvm/test/Feature/load_staticextension.ll
 create mode 100644 llvm/tools/opt/PrintPlugin.cpp

diff --git a/llvm/lib/Passes/PassPlugin.cpp b/llvm/lib/Passes/PassPlugin.cpp
index 6182cbbb1fddd3..9cdc27491a9bfb 100644
--- a/llvm/lib/Passes/PassPlugin.cpp
+++ b/llvm/lib/Passes/PassPlugin.cpp
@@ -14,20 +14,37 @@
 using namespace llvm;
 
 Expected<PassPlugin> PassPlugin::Load(const std::string &Filename) {
+  // First, see if the plugin is available in the current executable, with the
+  // suffix of the symbol being given by the `Filename` otherwise, try loading
+  // the plugin via the file
   std::string Error;
-  auto Library =
-      sys::DynamicLibrary::getPermanentLibrary(Filename.c_str(), &Error);
+
+  auto Library = sys::DynamicLibrary::getPermanentLibrary(nullptr, &Error);
   if (!Library.isValid())
-    return make_error<StringError>(Twine("Could not load library '") +
-                                       Filename + "': " + Error,
+    return make_error<StringError>("Could not load current executable",
                                    inconvertibleErrorCode());
 
-  PassPlugin P{Filename, Library};
-
   // llvmGetPassPluginInfo should be resolved to the definition from the plugin
   // we are currently loading.
+  std::string symbolName = "llvmGetPassPluginInfo" + Filename;
   intptr_t getDetailsFn =
-      (intptr_t)Library.getAddressOfSymbol("llvmGetPassPluginInfo");
+      (intptr_t)Library.getAddressOfSymbol(symbolName.c_str());
+
+  if (!getDetailsFn) {
+    Library = sys::DynamicLibrary::getPermanentLibrary(
+        (Filename == "") ? nullptr : Filename.c_str(), &Error);
+    if (!Library.isValid())
+      return make_error<StringError>(Twine("Could not load library '") +
+                                         Filename + "': " + Error,
+                                     inconvertibleErrorCode());
+
+    // llvmGetPassPluginInfo should be resolved to the definition from the
+    // plugin we are currently loading.
+    getDetailsFn =
+        (intptr_t)Library.getAddressOfSymbol("llvmGetPassPluginInfo");
+  }
+
+  PassPlugin P{Filename, Library};
 
   if (!getDetailsFn)
     // If the symbol isn't found, this is probably a legacy plugin, which is an
diff --git a/llvm/test/Feature/load_staticextension.ll b/llvm/test/Feature/load_staticextension.ll
new file mode 100644
index 00000000000000..6a17de86c0d18d
--- /dev/null
+++ b/llvm/test/Feature/load_staticextension.ll
@@ -0,0 +1,15 @@
+; REQUIRES: x86-registered-target
+; RUN: opt-printplugin %s -load-pass-plugin="PrintPlugin" -passes="printpass" -disable-output 2>&1 | FileCheck %s
+
+; REQUIRES: plugins
+
+; CHECK: [PrintPass] Found function: somefunk
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+ at junk = global i32 0
+
+define ptr @somefunk() {
+  ret ptr @junk
+}
+
diff --git a/llvm/tools/opt/CMakeLists.txt b/llvm/tools/opt/CMakeLists.txt
index 8d031b2cc57c78..2edb695eee03c9 100644
--- a/llvm/tools/opt/CMakeLists.txt
+++ b/llvm/tools/opt/CMakeLists.txt
@@ -50,3 +50,16 @@ add_llvm_tool(opt
 target_link_libraries(opt PRIVATE LLVMOptDriver)
 
 export_executable_symbols_for_plugins(opt)
+
+if (LLVM_ENABLE_PLUGINS)
+add_llvm_tool(opt-printplugin
+  NewPMDriver.cpp
+  opt.cpp
+  PrintPlugin.cpp
+
+  DEPENDS
+  intrinsics_gen
+  SUPPORT_PLUGINS
+  )
+target_link_options(opt-printplugin PUBLIC -Wl,--export-dynamic-symbol=llvmGetPassPluginInfoPrintPlugin)
+endif()
diff --git a/llvm/tools/opt/PrintPlugin.cpp b/llvm/tools/opt/PrintPlugin.cpp
new file mode 100644
index 00000000000000..b0bbca87b0a54a
--- /dev/null
+++ b/llvm/tools/opt/PrintPlugin.cpp
@@ -0,0 +1,63 @@
+//===- LLVMPrintFunctionNames.cpp
+//---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Example opt plugin which simply prints the names of all the functions
+// within the generated LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/PassManager.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Passes/PassPlugin.h"
+#include "llvm/Support/Registry.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+namespace {
+
+class PrintPass final : public llvm::AnalysisInfoMixin<PrintPass> {
+  friend struct llvm::AnalysisInfoMixin<PrintPass>;
+
+private:
+  static llvm::AnalysisKey key;
+
+public:
+  using Result = llvm::PreservedAnalyses;
+
+  Result run(llvm::Module &M, llvm::ModuleAnalysisManager &MAM) {
+    for (auto &F : M)
+      llvm::outs() << "[PrintPass] Found function: " << F.getName() << "\n";
+    return llvm::PreservedAnalyses::all();
+  }
+  static bool isRequired() { return true; }
+};
+
+} // namespace
+
+llvm::PassPluginLibraryInfo getPrintPluginInfo() {
+  return {LLVM_PLUGIN_API_VERSION, "PrintPlugin", LLVM_VERSION_STRING,
+          [](PassBuilder &PB) {
+            PB.registerPipelineParsingCallback(
+                [](StringRef Name, llvm::ModulePassManager &PM,
+                   ArrayRef<llvm::PassBuilder::PipelineElement>) {
+                  if (Name == "printpass") {
+                    PM.addPass(PrintPass());
+                    return true;
+                  }
+                  return false;
+                });
+          }};
+}
+
+extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
+llvmGetPassPluginInfoPrintPlugin() {
+  return getPrintPluginInfo();
+}

>From 6ea94cb9ccae97266de585670b34bdecaea7c3a7 Mon Sep 17 00:00:00 2001
From: "William S. Moses" <gh at wsmoses.com>
Date: Wed, 24 Jan 2024 15:19:12 -0500
Subject: [PATCH 2/2] fix

---
 llvm/lib/Passes/PassPlugin.cpp                | 31 +++----------
 llvm/test/CMakeLists.txt                      |  1 +
 llvm/test/Feature/load_staticextension.ll     |  2 +-
 llvm/tools/opt/CMakeLists.txt                 | 37 ++--------------
 llvm/tools/opt/driver/CMakeLists.txt          |  8 ++++
 llvm/tools/opt/{ => driver}/opt.cpp           |  0
 llvm/tools/opt/lib/CMakeLists.txt             |  9 ++++
 llvm/tools/opt/{ => lib}/NewPMDriver.cpp      | 20 ++++-----
 llvm/tools/opt/{ => lib}/NewPMDriver.h        |  9 +---
 llvm/tools/opt/{ => lib}/optdriver.cpp        |  0
 llvm/tools/opt/test/CMakeLists.txt            |  8 ++++
 .../opt-printplugin.cpp}                      | 44 ++++++++++---------
 .../llvm-project-overlay/llvm/BUILD.bazel     |  9 ++--
 13 files changed, 78 insertions(+), 100 deletions(-)
 create mode 100644 llvm/tools/opt/driver/CMakeLists.txt
 rename llvm/tools/opt/{ => driver}/opt.cpp (100%)
 create mode 100644 llvm/tools/opt/lib/CMakeLists.txt
 rename llvm/tools/opt/{ => lib}/NewPMDriver.cpp (97%)
 rename llvm/tools/opt/{ => lib}/NewPMDriver.h (97%)
 rename llvm/tools/opt/{ => lib}/optdriver.cpp (100%)
 create mode 100644 llvm/tools/opt/test/CMakeLists.txt
 rename llvm/tools/opt/{PrintPlugin.cpp => test/opt-printplugin.cpp} (57%)

diff --git a/llvm/lib/Passes/PassPlugin.cpp b/llvm/lib/Passes/PassPlugin.cpp
index 9cdc27491a9bfb..6182cbbb1fddd3 100644
--- a/llvm/lib/Passes/PassPlugin.cpp
+++ b/llvm/lib/Passes/PassPlugin.cpp
@@ -14,37 +14,20 @@
 using namespace llvm;
 
 Expected<PassPlugin> PassPlugin::Load(const std::string &Filename) {
-  // First, see if the plugin is available in the current executable, with the
-  // suffix of the symbol being given by the `Filename` otherwise, try loading
-  // the plugin via the file
   std::string Error;
-
-  auto Library = sys::DynamicLibrary::getPermanentLibrary(nullptr, &Error);
+  auto Library =
+      sys::DynamicLibrary::getPermanentLibrary(Filename.c_str(), &Error);
   if (!Library.isValid())
-    return make_error<StringError>("Could not load current executable",
+    return make_error<StringError>(Twine("Could not load library '") +
+                                       Filename + "': " + Error,
                                    inconvertibleErrorCode());
 
+  PassPlugin P{Filename, Library};
+
   // llvmGetPassPluginInfo should be resolved to the definition from the plugin
   // we are currently loading.
-  std::string symbolName = "llvmGetPassPluginInfo" + Filename;
   intptr_t getDetailsFn =
-      (intptr_t)Library.getAddressOfSymbol(symbolName.c_str());
-
-  if (!getDetailsFn) {
-    Library = sys::DynamicLibrary::getPermanentLibrary(
-        (Filename == "") ? nullptr : Filename.c_str(), &Error);
-    if (!Library.isValid())
-      return make_error<StringError>(Twine("Could not load library '") +
-                                         Filename + "': " + Error,
-                                     inconvertibleErrorCode());
-
-    // llvmGetPassPluginInfo should be resolved to the definition from the
-    // plugin we are currently loading.
-    getDetailsFn =
-        (intptr_t)Library.getAddressOfSymbol("llvmGetPassPluginInfo");
-  }
-
-  PassPlugin P{Filename, Library};
+      (intptr_t)Library.getAddressOfSymbol("llvmGetPassPluginInfo");
 
   if (!getDetailsFn)
     // If the symbol isn't found, this is probably a legacy plugin, which is an
diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt
index 6127b76db06b7f..1a07e951811943 100644
--- a/llvm/test/CMakeLists.txt
+++ b/llvm/test/CMakeLists.txt
@@ -138,6 +138,7 @@ set(LLVM_TEST_DEPENDS
           not
           obj2yaml
           opt
+          opt-printplugin
           sancov
           sanstats
           split-file
diff --git a/llvm/test/Feature/load_staticextension.ll b/llvm/test/Feature/load_staticextension.ll
index 6a17de86c0d18d..11b754e1612562 100644
--- a/llvm/test/Feature/load_staticextension.ll
+++ b/llvm/test/Feature/load_staticextension.ll
@@ -1,5 +1,5 @@
 ; REQUIRES: x86-registered-target
-; RUN: opt-printplugin %s -load-pass-plugin="PrintPlugin" -passes="printpass" -disable-output 2>&1 | FileCheck %s
+; RUN: opt-printplugin %s -passes="printpass" -disable-output 2>&1 | FileCheck %s
 
 ; REQUIRES: plugins
 
diff --git a/llvm/tools/opt/CMakeLists.txt b/llvm/tools/opt/CMakeLists.txt
index 2edb695eee03c9..abbfa245350449 100644
--- a/llvm/tools/opt/CMakeLists.txt
+++ b/llvm/tools/opt/CMakeLists.txt
@@ -29,37 +29,6 @@ set(LLVM_LINK_COMPONENTS
   Passes
   )
 
-# We don't want to link this into libLLVM
-add_llvm_library(LLVMOptDriver
-  STATIC
-  NewPMDriver.cpp
-  optdriver.cpp
-  PARTIAL_SOURCES_INTENDED
-  DEPENDS
-  intrinsics_gen
-)
-
-add_llvm_tool(opt
-  PARTIAL_SOURCES_INTENDED
-  opt.cpp
-  DEPENDS
-  intrinsics_gen
-  SUPPORT_PLUGINS
-
-  )
-target_link_libraries(opt PRIVATE LLVMOptDriver)
-
-export_executable_symbols_for_plugins(opt)
-
-if (LLVM_ENABLE_PLUGINS)
-add_llvm_tool(opt-printplugin
-  NewPMDriver.cpp
-  opt.cpp
-  PrintPlugin.cpp
-
-  DEPENDS
-  intrinsics_gen
-  SUPPORT_PLUGINS
-  )
-target_link_options(opt-printplugin PUBLIC -Wl,--export-dynamic-symbol=llvmGetPassPluginInfoPrintPlugin)
-endif()
+add_subdirectory(lib)
+add_subdirectory(driver)
+add_subdirectory(test)
diff --git a/llvm/tools/opt/driver/CMakeLists.txt b/llvm/tools/opt/driver/CMakeLists.txt
new file mode 100644
index 00000000000000..2b0d2722c00f51
--- /dev/null
+++ b/llvm/tools/opt/driver/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_llvm_tool(opt
+  opt.cpp
+  DEPENDS
+  intrinsics_gen
+  SUPPORT_PLUGINS
+  )
+target_link_libraries(opt PRIVATE LLVMOptDriver)
+export_executable_symbols_for_plugins(opt)
diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/driver/opt.cpp
similarity index 100%
rename from llvm/tools/opt/opt.cpp
rename to llvm/tools/opt/driver/opt.cpp
diff --git a/llvm/tools/opt/lib/CMakeLists.txt b/llvm/tools/opt/lib/CMakeLists.txt
new file mode 100644
index 00000000000000..bdcc6507c43c1a
--- /dev/null
+++ b/llvm/tools/opt/lib/CMakeLists.txt
@@ -0,0 +1,9 @@
+# We don't want to link this into libLLVM
+add_llvm_library(LLVMOptDriver
+  STATIC
+  NewPMDriver.cpp
+  optdriver.cpp
+  PARTIAL_SOURCES_INTENDED
+  DEPENDS
+  intrinsics_gen
+)
diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/lib/NewPMDriver.cpp
similarity index 97%
rename from llvm/tools/opt/NewPMDriver.cpp
rename to llvm/tools/opt/lib/NewPMDriver.cpp
index fdfb4df53273fe..7c76e8a1e80b70 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/lib/NewPMDriver.cpp
@@ -57,12 +57,12 @@ cl::opt<bool> VerifyEachDebugInfoPreserve(
     cl::desc("Start each pass with collecting and end it with checking of "
              "debug info preservation."));
 
-cl::opt<std::string>
-    VerifyDIPreserveExport("verify-di-preserve-export",
-                   cl::desc("Export debug info preservation failures into "
-                            "specified (JSON) file (should be abs path as we use"
-                            " append mode to insert new JSON objects)"),
-                   cl::value_desc("filename"), cl::init(""));
+cl::opt<std::string> VerifyDIPreserveExport(
+    "verify-di-preserve-export",
+    cl::desc("Export debug info preservation failures into "
+             "specified (JSON) file (should be abs path as we use"
+             " append mode to insert new JSON objects)"),
+    cl::value_desc("filename"), cl::init(""));
 
 } // namespace llvm
 
@@ -163,7 +163,6 @@ static cl::opt<bool> DisablePipelineVerification(
              "-print-pipeline-passes can be used to create a pipeline."),
     cl::Hidden);
 
-
 static cl::opt<PGOKind>
     PGOKindFlag("pgo-kind", cl::init(NoPGO), cl::Hidden,
                 cl::desc("The kind of profile guided optimization"),
@@ -174,8 +173,8 @@ static cl::opt<PGOKind>
                                       "Use instrumented profile to guide PGO."),
                            clEnumValN(SampleUse, "pgo-sample-use-pipeline",
                                       "Use sampled profile to guide PGO.")));
-static cl::opt<std::string> ProfileFile("profile-file",
-                                 cl::desc("Path to the profile."), cl::Hidden);
+static cl::opt<std::string>
+    ProfileFile("profile-file", cl::desc("Path to the profile."), cl::Hidden);
 static cl::opt<std::string>
     MemoryProfileFile("memory-profile-file",
                       cl::desc("Path to the memory profile."), cl::Hidden);
@@ -411,8 +410,7 @@ bool llvm::runPassPipeline(
   } else if (VerifyEachDebugInfoPreserve) {
     Debugify.setDebugInfoBeforePass(DebugInfoBeforePass);
     Debugify.setDebugifyMode(DebugifyMode::OriginalDebugInfo);
-    Debugify.setOrigDIVerifyBugsReportFilePath(
-      VerifyDIPreserveExport);
+    Debugify.setOrigDIVerifyBugsReportFilePath(VerifyDIPreserveExport);
     Debugify.registerCallbacks(PIC, MAM);
   }
 
diff --git a/llvm/tools/opt/NewPMDriver.h b/llvm/tools/opt/lib/NewPMDriver.h
similarity index 97%
rename from llvm/tools/opt/NewPMDriver.h
rename to llvm/tools/opt/lib/NewPMDriver.h
index 19cabd15436ebe..c9d66855f39e9c 100644
--- a/llvm/tools/opt/NewPMDriver.h
+++ b/llvm/tools/opt/lib/NewPMDriver.h
@@ -45,14 +45,9 @@ enum OutputKind {
   OK_OutputThinLTOBitcode,
 };
 enum VerifierKind { VK_NoVerifier, VK_VerifyOut, VK_VerifyEachPass };
-enum PGOKind {
-  NoPGO,
-  InstrGen,
-  InstrUse,
-  SampleUse
-};
+enum PGOKind { NoPGO, InstrGen, InstrUse, SampleUse };
 enum CSPGOKind { NoCSPGO, CSInstrGen, CSInstrUse };
-}
+} // namespace opt_tool
 
 void printPasses(raw_ostream &OS);
 
diff --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/lib/optdriver.cpp
similarity index 100%
rename from llvm/tools/opt/optdriver.cpp
rename to llvm/tools/opt/lib/optdriver.cpp
diff --git a/llvm/tools/opt/test/CMakeLists.txt b/llvm/tools/opt/test/CMakeLists.txt
new file mode 100644
index 00000000000000..6a2a369519257f
--- /dev/null
+++ b/llvm/tools/opt/test/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_llvm_tool(opt-printplugin
+  opt-printplugin.cpp
+  DEPENDS
+  intrinsics_gen
+  SUPPORT_PLUGINS
+  )
+target_link_libraries(opt-printplugin PRIVATE LLVMOptDriver)
+export_executable_symbols_for_plugins(opt-printplugin)
diff --git a/llvm/tools/opt/PrintPlugin.cpp b/llvm/tools/opt/test/opt-printplugin.cpp
similarity index 57%
rename from llvm/tools/opt/PrintPlugin.cpp
rename to llvm/tools/opt/test/opt-printplugin.cpp
index b0bbca87b0a54a..386a23e4f1d814 100644
--- a/llvm/tools/opt/PrintPlugin.cpp
+++ b/llvm/tools/opt/test/opt-printplugin.cpp
@@ -1,5 +1,5 @@
-//===- LLVMPrintFunctionNames.cpp
-//---------------------------------------------===//
+//===- opt-printplugin.cpp - The LLVM Modular Optimizer
+//-------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,11 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Example opt plugin which simply prints the names of all the functions
+// Example static opt plugin which simply prints the names of all the functions
 // within the generated LLVM code.
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Passes/PassBuilder.h"
@@ -19,6 +20,8 @@
 #include "llvm/Support/Registry.h"
 #include "llvm/Support/raw_ostream.h"
 
+#include <functional>
+
 using namespace llvm;
 
 namespace {
@@ -40,24 +43,25 @@ class PrintPass final : public llvm::AnalysisInfoMixin<PrintPass> {
   static bool isRequired() { return true; }
 };
 
+void registerPlugin(PassBuilder &PB) {
+  PB.registerPipelineParsingCallback(
+      [](StringRef Name, llvm::ModulePassManager &PM,
+         ArrayRef<llvm::PassBuilder::PipelineElement>) {
+        if (Name == "printpass") {
+          PM.addPass(PrintPass());
+          return true;
+        }
+        return false;
+      });
+}
+
 } // namespace
 
-llvm::PassPluginLibraryInfo getPrintPluginInfo() {
-  return {LLVM_PLUGIN_API_VERSION, "PrintPlugin", LLVM_VERSION_STRING,
-          [](PassBuilder &PB) {
-            PB.registerPipelineParsingCallback(
-                [](StringRef Name, llvm::ModulePassManager &PM,
-                   ArrayRef<llvm::PassBuilder::PipelineElement>) {
-                  if (Name == "printpass") {
-                    PM.addPass(PrintPass());
-                    return true;
-                  }
-                  return false;
-                });
-          }};
-}
+extern "C" int optMain(int argc, char **argv,
+                       llvm::ArrayRef<std::function<void(llvm::PassBuilder &)>>
+                           PassBuilderCallbacks);
 
-extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
-llvmGetPassPluginInfoPrintPlugin() {
-  return getPrintPluginInfo();
+int main(int argc, char **argv) {
+  std::function<void(llvm::PassBuilder &)> plugins[] = {registerPlugin};
+  return optMain(argc, argv, plugins);
 }
diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
index c3efe178d6ed6d..d541fecf73b1ad 100644
--- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
@@ -4817,8 +4817,8 @@ cc_binary(
 cc_library(
     name = "opt-driver",
     srcs = glob([
-        "tools/opt/*.cpp",
-        "tools/opt/*.h",
+        "tools/opt/lib/*.cpp",
+        "tools/opt/lib/*.h",
     ]),
     copts = llvm_copts,
     linkopts = select({
@@ -4855,7 +4855,10 @@ cc_library(
 cc_binary(
     name = "opt",
     stamp = 0,
-    deps = [":opt-driver"]
+    deps = [":opt-driver"],
+    srcs = glob([
+        "tools/opt/driver/opt.cpp",
+    ]),
 )
 
 gentbl(



More information about the llvm-commits mailing list