https://github.com/tclin914 updated 
https://github.com/llvm/llvm-project/pull/169762

>From c15ccbb6f797c24d9a3b28f5e0d8d9ca93a76668 Mon Sep 17 00:00:00 2001
From: Jim Lin <[email protected]>
Date: Fri, 21 Nov 2025 15:35:24 +0800
Subject: [PATCH 1/5] [Clang] Reuse the function getOptimizationLevel in
 tools::addLTOOptions.

I also move the functions getOptimizationLevel/getOptimizationLevelSize
to Driver.cpp. That we can more easily use those functions. Don't need
to add clangFrontend to LINK_LIBS additionally.
---
 clang/include/clang/Driver/Driver.h           |  7 +++
 .../clang/Frontend/CompilerInvocation.h       |  5 --
 clang/lib/Driver/Driver.cpp                   | 57 +++++++++++++++++++
 clang/lib/Driver/ToolChains/CommonArgs.cpp    | 27 +++------
 clang/lib/Frontend/CompilerInvocation.cpp     | 55 ------------------
 5 files changed, 71 insertions(+), 80 deletions(-)

diff --git a/clang/include/clang/Driver/Driver.h 
b/clang/include/clang/Driver/Driver.h
index 76a6c5a128efb..ab7c8d83adcaa 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -19,6 +19,7 @@
 #include "clang/Driver/ToolChain.h"
 #include "clang/Driver/Types.h"
 #include "clang/Driver/Util.h"
+#include "clang/Frontend/FrontendOptions.h"
 #include "clang/Options/Options.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLFunctionalExtras.h"
@@ -916,6 +917,12 @@ void applyOverrideOptions(SmallVectorImpl<const char *> 
&Args,
                           raw_ostream *OS = nullptr);
 
 } // end namespace driver
+
+unsigned getOptimizationLevel(const llvm::opt::ArgList &Args, InputKind IK,
+                              DiagnosticsEngine &Diags);
+
+unsigned getOptimizationLevelSize(const llvm::opt::ArgList &Args);
+
 } // end namespace clang
 
 #endif
diff --git a/clang/include/clang/Frontend/CompilerInvocation.h 
b/clang/include/clang/Frontend/CompilerInvocation.h
index 4977ddb307d21..57de5a4699975 100644
--- a/clang/include/clang/Frontend/CompilerInvocation.h
+++ b/clang/include/clang/Frontend/CompilerInvocation.h
@@ -67,11 +67,6 @@ bool ParseDiagnosticArgs(DiagnosticOptions &Opts, 
llvm::opt::ArgList &Args,
                          DiagnosticsEngine *Diags = nullptr,
                          bool DefaultDiagColor = true);
 
-unsigned getOptimizationLevel(llvm::opt::ArgList &Args, InputKind IK,
-                              DiagnosticsEngine &Diags);
-
-unsigned getOptimizationLevelSize(llvm::opt::ArgList &Args);
-
 /// The base class of CompilerInvocation. It keeps individual option objects
 /// behind reference-counted pointers, which is useful for clients that want to
 /// keep select option objects alive (even after CompilerInvocation gets
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 8644a271a04b5..78a03057447fc 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -7420,3 +7420,60 @@ void driver::applyOverrideOptions(SmallVectorImpl<const 
char *> &Args,
       ++S;
   }
 }
+
+unsigned clang::getOptimizationLevel(const ArgList &Args, InputKind IK,
+                                     DiagnosticsEngine &Diags) {
+  unsigned DefaultOpt = 0;
+  if ((IK.getLanguage() == Language::OpenCL ||
+       IK.getLanguage() == Language::OpenCLCXX) &&
+      !Args.hasArg(clang::options::OPT_cl_opt_disable))
+    DefaultOpt = 2;
+
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    if (A->getOption().matches(options::OPT_O0))
+      return 0;
+
+    if (A->getOption().matches(options::OPT_Ofast))
+      return 3;
+
+    assert(A->getOption().matches(options::OPT_O));
+
+    StringRef S(A->getValue());
+    if (S == "s" || S == "z")
+      return 2;
+
+    if (S == "g")
+      return 1;
+
+    DefaultOpt =
+        getLastArgIntValue(Args, clang::options::OPT_O, DefaultOpt, Diags);
+  }
+
+  unsigned MaxOptLevel = 3;
+  if (DefaultOpt > MaxOptLevel) {
+    // If the optimization level is not supported, fall back on the default
+    // optimization
+    Diags.Report(diag::warn_drv_optimization_value)
+        << Args.getLastArg(clang::options::OPT_O)->getAsString(Args) << "-O"
+        << MaxOptLevel;
+    DefaultOpt = MaxOptLevel;
+  }
+
+  return DefaultOpt;
+}
+
+unsigned clang::getOptimizationLevelSize(const ArgList &Args) {
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    if (A->getOption().matches(options::OPT_O)) {
+      switch (A->getValue()[0]) {
+      default:
+        return 0;
+      case 's':
+        return 1;
+      case 'z':
+        return 2;
+      }
+    }
+  }
+  return 0;
+}
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index d3539a594df11..c07cdc82eec82 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1095,27 +1095,14 @@ void tools::addLTOOptions(const ToolChain &ToolChain, 
const ArgList &Args,
     CmdArgs.push_back(
         Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash + "mcpu=" + 
CPU));
 
-  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
-    // The optimization level matches
-    // CompilerInvocation.cpp:getOptimizationLevel().
-    StringRef OOpt;
-    if (A->getOption().matches(options::OPT_O4) ||
-        A->getOption().matches(options::OPT_Ofast))
-      OOpt = "3";
-    else if (A->getOption().matches(options::OPT_O)) {
-      OOpt = A->getValue();
-      if (OOpt == "g")
-        OOpt = "1";
-      else if (OOpt == "s" || OOpt == "z")
-        OOpt = "2";
-    } else if (A->getOption().matches(options::OPT_O0))
-      OOpt = "0";
-    if (!OOpt.empty()) {
+  if (Args.getLastArg(options::OPT_O_Group)) {
+    unsigned OptimizationLevel =
+        getOptimizationLevel(Args, InputKind(), D.getDiags());
+    CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash +
+                                         "O" + Twine(OptimizationLevel)));
+    if (IsAMDGCN)
       CmdArgs.push_back(
-          Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash + "O" + OOpt));
-      if (IsAMDGCN)
-        CmdArgs.push_back(Args.MakeArgString(Twine("--lto-CGO") + OOpt));
-    }
+          Args.MakeArgString(Twine("--lto-CGO") + Twine(OptimizationLevel)));
   }
 
   if (Args.hasArg(options::OPT_gsplit_dwarf)) {
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index d2a5ed6262de1..ba3276447eaac 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2669,61 +2669,6 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, 
ArgList &Args,
   return Diags->getNumErrors() == NumErrorsBefore;
 }
 
-unsigned clang::getOptimizationLevel(ArgList &Args, InputKind IK,
-                                     DiagnosticsEngine &Diags) {
-  unsigned DefaultOpt = 0;
-  if ((IK.getLanguage() == Language::OpenCL ||
-       IK.getLanguage() == Language::OpenCLCXX) &&
-      !Args.hasArg(OPT_cl_opt_disable))
-    DefaultOpt = 2;
-
-  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
-    if (A->getOption().matches(options::OPT_O0))
-      return 0;
-
-    if (A->getOption().matches(options::OPT_Ofast))
-      return 3;
-
-    assert(A->getOption().matches(options::OPT_O));
-
-    StringRef S(A->getValue());
-    if (S == "s" || S == "z")
-      return 2;
-
-    if (S == "g")
-      return 1;
-
-    DefaultOpt = getLastArgIntValue(Args, OPT_O, DefaultOpt, Diags);
-  }
-
-  unsigned MaxOptLevel = 3;
-  if (DefaultOpt > MaxOptLevel) {
-    // If the optimization level is not supported, fall back on the default
-    // optimization
-    Diags.Report(diag::warn_drv_optimization_value)
-        << Args.getLastArg(OPT_O)->getAsString(Args) << "-O" << MaxOptLevel;
-    DefaultOpt = MaxOptLevel;
-  }
-
-  return DefaultOpt;
-}
-
-unsigned clang::getOptimizationLevelSize(ArgList &Args) {
-  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
-    if (A->getOption().matches(options::OPT_O)) {
-      switch (A->getValue()[0]) {
-      default:
-        return 0;
-      case 's':
-        return 1;
-      case 'z':
-        return 2;
-      }
-    }
-  }
-  return 0;
-}
-
 /// Parse the argument to the -ftest-module-file-extension
 /// command-line argument.
 ///

>From 0fc8606c9555cab027b13907737c72006ab04524 Mon Sep 17 00:00:00 2001
From: Jim Lin <[email protected]>
Date: Tue, 2 Dec 2025 13:03:01 +0800
Subject: [PATCH 2/5] Move getOptimizationLevel/getOptimizationLevelSize to
 `clang::driver` namespace

---
 clang/include/clang/Driver/Driver.h | 3 +--
 clang/lib/Driver/Driver.cpp         | 6 +++---
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/Driver/Driver.h 
b/clang/include/clang/Driver/Driver.h
index ab7c8d83adcaa..d33db3d8c8b4a 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -916,13 +916,12 @@ void applyOverrideOptions(SmallVectorImpl<const char *> 
&Args,
                           llvm::StringSet<> &SavedStrings, StringRef EnvVar,
                           raw_ostream *OS = nullptr);
 
-} // end namespace driver
-
 unsigned getOptimizationLevel(const llvm::opt::ArgList &Args, InputKind IK,
                               DiagnosticsEngine &Diags);
 
 unsigned getOptimizationLevelSize(const llvm::opt::ArgList &Args);
 
+} // end namespace driver
 } // end namespace clang
 
 #endif
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 78a03057447fc..01d4d698ff195 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -7421,8 +7421,8 @@ void driver::applyOverrideOptions(SmallVectorImpl<const 
char *> &Args,
   }
 }
 
-unsigned clang::getOptimizationLevel(const ArgList &Args, InputKind IK,
-                                     DiagnosticsEngine &Diags) {
+unsigned clang::driver::getOptimizationLevel(const ArgList &Args, InputKind IK,
+                                             DiagnosticsEngine &Diags) {
   unsigned DefaultOpt = 0;
   if ((IK.getLanguage() == Language::OpenCL ||
        IK.getLanguage() == Language::OpenCLCXX) &&
@@ -7462,7 +7462,7 @@ unsigned clang::getOptimizationLevel(const ArgList &Args, 
InputKind IK,
   return DefaultOpt;
 }
 
-unsigned clang::getOptimizationLevelSize(const ArgList &Args) {
+unsigned clang::driver::getOptimizationLevelSize(const ArgList &Args) {
   if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
     if (A->getOption().matches(options::OPT_O)) {
       switch (A->getValue()[0]) {

>From e4d5f5769a003fd3c86009414932130b375cc3bb Mon Sep 17 00:00:00 2001
From: Jim Lin <[email protected]>
Date: Wed, 3 Dec 2025 15:58:23 +0800
Subject: [PATCH 3/5] Revert "Move
 getOptimizationLevel/getOptimizationLevelSize to `clang::driver` namespace"

This reverts commit 0fc8606c9555cab027b13907737c72006ab04524.
---
 clang/include/clang/Driver/Driver.h | 3 ++-
 clang/lib/Driver/Driver.cpp         | 6 +++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Driver/Driver.h 
b/clang/include/clang/Driver/Driver.h
index d33db3d8c8b4a..ab7c8d83adcaa 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -916,12 +916,13 @@ void applyOverrideOptions(SmallVectorImpl<const char *> 
&Args,
                           llvm::StringSet<> &SavedStrings, StringRef EnvVar,
                           raw_ostream *OS = nullptr);
 
+} // end namespace driver
+
 unsigned getOptimizationLevel(const llvm::opt::ArgList &Args, InputKind IK,
                               DiagnosticsEngine &Diags);
 
 unsigned getOptimizationLevelSize(const llvm::opt::ArgList &Args);
 
-} // end namespace driver
 } // end namespace clang
 
 #endif
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 01d4d698ff195..78a03057447fc 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -7421,8 +7421,8 @@ void driver::applyOverrideOptions(SmallVectorImpl<const 
char *> &Args,
   }
 }
 
-unsigned clang::driver::getOptimizationLevel(const ArgList &Args, InputKind IK,
-                                             DiagnosticsEngine &Diags) {
+unsigned clang::getOptimizationLevel(const ArgList &Args, InputKind IK,
+                                     DiagnosticsEngine &Diags) {
   unsigned DefaultOpt = 0;
   if ((IK.getLanguage() == Language::OpenCL ||
        IK.getLanguage() == Language::OpenCLCXX) &&
@@ -7462,7 +7462,7 @@ unsigned clang::driver::getOptimizationLevel(const 
ArgList &Args, InputKind IK,
   return DefaultOpt;
 }
 
-unsigned clang::driver::getOptimizationLevelSize(const ArgList &Args) {
+unsigned clang::getOptimizationLevelSize(const ArgList &Args) {
   if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
     if (A->getOption().matches(options::OPT_O)) {
       switch (A->getValue()[0]) {

>From 7b39053535ef7bd0ff129ce9a7f879fd41fd836e Mon Sep 17 00:00:00 2001
From: Jim Lin <[email protected]>
Date: Wed, 3 Dec 2025 15:58:31 +0800
Subject: [PATCH 4/5] Revert "[Clang] Reuse the function getOptimizationLevel
 in tools::addLTOOptions."

This reverts commit c15ccbb6f797c24d9a3b28f5e0d8d9ca93a76668.
---
 clang/include/clang/Driver/Driver.h           |  7 ---
 .../clang/Frontend/CompilerInvocation.h       |  5 ++
 clang/lib/Driver/Driver.cpp                   | 57 -------------------
 clang/lib/Driver/ToolChains/CommonArgs.cpp    | 27 ++++++---
 clang/lib/Frontend/CompilerInvocation.cpp     | 55 ++++++++++++++++++
 5 files changed, 80 insertions(+), 71 deletions(-)

diff --git a/clang/include/clang/Driver/Driver.h 
b/clang/include/clang/Driver/Driver.h
index ab7c8d83adcaa..76a6c5a128efb 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -19,7 +19,6 @@
 #include "clang/Driver/ToolChain.h"
 #include "clang/Driver/Types.h"
 #include "clang/Driver/Util.h"
-#include "clang/Frontend/FrontendOptions.h"
 #include "clang/Options/Options.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLFunctionalExtras.h"
@@ -917,12 +916,6 @@ void applyOverrideOptions(SmallVectorImpl<const char *> 
&Args,
                           raw_ostream *OS = nullptr);
 
 } // end namespace driver
-
-unsigned getOptimizationLevel(const llvm::opt::ArgList &Args, InputKind IK,
-                              DiagnosticsEngine &Diags);
-
-unsigned getOptimizationLevelSize(const llvm::opt::ArgList &Args);
-
 } // end namespace clang
 
 #endif
diff --git a/clang/include/clang/Frontend/CompilerInvocation.h 
b/clang/include/clang/Frontend/CompilerInvocation.h
index 57de5a4699975..4977ddb307d21 100644
--- a/clang/include/clang/Frontend/CompilerInvocation.h
+++ b/clang/include/clang/Frontend/CompilerInvocation.h
@@ -67,6 +67,11 @@ bool ParseDiagnosticArgs(DiagnosticOptions &Opts, 
llvm::opt::ArgList &Args,
                          DiagnosticsEngine *Diags = nullptr,
                          bool DefaultDiagColor = true);
 
+unsigned getOptimizationLevel(llvm::opt::ArgList &Args, InputKind IK,
+                              DiagnosticsEngine &Diags);
+
+unsigned getOptimizationLevelSize(llvm::opt::ArgList &Args);
+
 /// The base class of CompilerInvocation. It keeps individual option objects
 /// behind reference-counted pointers, which is useful for clients that want to
 /// keep select option objects alive (even after CompilerInvocation gets
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 78a03057447fc..8644a271a04b5 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -7420,60 +7420,3 @@ void driver::applyOverrideOptions(SmallVectorImpl<const 
char *> &Args,
       ++S;
   }
 }
-
-unsigned clang::getOptimizationLevel(const ArgList &Args, InputKind IK,
-                                     DiagnosticsEngine &Diags) {
-  unsigned DefaultOpt = 0;
-  if ((IK.getLanguage() == Language::OpenCL ||
-       IK.getLanguage() == Language::OpenCLCXX) &&
-      !Args.hasArg(clang::options::OPT_cl_opt_disable))
-    DefaultOpt = 2;
-
-  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
-    if (A->getOption().matches(options::OPT_O0))
-      return 0;
-
-    if (A->getOption().matches(options::OPT_Ofast))
-      return 3;
-
-    assert(A->getOption().matches(options::OPT_O));
-
-    StringRef S(A->getValue());
-    if (S == "s" || S == "z")
-      return 2;
-
-    if (S == "g")
-      return 1;
-
-    DefaultOpt =
-        getLastArgIntValue(Args, clang::options::OPT_O, DefaultOpt, Diags);
-  }
-
-  unsigned MaxOptLevel = 3;
-  if (DefaultOpt > MaxOptLevel) {
-    // If the optimization level is not supported, fall back on the default
-    // optimization
-    Diags.Report(diag::warn_drv_optimization_value)
-        << Args.getLastArg(clang::options::OPT_O)->getAsString(Args) << "-O"
-        << MaxOptLevel;
-    DefaultOpt = MaxOptLevel;
-  }
-
-  return DefaultOpt;
-}
-
-unsigned clang::getOptimizationLevelSize(const ArgList &Args) {
-  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
-    if (A->getOption().matches(options::OPT_O)) {
-      switch (A->getValue()[0]) {
-      default:
-        return 0;
-      case 's':
-        return 1;
-      case 'z':
-        return 2;
-      }
-    }
-  }
-  return 0;
-}
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index c07cdc82eec82..d3539a594df11 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1095,14 +1095,27 @@ void tools::addLTOOptions(const ToolChain &ToolChain, 
const ArgList &Args,
     CmdArgs.push_back(
         Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash + "mcpu=" + 
CPU));
 
-  if (Args.getLastArg(options::OPT_O_Group)) {
-    unsigned OptimizationLevel =
-        getOptimizationLevel(Args, InputKind(), D.getDiags());
-    CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash +
-                                         "O" + Twine(OptimizationLevel)));
-    if (IsAMDGCN)
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    // The optimization level matches
+    // CompilerInvocation.cpp:getOptimizationLevel().
+    StringRef OOpt;
+    if (A->getOption().matches(options::OPT_O4) ||
+        A->getOption().matches(options::OPT_Ofast))
+      OOpt = "3";
+    else if (A->getOption().matches(options::OPT_O)) {
+      OOpt = A->getValue();
+      if (OOpt == "g")
+        OOpt = "1";
+      else if (OOpt == "s" || OOpt == "z")
+        OOpt = "2";
+    } else if (A->getOption().matches(options::OPT_O0))
+      OOpt = "0";
+    if (!OOpt.empty()) {
       CmdArgs.push_back(
-          Args.MakeArgString(Twine("--lto-CGO") + Twine(OptimizationLevel)));
+          Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash + "O" + OOpt));
+      if (IsAMDGCN)
+        CmdArgs.push_back(Args.MakeArgString(Twine("--lto-CGO") + OOpt));
+    }
   }
 
   if (Args.hasArg(options::OPT_gsplit_dwarf)) {
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index ba3276447eaac..d2a5ed6262de1 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2669,6 +2669,61 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, 
ArgList &Args,
   return Diags->getNumErrors() == NumErrorsBefore;
 }
 
+unsigned clang::getOptimizationLevel(ArgList &Args, InputKind IK,
+                                     DiagnosticsEngine &Diags) {
+  unsigned DefaultOpt = 0;
+  if ((IK.getLanguage() == Language::OpenCL ||
+       IK.getLanguage() == Language::OpenCLCXX) &&
+      !Args.hasArg(OPT_cl_opt_disable))
+    DefaultOpt = 2;
+
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    if (A->getOption().matches(options::OPT_O0))
+      return 0;
+
+    if (A->getOption().matches(options::OPT_Ofast))
+      return 3;
+
+    assert(A->getOption().matches(options::OPT_O));
+
+    StringRef S(A->getValue());
+    if (S == "s" || S == "z")
+      return 2;
+
+    if (S == "g")
+      return 1;
+
+    DefaultOpt = getLastArgIntValue(Args, OPT_O, DefaultOpt, Diags);
+  }
+
+  unsigned MaxOptLevel = 3;
+  if (DefaultOpt > MaxOptLevel) {
+    // If the optimization level is not supported, fall back on the default
+    // optimization
+    Diags.Report(diag::warn_drv_optimization_value)
+        << Args.getLastArg(OPT_O)->getAsString(Args) << "-O" << MaxOptLevel;
+    DefaultOpt = MaxOptLevel;
+  }
+
+  return DefaultOpt;
+}
+
+unsigned clang::getOptimizationLevelSize(ArgList &Args) {
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    if (A->getOption().matches(options::OPT_O)) {
+      switch (A->getValue()[0]) {
+      default:
+        return 0;
+      case 's':
+        return 1;
+      case 'z':
+        return 2;
+      }
+    }
+  }
+  return 0;
+}
+
 /// Parse the argument to the -ftest-module-file-extension
 /// command-line argument.
 ///

>From 19303c001c7806fc6490bb7459869a7098b735e3 Mon Sep 17 00:00:00 2001
From: Jim Lin <[email protected]>
Date: Wed, 3 Dec 2025 10:10:56 +0800
Subject: [PATCH 5/5] Don't move the functions to Driver

After https://github.com/llvm/llvm-project/pull/169599, the dependency
of clangDriver and clangFrontend is removed.
---
 .../clang/Frontend/CompilerInvocation.h       |  4 +--
 clang/lib/Driver/ToolChains/CommonArgs.cpp    | 28 ++++++-------------
 clang/lib/Frontend/CompilerInvocation.cpp     |  4 +--
 3 files changed, 12 insertions(+), 24 deletions(-)

diff --git a/clang/include/clang/Frontend/CompilerInvocation.h 
b/clang/include/clang/Frontend/CompilerInvocation.h
index 4977ddb307d21..903583e3fe79c 100644
--- a/clang/include/clang/Frontend/CompilerInvocation.h
+++ b/clang/include/clang/Frontend/CompilerInvocation.h
@@ -67,10 +67,10 @@ bool ParseDiagnosticArgs(DiagnosticOptions &Opts, 
llvm::opt::ArgList &Args,
                          DiagnosticsEngine *Diags = nullptr,
                          bool DefaultDiagColor = true);
 
-unsigned getOptimizationLevel(llvm::opt::ArgList &Args, InputKind IK,
+unsigned getOptimizationLevel(const llvm::opt::ArgList &Args, InputKind IK,
                               DiagnosticsEngine &Diags);
 
-unsigned getOptimizationLevelSize(llvm::opt::ArgList &Args);
+unsigned getOptimizationLevelSize(const llvm::opt::ArgList &Args);
 
 /// The base class of CompilerInvocation. It keeps individual option objects
 /// behind reference-counted pointers, which is useful for clients that want to
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index d3539a594df11..882283a99d4f1 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -35,6 +35,7 @@
 #include "clang/Driver/ToolChain.h"
 #include "clang/Driver/Util.h"
 #include "clang/Driver/XRayArgs.h"
+#include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Options/Options.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
@@ -1095,27 +1096,14 @@ void tools::addLTOOptions(const ToolChain &ToolChain, 
const ArgList &Args,
     CmdArgs.push_back(
         Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash + "mcpu=" + 
CPU));
 
-  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
-    // The optimization level matches
-    // CompilerInvocation.cpp:getOptimizationLevel().
-    StringRef OOpt;
-    if (A->getOption().matches(options::OPT_O4) ||
-        A->getOption().matches(options::OPT_Ofast))
-      OOpt = "3";
-    else if (A->getOption().matches(options::OPT_O)) {
-      OOpt = A->getValue();
-      if (OOpt == "g")
-        OOpt = "1";
-      else if (OOpt == "s" || OOpt == "z")
-        OOpt = "2";
-    } else if (A->getOption().matches(options::OPT_O0))
-      OOpt = "0";
-    if (!OOpt.empty()) {
+  if (Args.getLastArg(options::OPT_O_Group)) {
+    unsigned OptimizationLevel =
+        getOptimizationLevel(Args, InputKind(), D.getDiags());
+    CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash +
+                                         "O" + Twine(OptimizationLevel)));
+    if (IsAMDGCN)
       CmdArgs.push_back(
-          Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash + "O" + OOpt));
-      if (IsAMDGCN)
-        CmdArgs.push_back(Args.MakeArgString(Twine("--lto-CGO") + OOpt));
-    }
+          Args.MakeArgString(Twine("--lto-CGO") + Twine(OptimizationLevel)));
   }
 
   if (Args.hasArg(options::OPT_gsplit_dwarf)) {
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index d2a5ed6262de1..b42c263abd2c7 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2669,7 +2669,7 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, 
ArgList &Args,
   return Diags->getNumErrors() == NumErrorsBefore;
 }
 
-unsigned clang::getOptimizationLevel(ArgList &Args, InputKind IK,
+unsigned clang::getOptimizationLevel(const ArgList &Args, InputKind IK,
                                      DiagnosticsEngine &Diags) {
   unsigned DefaultOpt = 0;
   if ((IK.getLanguage() == Language::OpenCL ||
@@ -2708,7 +2708,7 @@ unsigned clang::getOptimizationLevel(ArgList &Args, 
InputKind IK,
   return DefaultOpt;
 }
 
-unsigned clang::getOptimizationLevelSize(ArgList &Args) {
+unsigned clang::getOptimizationLevelSize(const ArgList &Args) {
   if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
     if (A->getOption().matches(options::OPT_O)) {
       switch (A->getValue()[0]) {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to