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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits