Author: Chuanqi Xu
Date: 2026-02-12T03:53:56Z
New Revision: 477e73f5347489895d076bfc810a30bf34ec8cd0

URL: 
https://github.com/llvm/llvm-project/commit/477e73f5347489895d076bfc810a30bf34ec8cd0
DIFF: 
https://github.com/llvm/llvm-project/commit/477e73f5347489895d076bfc810a30bf34ec8cd0.diff

LOG: [C++20] [Modules] Support to generate reduced BMI only (#181081)

Introduced --precompile-reduced-bmi. This allows users to generate
Reduced BMI only.
Previously, users can only generate the reduced BMI as a by product of
other process (e.g, generating an object file or a full BMI). This is
not ideal.

Added: 
    clang/test/Driver/module-fgen-reduced-bmi-precompile.cppm

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/docs/StandardCPlusPlusModules.rst
    clang/include/clang/Options/Options.td
    clang/lib/Driver/Driver.cpp
    clang/lib/Driver/ToolChains/Clang.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 982f866e228b6..557e231a938d9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -143,6 +143,10 @@ New Compiler Flags
 - New option ``-fms-anonymous-structs`` / ``-fno-ms-anonymous-structs`` added
   to enable or disable Microsoft's anonymous struct/union extension without
   enabling other ``-fms-extensions`` features (#GH177607).
+- New option ``--precompile-reduced-bmi`` allows build system to generate a
+  reduced BMI only for a C++20 importable module unit. Previously the users
+  can only generate the reduced BMI as a by-product, e.g, an object files or
+  a full BMI.
 
 Deprecated Compiler Flags
 -------------------------

diff  --git a/clang/docs/StandardCPlusPlusModules.rst 
b/clang/docs/StandardCPlusPlusModules.rst
index c714a41d37aff..806bbc45c7f49 100644
--- a/clang/docs/StandardCPlusPlusModules.rst
+++ b/clang/docs/StandardCPlusPlusModules.rst
@@ -208,12 +208,16 @@ is ``-std=c++20`` or newer.
 How to produce a BMI
 ~~~~~~~~~~~~~~~~~~~~
 
-To generate a BMI for an importable module unit, use either the 
``--precompile``
-or ``-fmodule-output`` command line options.
+To generate a BMI for an importable module unit, use either the 
``--precompile``,
+``--precompile-reduced-bmi``, or ``-fmodule-output`` command line options.
 
 The ``--precompile`` option generates the BMI as the output of the compilation
 with the output path specified using the ``-o`` option.
 
+The ``--precompile-reduced-bmi`` option generates a Reduced BMI (See the
+following section for the definition of Reduced BMI) as the output of
+the compilation with the output path specified using the ``-o`` option.
+
 The ``-fmodule-output`` option generates the BMI as a by-product of the
 compilation. If ``-fmodule-output=`` is specified, the BMI will be emitted to
 the specified location. If ``-fmodule-output`` and ``-c`` are specified, the
@@ -604,8 +608,14 @@ unnecessary dependencies for the BMI. To mitigate the 
problem, Clang has a
 compiler option to reduce the information contained in the BMI. These two
 formats are known as Full BMI and Reduced BMI, respectively.
 
-Users can use the ``-fmodules-reduced-bmi`` option to produce a
-Reduced BMI.
+Users can use the ``-fmodules-reduced-bmi`` or ``--precompile-reduced-bmi``
+option to produce a Reduced BMI.
+
+The ``--precompile-reduced-bmi`` option will produce the reduced BMI
+to the location specified by ``-o``.
+
+Note that ``--precompile`` will always generate the full BMI. So that build
+system which may generate the BMI only should take care of this.
 
 For the one-phase compilation model (CMake implements this model), with
 ``-fmodules-reduced-bmi``, the generated BMI will be a Reduced

diff  --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index 5b876db25c544..a274017953b1d 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -6645,6 +6645,9 @@ def _param_EQ : Joined<["--"], "param=">, Alias<_param>;
 def _precompile : Flag<["--"], "precompile">, Flags<[NoXarchOption]>,
   Visibility<[ClangOption, CLOption]>,
   Group<Action_Group>, HelpText<"Only precompile the input">;
+def _precompile_reduced_bmi : Flag<["--"], "precompile-reduced-bmi">, 
Flags<[NoXarchOption]>,
+  Visibility<[ClangOption, CLOption]>,
+  Group<Action_Group>, HelpText<"Only precompile the input as a reduced BMI">;
 def _prefix_EQ : Joined<["--"], "prefix=">, Alias<B>;
 def _prefix : Separate<["--"], "prefix">, Alias<B>;
 def _preprocess : Flag<["--"], "preprocess">, Alias<E>;

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index a55c5033b57cf..d7d744d1770b6 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -342,6 +342,8 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
     // Options that cause the output of C++20 compiled module interfaces or
     // header units have the same effect.
   } else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile)) ||
+             (PhaseArg =
+                  DAL.getLastArg(options::OPT__precompile_reduced_bmi)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_extract_api)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header,
                                         options::OPT_fmodule_header_EQ))) {
@@ -5125,13 +5127,16 @@ Action *Driver::ConstructPhaseAction(
       return C.MakeAction<ExtractAPIJobAction>(Input, types::TY_API_INFO);
 
     // With 'fmodules-reduced-bmi', we don't want to run the
-    // precompile phase unless the user specified '--precompile'. In the case
-    // the '--precompile' flag is enabled, we will try to emit the reduced BMI
-    // as a by product in GenerateModuleInterfaceAction.
+    // precompile phase unless the user specified '--precompile' or
+    // '--precompile-reduced-bmi'. If '--precompile' is specified, we will try
+    // to emit the reduced BMI as a by product in
+    // GenerateModuleInterfaceAction. If '--precompile-reduced-bmi' is
+    // specified, we will generate the reduced BMI directly.
     if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
         (Input->getType() == driver::types::TY_CXXModule ||
          Input->getType() == driver::types::TY_PP_CXXModule) &&
-        !Args.getLastArg(options::OPT__precompile))
+        !Args.getLastArg(options::OPT__precompile) &&
+        !Args.getLastArg(options::OPT__precompile_reduced_bmi))
       return Input;
 
     types::ID OutputTy = getPrecompiledType(Input->getType());

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 9cbee494ea2ed..c16aa33f29ebb 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4036,7 +4036,8 @@ static bool RenderModulesOptions(Compilation &C, const 
Driver &D,
 
     if (Args.hasArg(options::OPT_fmodule_output_EQ))
       Args.AddLastArg(CmdArgs, options::OPT_fmodule_output_EQ);
-    else if (!Args.hasArg(options::OPT__precompile) ||
+    else if (!(Args.hasArg(options::OPT__precompile) ||
+               Args.hasArg(options::OPT__precompile_reduced_bmi)) ||
              Args.hasArg(options::OPT_fmodule_output))
       // If --precompile is specified, we will always generate a module file if
       // we're compiling an importable module unit. This is fine even if the
@@ -5142,9 +5143,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
   } else if (isa<PrecompileJobAction>(JA)) {
     if (JA.getType() == types::TY_Nothing)
       CmdArgs.push_back("-fsyntax-only");
-    else if (JA.getType() == types::TY_ModuleFile)
-      CmdArgs.push_back("-emit-module-interface");
-    else if (JA.getType() == types::TY_HeaderUnit)
+    else if (JA.getType() == types::TY_ModuleFile) {
+      if (Args.hasArg(options::OPT__precompile_reduced_bmi))
+        CmdArgs.push_back("-emit-reduced-module-interface");
+      else
+        CmdArgs.push_back("-emit-module-interface");
+    } else if (JA.getType() == types::TY_HeaderUnit)
       CmdArgs.push_back("-emit-header-unit");
     else if (!Args.hasArg(options::OPT_ignore_pch))
       CmdArgs.push_back("-emit-pch");

diff  --git a/clang/test/Driver/module-fgen-reduced-bmi-precompile.cppm 
b/clang/test/Driver/module-fgen-reduced-bmi-precompile.cppm
new file mode 100644
index 0000000000000..80439c027e93b
--- /dev/null
+++ b/clang/test/Driver/module-fgen-reduced-bmi-precompile.cppm
@@ -0,0 +1,13 @@
+// Test that --precompile-reduced-bmi generates -emit-reduced-module-interface
+// RUN: %clang -std=c++20 %s --precompile-reduced-bmi -### 2>&1 | FileCheck %s 
--check-prefix=CHECK-REDUCED
+//
+// Test that --precompile still generates -emit-module-interface
+// RUN: %clang -std=c++20 %s --precompile -### 2>&1 | FileCheck %s 
--check-prefix=CHECK-FULL
+
+export module Hello;
+
+// CHECK-REDUCED: -emit-reduced-module-interface
+// CHECK-REDUCED-NOT: -emit-module-interface
+
+// CHECK-FULL: -emit-module-interface
+// CHECK-FULL-NOT: -emit-reduced-module-interface


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

Reply via email to