[llvm] [llvm] Refactor llc to use OptTable (PR #187901)

Alexis Engelke via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 25 01:16:20 PDT 2026


================
@@ -399,19 +497,79 @@ int main(int argc, char **argv) {
   initializeScavengerTestPass(*Registry);
 
   SmallVector<PassPlugin, 1> PluginList;
-  PassPlugins.setCallback([&](const std::string &PluginPath) {
-    auto Plugin = PassPlugin::Load(PluginPath);
-    if (!Plugin)
-      reportFatalUsageError(Plugin.takeError());
-    PluginList.emplace_back(Plugin.get());
-  });
 
-  // Register the Target and CPU printer for --version.
-  cl::AddExtraVersionPrinter(sys::printDefaultTargetAndDetectedCPU);
-  // Register the target printer for --version.
-  cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
+  LlcOptTable Tbl;
+  unsigned MissingArgIndex, MissingArgCount;
+  ArrayRef<const char *> ArgsArr = ArrayRef(argv + 1, argc - 1);
+  opt::InputArgList Args =
+      Tbl.ParseArgs(ArgsArr, MissingArgIndex, MissingArgCount);
 
-  cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
+  if (MissingArgCount) {
+    reportError("missing argument to option: " +
+                Twine(Args.getArgString(MissingArgIndex)));
+  }
+
+  if (Args.hasArg(OPT_help)) {
+    Tbl.printHelp(outs(), "llc [options] <input bitcode>",
+                  "llvm system compiler");
+    return 0;
+  }
+
+  RecordLlcOpts(Args, PluginList);
+
+  // Arguments not consumed by llc directly must be passed
+  // to the backend via cl::ParseCommandLineOptions. Unfortunately, this
+  // function only accepts a raw argc + argv. Ideally, we'd just construct a
+  // `const char*` vector that we could pass to this function consisting of
+  // string pointers to the original argv from main, but there's no easy way to
+  // do this. Here, we instead reconstruct the arguments as strings and convert
+  // them to `const char*`.
+  std::vector<const char *> NewArgv;
+  NewArgv.push_back(argv[0]);
+
+  // This is used as storage for arguments that need to be rendered and
+  // eventually passed into NewArgv. A std::list is used because it guarantees
+  // that additions to RenderedArgs can be made without invalidating any
+  // pointers to existing elements. These pointers are what we store in NewArgv.
+  std::list<std::string> RenderedArgs;
+
+  // Forward all options that are NOT locally consumed and NOT unknown/input.
+  for (const auto *A : Args) {
+    unsigned ID = A->getOption().getID();
+    if (ID == OPT_INPUT)
+      continue;
+
+    if (ID == OPT_UNKNOWN) {
+      NewArgv.push_back(A->getSpelling().data());
+      continue;
+    }
+
+    if (kLocallyConsumed.find(ID) != kLocallyConsumed.end())
+      continue;
----------------
aengelke wrote:

Instead of a set, explicitly list forwarded arguments that were already parsed?

https://github.com/llvm/llvm-project/pull/187901


More information about the llvm-commits mailing list