[clang] 255a163 - [C++20] [Modules] Enable reduced BMI by default
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 21 03:58:42 PDT 2025
Author: Chuanqi Xu
Date: 2025-07-21T18:57:38+08:00
New Revision: 255a163e5183082016402ac51db83e10c1f5a731
URL: https://github.com/llvm/llvm-project/commit/255a163e5183082016402ac51db83e10c1f5a731
DIFF: https://github.com/llvm/llvm-project/commit/255a163e5183082016402ac51db83e10c1f5a731.diff
LOG: [C++20] [Modules] Enable reduced BMI by default
As documented in 20.x, we'd like to keep reduced BMI off by default for
1~2 versions. And now we're in 22.x.
I rarely receive bug reports for reduced BMI. I am not sure about the
reason. Maybe not a lot of people are using it. Or it is really stable
enough.
And also, we've been enabling the reduced BMI internally for roughly half a
year.
So I think it's the time to move on. See the document changes for other
information.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/docs/StandardCPlusPlusModules.rst
clang/include/clang/Driver/Options.td
clang/lib/Driver/Driver.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/test/ClangScanDeps/modules-full-named-modules.cppm
clang/test/Driver/module-fgen-reduced-bmi.cppm
clang/test/Driver/module-output.cppm
clang/test/Driver/modules.cpp
clang/test/Modules/mingw-exceptions.cppm
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 46a77673919d3..81483c12c8fe9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -77,6 +77,10 @@ C++ Specific Potentially Breaking Changes
whose nested-name-specifier doesn't refer to a base class such as
``using CurrentClass::Foo;`` is now rejected in C++98 mode.
+- For C++20 modules, the Reduced BMI mode will be the default option. This may introduce
+ regressions if your build system supports two-phase compilation model but haven't support
+ reduced BMI or it is a compiler bug or a bug in users code.
+
ABI Changes in This Version
---------------------------
diff --git a/clang/docs/StandardCPlusPlusModules.rst b/clang/docs/StandardCPlusPlusModules.rst
index 933a57ff34dd9..fdd350857a3f7 100644
--- a/clang/docs/StandardCPlusPlusModules.rst
+++ b/clang/docs/StandardCPlusPlusModules.rst
@@ -687,16 +687,12 @@ fails to instantiate. For such issues, users can add references to ``N::g`` in
the `module purview <https://eel.is/c++draft/module.unit#5>`_ of ``M.cppm`` to
ensure it is reachable, e.g. ``using N::g;``.
-Support for Reduced BMIs is still experimental, but it may become the default
-in the future. The expected roadmap for Reduced BMIs as of Clang 19.x is:
-
-1. ``-fexperimental-modules-reduced-bmi`` was introduced in v19.x
-2. For v20.x, ``-fmodules-reduced-bmi`` is introduced as an equivalent non-experimental
- option. It is expected to stay opt-in for 1~2 releases, though the period depends
- on user feedback and may be extended.
-3. Finally, ``-fmodules-reduced-bmi`` will be the default. When that time
- comes, the term BMI will refer to the Reduced BMI and the Full BMI will only
- be meaningful to build systems which elect to support two-phase compilation.
+As of Clang 22.x, the Reduced BMI is enabled by default. You may still want to
+use Full BMI with ``-fno-modules-reduced-bmi`` in the following case:
+1. Your build system uses two-phase compilation but it haven't adjusted the
+ implementation for reduced BMI.
+2. You meet a regression with Reduced BMI that you cannot work around. Please
+ report an issue for this case.
Experimental Non-Cascading Changes
----------------------------------
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 6c22f06b269fb..8087979b3051a 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3257,13 +3257,14 @@ defm skip_odr_check_in_gmf : BoolOption<"f", "skip-odr-check-in-gmf",
"Perform ODR checks for decls in the global module fragment.">>,
Group<f_Group>;
-def modules_reduced_bmi : Flag<["-"], "fmodules-reduced-bmi">,
- Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
- HelpText<"Generate the reduced BMI">,
- MarshallingInfoFlag<FrontendOpts<"GenReducedBMI">>;
+defm modules_reduced_bmi : BoolOption<"f", "modules-reduced-bmi",
+ FrontendOpts<"GenReducedBMI">, DefaultFalse,
+ NegFlag<SetFalse>,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Generate the reduced BMI">>;
def experimental_modules_reduced_bmi : Flag<["-"], "fexperimental-modules-reduced-bmi">,
- Group<f_Group>, Visibility<[ClangOption, CC1Option]>, Alias<modules_reduced_bmi>;
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>, Alias<fmodules_reduced_bmi>;
def fmodules_embed_all_files : Joined<["-"], "fmodules-embed-all-files">,
Visibility<[ClangOption, CC1Option, CLOption]>,
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index ec1135eecd401..eeb482392ae91 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -5131,11 +5131,13 @@ Action *Driver::ConstructPhaseAction(
if (Args.hasArg(options::OPT_extract_api))
return C.MakeAction<ExtractAPIJobAction>(Input, types::TY_API_INFO);
- // With 'fexperimental-modules-reduced-bmi', we don't want to run the
+ // 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.
- if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
+ 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))
return Input;
@@ -6323,7 +6325,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
// `-fmodule-output`.
if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
JA.getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
- assert(!C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
+ assert(C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
return GetModuleOutputPath(C, JA, BaseInput);
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 241ca6ed5d604..1fc7002a3a186 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4085,31 +4085,34 @@ static bool RenderModulesOptions(Compilation &C, const Driver &D,
// module fragment.
CmdArgs.push_back("-fskip-odr-check-in-gmf");
- if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
+ if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
(Input.getType() == driver::types::TY_CXXModule ||
- Input.getType() == driver::types::TY_PP_CXXModule)) {
+ Input.getType() == driver::types::TY_PP_CXXModule) &&
+ !Args.hasArg(options::OPT__precompile)) {
CmdArgs.push_back("-fmodules-reduced-bmi");
if (Args.hasArg(options::OPT_fmodule_output_EQ))
Args.AddLastArg(CmdArgs, options::OPT_fmodule_output_EQ);
- else {
- if (Args.hasArg(options::OPT__precompile) &&
- (!Args.hasArg(options::OPT_o) ||
- Args.getLastArg(options::OPT_o)->getValue() ==
- getCXX20NamedModuleOutputPath(Args, Input.getBaseInput()))) {
- D.Diag(diag::err_drv_reduced_module_output_overrided);
- }
-
+ else
CmdArgs.push_back(Args.MakeArgString(
"-fmodule-output=" +
getCXX20NamedModuleOutputPath(Args, Input.getBaseInput())));
- }
}
- // Noop if we see '-fmodules-reduced-bmi' with other translation
- // units than module units. This is more user friendly to allow end uers to
- // enable this feature without asking for help from build systems.
- Args.ClaimAllArgs(options::OPT_modules_reduced_bmi);
+ if (Args.hasArg(options::OPT_fmodules_reduced_bmi) &&
+ Args.hasArg(options::OPT__precompile) &&
+ (!Args.hasArg(options::OPT_o) ||
+ Args.getLastArg(options::OPT_o)->getValue() ==
+ getCXX20NamedModuleOutputPath(Args, Input.getBaseInput()))) {
+ D.Diag(diag::err_drv_reduced_module_output_overrided);
+ }
+
+ // Noop if we see '-fmodules-reduced-bmi' or `-fno-modules-reduced-bmi` with
+ // other translation units than module units. This is more user friendly to
+ // allow end uers to enable this feature without asking for help from build
+ // systems.
+ Args.ClaimAllArgs(options::OPT_fmodules_reduced_bmi);
+ Args.ClaimAllArgs(options::OPT_fno_modules_reduced_bmi);
// We need to include the case the input file is a module file here.
// Since the default compilation model for C++ module interface unit will
diff --git a/clang/test/ClangScanDeps/modules-full-named-modules.cppm b/clang/test/ClangScanDeps/modules-full-named-modules.cppm
index 5967a8705c09d..c69a215a62dc1 100644
--- a/clang/test/ClangScanDeps/modules-full-named-modules.cppm
+++ b/clang/test/ClangScanDeps/modules-full-named-modules.cppm
@@ -92,14 +92,7 @@ export void Hello();
// CHECK-NEXT: ]
// CHECK: "command-line": [
// CHECK: "-o",
-// CHECK-NEXT: "{{.*}}/M-{{.*}}.pcm"
-// CHECK: ]
-// CHECK: "input-file": "[[PREFIX]]/M.cppm"
-// CHECK: },
-// CHECK-NEXT: {
-// CHECK: "command-line": [
-// CHECK: "-o",
-// CHECK-NEXT: "[[PREFIX]]/M.o"
+// CHECK-NEXT: "{{.*}}/M.o"
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/M.cppm"
// CHECK: }
@@ -160,18 +153,7 @@ void World() {
// CHECK-NEXT: ]
// CHECK: "command-line": [
// CHECK: "-o",
-// CHECK-NEXT: "{{.*}}/impl_part-{{.*}}.pcm",
-// CHECK: ]
-// CHECK: "input-file": "[[PREFIX]]/impl_part.cppm"
-// CHECK: },
-// CHECK-NEXT: {
-// CHECK: "named-module": "M:impl_part"
-// CHECK-NEXT: "named-module-deps": [
-// CHECK-NEXT: "M:interface_part"
-// CHECK-NEXT: ]
-// CHECK: "command-line": [
-// CHECK: "-o",
-// CHECK-NEXT: "[[PREFIX]]/impl_part.o",
+// CHECK-NEXT: "{{.*}}/impl_part.o",
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/impl_part.cppm"
// CHECK: }
@@ -194,16 +176,7 @@ export void World();
// CHECK-NOT: "named-module-deps": []
// CHECK: "command-line": [
// CHECK: "-o",
-// CHECK-NEXT: "{{.*}}/interface_part-{{.*}}.pcm",
-// CHECK: ]
-// CHECK: "input-file": "[[PREFIX]]/interface_part.cppm"
-// CHECK: },
-// CHECK-NEXT: {
-// CHECK: "named-module": "M:interface_part"
-// CHECK-NOT: "named-module-deps": []
-// CHECK: "command-line": [
-// CHECK: "-o",
-// CHECK-NEXT: "[[PREFIX]]/interface_part.o",
+// CHECK-NEXT: "{{.*}}/interface_part.o",
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/interface_part.cppm"
// CHECK: }
@@ -259,14 +232,7 @@ int main() {
// CHECK-NEXT: ]
// CHECK: "command-line": [
// CHECK: "-o",
-// CHECK-NEXT: "{{.*}}/M-{{.*}}.pcm"
-// CHECK: ]
-// CHECK: "input-file": "[[PREFIX]]/M.cppm"
-// CHECK: },
-// CHECK-NEXT: {
-// CHECK: "command-line": [
-// CHECK: "-o",
-// CHECK-NEXT: "[[PREFIX]]/M.o"
+// CHECK-NEXT: "{{.*}}/M.o"
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/M.cppm"
// CHECK: },
@@ -292,18 +258,7 @@ int main() {
// CHECK-NEXT: ]
// CHECK: "command-line": [
// CHECK: "-o",
-// CHECK-NEXT: "{{.*}}/impl_part-{{.*}}.pcm",
-// CHECK: ]
-// CHECK: "input-file": "[[PREFIX]]/impl_part.cppm"
-// CHECK: },
-// CHECK-NEXT: {
-// CHECK: "named-module": "M:impl_part"
-// CHECK-NEXT: "named-module-deps": [
-// CHECK-NEXT: "M:interface_part"
-// CHECK-NEXT: ]
-// CHECK: "command-line": [
-// CHECK: "-o",
-// CHECK-NEXT: "[[PREFIX]]/impl_part.o",
+// CHECK-NEXT: "{{.*}}/impl_part.o",
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/impl_part.cppm"
// CHECK: }
@@ -316,16 +271,7 @@ int main() {
// CHECK-NOT: "named-module-deps": []
// CHECK: "command-line": [
// CHECK: "-o",
-// CHECK-NEXT: "{{.*}}/interface_part-{{.*}}.pcm",
-// CHECK: ]
-// CHECK: "input-file": "[[PREFIX]]/interface_part.cppm"
-// CHECK: },
-// CHECK-NEXT: {
-// CHECK: "named-module": "M:interface_part"
-// CHECK-NOT: "named-module-deps": []
-// CHECK: "command-line": [
-// CHECK: "-o",
-// CHECK-NEXT: "[[PREFIX]]/interface_part.o",
+// CHECK-NEXT: "{{.*}}/interface_part.o",
// CHECK: ]
// CHECK: "input-file": "[[PREFIX]]/interface_part.cppm"
// CHECK: }
diff --git a/clang/test/Driver/module-fgen-reduced-bmi.cppm b/clang/test/Driver/module-fgen-reduced-bmi.cppm
index 9bdd4c9f6682f..4b893ffbfaae8 100644
--- a/clang/test/Driver/module-fgen-reduced-bmi.cppm
+++ b/clang/test/Driver/module-fgen-reduced-bmi.cppm
@@ -64,7 +64,8 @@
// RUN: -Wno-missing-reduced-bmi -### 2>&1 | FileCheck Hello.cppm -check-prefix=NO_WARN
//
// RUN: %clang -std=c++20 Hello.cppm --precompile -o Hello.pcm \
-// RUN: -Wno-missing-reduced-bmi -### 2>&1 | FileCheck Hello.cppm -check-prefix=NO_WARN
+// RUN: -fno-modules-reduced-bmi -Wno-missing-reduced-bmi -### 2>&1 | \
+// RUN: FileCheck Hello.cppm -check-prefix=NO_WARN
//--- Hello.cppm
export module Hello;
diff --git a/clang/test/Driver/module-output.cppm b/clang/test/Driver/module-output.cppm
index 7cf0771f3d6ef..197f1d85b0f9c 100644
--- a/clang/test/Driver/module-output.cppm
+++ b/clang/test/Driver/module-output.cppm
@@ -13,28 +13,29 @@
// Tests that the .pcm file will be generated in the same directory with the specified
// output and the name of the .pcm file should be the same with the input file.
// RUN: %clang -std=c++20 %t/Hello.cppm -fmodule-output -c -o %t/output/Hello.o \
-// RUN: -### 2>&1 | FileCheck %t/Hello.cppm
+// RUN: -fno-modules-reduced-bmi -### 2>&1 | FileCheck %t/Hello.cppm
//
// Tests that the output file will be generated in the input directory if the output
// file is not the corresponding object file.
// RUN: %clang -std=c++20 %t/Hello.cppm %t/AnotherModule.cppm -fmodule-output -o \
-// RUN: %t/output/a.out -### 2>&1 | FileCheck %t/AnotherModule.cppm
+// RUN: %t/output/a.out -fno-modules-reduced-bmi -### 2>&1 | FileCheck %t/AnotherModule.cppm
//
// Tests that clang will reject the command line if it specifies -fmodule-output with
// multiple archs.
// RUN: not %clang %t/Hello.cppm -fmodule-output -arch i386 -arch x86_64 -### \
-// RUN: --target=x86_64-apple-darwin 2>&1 | FileCheck %t/Hello.cppm -check-prefix=MULTIPLE-ARCH
+// RUN: -fno-modules-reduced-bmi --target=x86_64-apple-darwin 2>&1 | FileCheck %t/Hello.cppm \
+// RUN: -check-prefix=MULTIPLE-ARCH
// Tests that the .pcm file will be generated in the same path with the specified one
// in the comamnd line.
// RUN: %clang -std=c++20 %t/Hello.cppm -fmodule-output=%t/pcm/Hello.pcm -o %t/Hello.o \
-// RUN: -c -### 2>&1 | FileCheck %t/Hello.cppm --check-prefix=CHECK-SPECIFIED
+// RUN: -fno-modules-reduced-bmi -c -### 2>&1 | FileCheck %t/Hello.cppm --check-prefix=CHECK-SPECIFIED
//
// RUN: %clang -std=c++20 %t/Hello.cppm -fmodule-output=%t/Hello.pcm -fmodule-output -c -fsyntax-only \
-// RUN: -### 2>&1 | FileCheck %t/Hello.cppm --check-prefix=CHECK-NOT-USED
+// RUN: -fno-modules-reduced-bmi -### 2>&1 | FileCheck %t/Hello.cppm --check-prefix=CHECK-NOT-USED
// Test that we can emit a warning if the type of the input file is not a module interface unit.
-// RUN: %clang -std=c++20 %t/a.cpp -fmodule-output -c -o %t/a.o -### 2>&1 | FileCheck %t/a.cpp
+// RUN: %clang -std=c++20 %t/a.cpp -fmodule-output -fno-modules-reduced-bmi -c -o %t/a.o -### 2>&1 | FileCheck %t/a.cpp
//--- Hello.cppm
export module Hello;
diff --git a/clang/test/Driver/modules.cpp b/clang/test/Driver/modules.cpp
index 088a73230f81e..edbe8d8e92c85 100644
--- a/clang/test/Driver/modules.cpp
+++ b/clang/test/Driver/modules.cpp
@@ -34,7 +34,7 @@
// Check combining precompile and compile steps works.
//
-// RUN: %clang -std=c++2a -x c++-module %t/foo.cpp -S -o %t/foo2.pcm.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE --check-prefix=CHECK-COMPILE
+// RUN: %clang -std=c++2a -x c++-module -fno-modules-reduced-bmi %t/foo.cpp -S -o %t/foo2.pcm.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE --check-prefix=CHECK-COMPILE
// Check that .cppm is treated as a module implicitly.
//
diff --git a/clang/test/Modules/mingw-exceptions.cppm b/clang/test/Modules/mingw-exceptions.cppm
index db7aa2ce90a94..be9d61d7d3418 100644
--- a/clang/test/Modules/mingw-exceptions.cppm
+++ b/clang/test/Modules/mingw-exceptions.cppm
@@ -1,5 +1,6 @@
// REQUIRES: x86-registered-target
-// RUN: %clang -target x86_64-windows-gnu -x c++-module -std=gnu++23 -c -o /dev/null -Xclang -disable-llvm-passes %s
+// RUN: %clang -target x86_64-windows-gnu -x c++-module -std=gnu++23 -fno-modules-reduced-bmi \
+// RUN: -c -o /dev/null -Xclang -disable-llvm-passes %s
// Make sure the command succeeds and doesn't break on the -exception-model flag in cc1.
export module empty;
More information about the cfe-commits
mailing list