Skip to content

Commit 255a163

Browse files
committed
[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.
1 parent fc69f25 commit 255a163

File tree

10 files changed

+57
-102
lines changed

10 files changed

+57
-102
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ C++ Specific Potentially Breaking Changes
7777
whose nested-name-specifier doesn't refer to a base class such as
7878
``using CurrentClass::Foo;`` is now rejected in C++98 mode.
7979

80+
- For C++20 modules, the Reduced BMI mode will be the default option. This may introduce
81+
regressions if your build system supports two-phase compilation model but haven't support
82+
reduced BMI or it is a compiler bug or a bug in users code.
83+
8084
ABI Changes in This Version
8185
---------------------------
8286

clang/docs/StandardCPlusPlusModules.rst

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -687,16 +687,12 @@ fails to instantiate. For such issues, users can add references to ``N::g`` in
687687
the `module purview <https://eel.is/c++draft/module.unit#5>`_ of ``M.cppm`` to
688688
ensure it is reachable, e.g. ``using N::g;``.
689689

690-
Support for Reduced BMIs is still experimental, but it may become the default
691-
in the future. The expected roadmap for Reduced BMIs as of Clang 19.x is:
692-
693-
1. ``-fexperimental-modules-reduced-bmi`` was introduced in v19.x
694-
2. For v20.x, ``-fmodules-reduced-bmi`` is introduced as an equivalent non-experimental
695-
option. It is expected to stay opt-in for 1~2 releases, though the period depends
696-
on user feedback and may be extended.
697-
3. Finally, ``-fmodules-reduced-bmi`` will be the default. When that time
698-
comes, the term BMI will refer to the Reduced BMI and the Full BMI will only
699-
be meaningful to build systems which elect to support two-phase compilation.
690+
As of Clang 22.x, the Reduced BMI is enabled by default. You may still want to
691+
use Full BMI with ``-fno-modules-reduced-bmi`` in the following case:
692+
1. Your build system uses two-phase compilation but it haven't adjusted the
693+
implementation for reduced BMI.
694+
2. You meet a regression with Reduced BMI that you cannot work around. Please
695+
report an issue for this case.
700696

701697
Experimental Non-Cascading Changes
702698
----------------------------------

clang/include/clang/Driver/Options.td

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3257,13 +3257,14 @@ defm skip_odr_check_in_gmf : BoolOption<"f", "skip-odr-check-in-gmf",
32573257
"Perform ODR checks for decls in the global module fragment.">>,
32583258
Group<f_Group>;
32593259

3260-
def modules_reduced_bmi : Flag<["-"], "fmodules-reduced-bmi">,
3261-
Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
3262-
HelpText<"Generate the reduced BMI">,
3263-
MarshallingInfoFlag<FrontendOpts<"GenReducedBMI">>;
3260+
defm modules_reduced_bmi : BoolOption<"f", "modules-reduced-bmi",
3261+
FrontendOpts<"GenReducedBMI">, DefaultFalse,
3262+
NegFlag<SetFalse>,
3263+
PosFlag<SetTrue, [], [ClangOption, CC1Option],
3264+
"Generate the reduced BMI">>;
32643265

32653266
def experimental_modules_reduced_bmi : Flag<["-"], "fexperimental-modules-reduced-bmi">,
3266-
Group<f_Group>, Visibility<[ClangOption, CC1Option]>, Alias<modules_reduced_bmi>;
3267+
Group<f_Group>, Visibility<[ClangOption, CC1Option]>, Alias<fmodules_reduced_bmi>;
32673268

32683269
def fmodules_embed_all_files : Joined<["-"], "fmodules-embed-all-files">,
32693270
Visibility<[ClangOption, CC1Option, CLOption]>,

clang/lib/Driver/Driver.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5131,11 +5131,13 @@ Action *Driver::ConstructPhaseAction(
51315131
if (Args.hasArg(options::OPT_extract_api))
51325132
return C.MakeAction<ExtractAPIJobAction>(Input, types::TY_API_INFO);
51335133

5134-
// With 'fexperimental-modules-reduced-bmi', we don't want to run the
5134+
// With 'fmodules-reduced-bmi', we don't want to run the
51355135
// precompile phase unless the user specified '--precompile'. In the case
51365136
// the '--precompile' flag is enabled, we will try to emit the reduced BMI
51375137
// as a by product in GenerateModuleInterfaceAction.
5138-
if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
5138+
if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
5139+
(Input->getType() == driver::types::TY_CXXModule ||
5140+
Input->getType() == driver::types::TY_PP_CXXModule) &&
51395141
!Args.getLastArg(options::OPT__precompile))
51405142
return Input;
51415143

@@ -6323,7 +6325,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
63236325
// `-fmodule-output`.
63246326
if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
63256327
JA.getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
6326-
assert(!C.getArgs().hasArg(options::OPT_modules_reduced_bmi));
6328+
assert(C.getArgs().hasArg(options::OPT_fno_modules_reduced_bmi));
63276329
return GetModuleOutputPath(C, JA, BaseInput);
63286330
}
63296331

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4085,31 +4085,34 @@ static bool RenderModulesOptions(Compilation &C, const Driver &D,
40854085
// module fragment.
40864086
CmdArgs.push_back("-fskip-odr-check-in-gmf");
40874087

4088-
if (Args.hasArg(options::OPT_modules_reduced_bmi) &&
4088+
if (!Args.hasArg(options::OPT_fno_modules_reduced_bmi) &&
40894089
(Input.getType() == driver::types::TY_CXXModule ||
4090-
Input.getType() == driver::types::TY_PP_CXXModule)) {
4090+
Input.getType() == driver::types::TY_PP_CXXModule) &&
4091+
!Args.hasArg(options::OPT__precompile)) {
40914092
CmdArgs.push_back("-fmodules-reduced-bmi");
40924093

40934094
if (Args.hasArg(options::OPT_fmodule_output_EQ))
40944095
Args.AddLastArg(CmdArgs, options::OPT_fmodule_output_EQ);
4095-
else {
4096-
if (Args.hasArg(options::OPT__precompile) &&
4097-
(!Args.hasArg(options::OPT_o) ||
4098-
Args.getLastArg(options::OPT_o)->getValue() ==
4099-
getCXX20NamedModuleOutputPath(Args, Input.getBaseInput()))) {
4100-
D.Diag(diag::err_drv_reduced_module_output_overrided);
4101-
}
4102-
4096+
else
41034097
CmdArgs.push_back(Args.MakeArgString(
41044098
"-fmodule-output=" +
41054099
getCXX20NamedModuleOutputPath(Args, Input.getBaseInput())));
4106-
}
41074100
}
41084101

4109-
// Noop if we see '-fmodules-reduced-bmi' with other translation
4110-
// units than module units. This is more user friendly to allow end uers to
4111-
// enable this feature without asking for help from build systems.
4112-
Args.ClaimAllArgs(options::OPT_modules_reduced_bmi);
4102+
if (Args.hasArg(options::OPT_fmodules_reduced_bmi) &&
4103+
Args.hasArg(options::OPT__precompile) &&
4104+
(!Args.hasArg(options::OPT_o) ||
4105+
Args.getLastArg(options::OPT_o)->getValue() ==
4106+
getCXX20NamedModuleOutputPath(Args, Input.getBaseInput()))) {
4107+
D.Diag(diag::err_drv_reduced_module_output_overrided);
4108+
}
4109+
4110+
// Noop if we see '-fmodules-reduced-bmi' or `-fno-modules-reduced-bmi` with
4111+
// other translation units than module units. This is more user friendly to
4112+
// allow end uers to enable this feature without asking for help from build
4113+
// systems.
4114+
Args.ClaimAllArgs(options::OPT_fmodules_reduced_bmi);
4115+
Args.ClaimAllArgs(options::OPT_fno_modules_reduced_bmi);
41134116

41144117
// We need to include the case the input file is a module file here.
41154118
// Since the default compilation model for C++ module interface unit will

clang/test/ClangScanDeps/modules-full-named-modules.cppm

Lines changed: 6 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,7 @@ export void Hello();
9292
// CHECK-NEXT: ]
9393
// CHECK: "command-line": [
9494
// CHECK: "-o",
95-
// CHECK-NEXT: "{{.*}}/M-{{.*}}.pcm"
96-
// CHECK: ]
97-
// CHECK: "input-file": "[[PREFIX]]/M.cppm"
98-
// CHECK: },
99-
// CHECK-NEXT: {
100-
// CHECK: "command-line": [
101-
// CHECK: "-o",
102-
// CHECK-NEXT: "[[PREFIX]]/M.o"
95+
// CHECK-NEXT: "{{.*}}/M.o"
10396
// CHECK: ]
10497
// CHECK: "input-file": "[[PREFIX]]/M.cppm"
10598
// CHECK: }
@@ -160,18 +153,7 @@ void World() {
160153
// CHECK-NEXT: ]
161154
// CHECK: "command-line": [
162155
// CHECK: "-o",
163-
// CHECK-NEXT: "{{.*}}/impl_part-{{.*}}.pcm",
164-
// CHECK: ]
165-
// CHECK: "input-file": "[[PREFIX]]/impl_part.cppm"
166-
// CHECK: },
167-
// CHECK-NEXT: {
168-
// CHECK: "named-module": "M:impl_part"
169-
// CHECK-NEXT: "named-module-deps": [
170-
// CHECK-NEXT: "M:interface_part"
171-
// CHECK-NEXT: ]
172-
// CHECK: "command-line": [
173-
// CHECK: "-o",
174-
// CHECK-NEXT: "[[PREFIX]]/impl_part.o",
156+
// CHECK-NEXT: "{{.*}}/impl_part.o",
175157
// CHECK: ]
176158
// CHECK: "input-file": "[[PREFIX]]/impl_part.cppm"
177159
// CHECK: }
@@ -194,16 +176,7 @@ export void World();
194176
// CHECK-NOT: "named-module-deps": []
195177
// CHECK: "command-line": [
196178
// CHECK: "-o",
197-
// CHECK-NEXT: "{{.*}}/interface_part-{{.*}}.pcm",
198-
// CHECK: ]
199-
// CHECK: "input-file": "[[PREFIX]]/interface_part.cppm"
200-
// CHECK: },
201-
// CHECK-NEXT: {
202-
// CHECK: "named-module": "M:interface_part"
203-
// CHECK-NOT: "named-module-deps": []
204-
// CHECK: "command-line": [
205-
// CHECK: "-o",
206-
// CHECK-NEXT: "[[PREFIX]]/interface_part.o",
179+
// CHECK-NEXT: "{{.*}}/interface_part.o",
207180
// CHECK: ]
208181
// CHECK: "input-file": "[[PREFIX]]/interface_part.cppm"
209182
// CHECK: }
@@ -259,14 +232,7 @@ int main() {
259232
// CHECK-NEXT: ]
260233
// CHECK: "command-line": [
261234
// CHECK: "-o",
262-
// CHECK-NEXT: "{{.*}}/M-{{.*}}.pcm"
263-
// CHECK: ]
264-
// CHECK: "input-file": "[[PREFIX]]/M.cppm"
265-
// CHECK: },
266-
// CHECK-NEXT: {
267-
// CHECK: "command-line": [
268-
// CHECK: "-o",
269-
// CHECK-NEXT: "[[PREFIX]]/M.o"
235+
// CHECK-NEXT: "{{.*}}/M.o"
270236
// CHECK: ]
271237
// CHECK: "input-file": "[[PREFIX]]/M.cppm"
272238
// CHECK: },
@@ -292,18 +258,7 @@ int main() {
292258
// CHECK-NEXT: ]
293259
// CHECK: "command-line": [
294260
// CHECK: "-o",
295-
// CHECK-NEXT: "{{.*}}/impl_part-{{.*}}.pcm",
296-
// CHECK: ]
297-
// CHECK: "input-file": "[[PREFIX]]/impl_part.cppm"
298-
// CHECK: },
299-
// CHECK-NEXT: {
300-
// CHECK: "named-module": "M:impl_part"
301-
// CHECK-NEXT: "named-module-deps": [
302-
// CHECK-NEXT: "M:interface_part"
303-
// CHECK-NEXT: ]
304-
// CHECK: "command-line": [
305-
// CHECK: "-o",
306-
// CHECK-NEXT: "[[PREFIX]]/impl_part.o",
261+
// CHECK-NEXT: "{{.*}}/impl_part.o",
307262
// CHECK: ]
308263
// CHECK: "input-file": "[[PREFIX]]/impl_part.cppm"
309264
// CHECK: }
@@ -316,16 +271,7 @@ int main() {
316271
// CHECK-NOT: "named-module-deps": []
317272
// CHECK: "command-line": [
318273
// CHECK: "-o",
319-
// CHECK-NEXT: "{{.*}}/interface_part-{{.*}}.pcm",
320-
// CHECK: ]
321-
// CHECK: "input-file": "[[PREFIX]]/interface_part.cppm"
322-
// CHECK: },
323-
// CHECK-NEXT: {
324-
// CHECK: "named-module": "M:interface_part"
325-
// CHECK-NOT: "named-module-deps": []
326-
// CHECK: "command-line": [
327-
// CHECK: "-o",
328-
// CHECK-NEXT: "[[PREFIX]]/interface_part.o",
274+
// CHECK-NEXT: "{{.*}}/interface_part.o",
329275
// CHECK: ]
330276
// CHECK: "input-file": "[[PREFIX]]/interface_part.cppm"
331277
// CHECK: }

clang/test/Driver/module-fgen-reduced-bmi.cppm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@
6464
// RUN: -Wno-missing-reduced-bmi -### 2>&1 | FileCheck Hello.cppm -check-prefix=NO_WARN
6565
//
6666
// RUN: %clang -std=c++20 Hello.cppm --precompile -o Hello.pcm \
67-
// RUN: -Wno-missing-reduced-bmi -### 2>&1 | FileCheck Hello.cppm -check-prefix=NO_WARN
67+
// RUN: -fno-modules-reduced-bmi -Wno-missing-reduced-bmi -### 2>&1 | \
68+
// RUN: FileCheck Hello.cppm -check-prefix=NO_WARN
6869

6970
//--- Hello.cppm
7071
export module Hello;

clang/test/Driver/module-output.cppm

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,29 @@
1313
// Tests that the .pcm file will be generated in the same directory with the specified
1414
// output and the name of the .pcm file should be the same with the input file.
1515
// RUN: %clang -std=c++20 %t/Hello.cppm -fmodule-output -c -o %t/output/Hello.o \
16-
// RUN: -### 2>&1 | FileCheck %t/Hello.cppm
16+
// RUN: -fno-modules-reduced-bmi -### 2>&1 | FileCheck %t/Hello.cppm
1717
//
1818
// Tests that the output file will be generated in the input directory if the output
1919
// file is not the corresponding object file.
2020
// RUN: %clang -std=c++20 %t/Hello.cppm %t/AnotherModule.cppm -fmodule-output -o \
21-
// RUN: %t/output/a.out -### 2>&1 | FileCheck %t/AnotherModule.cppm
21+
// RUN: %t/output/a.out -fno-modules-reduced-bmi -### 2>&1 | FileCheck %t/AnotherModule.cppm
2222
//
2323
// Tests that clang will reject the command line if it specifies -fmodule-output with
2424
// multiple archs.
2525
// RUN: not %clang %t/Hello.cppm -fmodule-output -arch i386 -arch x86_64 -### \
26-
// RUN: --target=x86_64-apple-darwin 2>&1 | FileCheck %t/Hello.cppm -check-prefix=MULTIPLE-ARCH
26+
// RUN: -fno-modules-reduced-bmi --target=x86_64-apple-darwin 2>&1 | FileCheck %t/Hello.cppm \
27+
// RUN: -check-prefix=MULTIPLE-ARCH
2728

2829
// Tests that the .pcm file will be generated in the same path with the specified one
2930
// in the comamnd line.
3031
// RUN: %clang -std=c++20 %t/Hello.cppm -fmodule-output=%t/pcm/Hello.pcm -o %t/Hello.o \
31-
// RUN: -c -### 2>&1 | FileCheck %t/Hello.cppm --check-prefix=CHECK-SPECIFIED
32+
// RUN: -fno-modules-reduced-bmi -c -### 2>&1 | FileCheck %t/Hello.cppm --check-prefix=CHECK-SPECIFIED
3233
//
3334
// RUN: %clang -std=c++20 %t/Hello.cppm -fmodule-output=%t/Hello.pcm -fmodule-output -c -fsyntax-only \
34-
// RUN: -### 2>&1 | FileCheck %t/Hello.cppm --check-prefix=CHECK-NOT-USED
35+
// RUN: -fno-modules-reduced-bmi -### 2>&1 | FileCheck %t/Hello.cppm --check-prefix=CHECK-NOT-USED
3536

3637
// Test that we can emit a warning if the type of the input file is not a module interface unit.
37-
// RUN: %clang -std=c++20 %t/a.cpp -fmodule-output -c -o %t/a.o -### 2>&1 | FileCheck %t/a.cpp
38+
// 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
3839

3940
//--- Hello.cppm
4041
export module Hello;

clang/test/Driver/modules.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
// Check combining precompile and compile steps works.
3636
//
37-
// 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
37+
// 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
3838

3939
// Check that .cppm is treated as a module implicitly.
4040
//
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// REQUIRES: x86-registered-target
2-
// RUN: %clang -target x86_64-windows-gnu -x c++-module -std=gnu++23 -c -o /dev/null -Xclang -disable-llvm-passes %s
2+
// RUN: %clang -target x86_64-windows-gnu -x c++-module -std=gnu++23 -fno-modules-reduced-bmi \
3+
// RUN: -c -o /dev/null -Xclang -disable-llvm-passes %s
34

45
// Make sure the command succeeds and doesn't break on the -exception-model flag in cc1.
56
export module empty;

0 commit comments

Comments
 (0)