[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.
This commit is contained in:
Chuanqi Xu 2026-02-12 11:53:56 +08:00 committed by GitHub
parent dde762afb9
commit 477e73f534
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 51 additions and 12 deletions

View file

@ -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
-------------------------

View file

@ -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

View file

@ -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>;

View file

@ -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());

View file

@ -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");

View file

@ -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