Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[C++20] [Modules] Introduce -fexperimental-modules-reduced-bmi #85050

Merged
merged 1 commit into from
Apr 15, 2024

Conversation

ChuanqiXu9
Copy link
Member

@ChuanqiXu9 ChuanqiXu9 commented Mar 13, 2024

This is the driver part of #75894.

This patch introduces '-fexperimental-modules-reduced-bmi' to enable generating the reduced BMI.

This patch did:

  • When -fexperimental-modules-reduced-bmi is specified but --precompile is not specified for a module unit, we'll skip the precompile phase to avoid unnecessary two-phase compilation phases. Then if -c is specified, we will generate the reduced BMI in CodeGenAction as a by-product.
  • When -fexperimental-modules-reduced-bmi is specified and --precompile is specified, we will generate the reduced BMI in GenerateModuleInterfaceAction as a by-product.
  • When -fexperimental-modules-reduced-bmi is specified for a non-module unit. We don't do anything nor try to give a warn. This is more user friendly so that the end users can try to test and experiment with the feature without asking help from the build systems.

The core design idea is that users should be able to enable this easily with the existing cmake mechanisms.

The future plan for the flag is:

  • Add this to clang19 and make it opt-in for 1~2 releases. It depends on the testing feedback to decide how long we like to make it opt-in.
  • Then we can announce the existing BMI generating may be deprecated and suggesting people (end users or build systems) to enable this for 1~2 releases.
  • Finally we will enable this by default. When that time comes, the term BMI will refer to the reduced BMI today and the existing BMI will only be meaningful to build systems which loves to support two phase compilations.

I'll send release notes and document in seperate commits after this get landed.

@ChuanqiXu9 ChuanqiXu9 self-assigned this Mar 13, 2024
@ChuanqiXu9 ChuanqiXu9 added the clang:modules C++20 modules and Clang Header Modules label Mar 13, 2024
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:codegen labels Mar 13, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Mar 13, 2024

@llvm/pr-subscribers-clang
@llvm/pr-subscribers-clang-modules
@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang-driver

Author: Chuanqi Xu (ChuanqiXu9)

Changes

This is the driver part of #75894.

This patch introduces '-fgen-reduced-bmi' to enable generating the reduced BMI.

This patch did:

  • When -fgen-reduced-bmi is specified but --precompile is not specified for a module unit, we'll skip the precompile phase to avoid unnecessary two-phase compilation phases. Then if -c is specified, we will generate the reduced BMI in CodeGenAction as a by-product.
  • When -fgen-reduced-bmi is specified and --precompile is specified, we will generate the reduced BMI in GenerateModuleInterfaceAction as a by-product.
  • When -fgen-reduced-bmi is specified for a non-module unit. We don't do anything nor try to give a warn. This is more user friendly so that the end users can try to test and experiment with the feature without asking help from the build systems.

The core design idea is that users should be able to enable this easily with the existing cmake mechanisms.

The future plan for the flag is:

  • Add this to clang19 and make it opt-in for 1~2 releases. It depends on the testing feedback to decide how long we like to make it opt-in.
  • Then we can announce the existing BMI generating may be deprecated and suggesting people (end users or build systems) to enable this for 1~2 releases.
  • Finally we will enable this by default. When that time comes, the term BMI will refer to the reduced BMI today and the existing BMI will only be meaningful to build systems which loves to support two phase compilations.

I'll send release notes and document in seperate commits after this get landed.


Patch is 20.38 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/85050.diff

13 Files Affected:

  • (modified) clang/include/clang/CodeGen/CodeGenAction.h (+2)
  • (modified) clang/include/clang/Driver/Options.td (+6)
  • (modified) clang/include/clang/Frontend/FrontendOptions.h (+8-1)
  • (modified) clang/include/clang/Serialization/ASTWriter.h (+4-3)
  • (modified) clang/lib/CodeGen/CodeGenAction.cpp (+19)
  • (modified) clang/lib/Driver/Driver.cpp (+13-14)
  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+38-3)
  • (modified) clang/lib/Driver/ToolChains/Clang.h (+14)
  • (modified) clang/lib/Frontend/FrontendActions.cpp (+7)
  • (modified) clang/lib/Frontend/PrecompiledPreamble.cpp (+1-2)
  • (modified) clang/lib/Serialization/GeneratePCH.cpp (+19-4)
  • (added) clang/test/Driver/module-fgen-reduced-bmi.cppm (+53)
  • (added) clang/test/Modules/gen-reduced-bmi.cppm (+36)
diff --git a/clang/include/clang/CodeGen/CodeGenAction.h b/clang/include/clang/CodeGen/CodeGenAction.h
index 7ad2988e589eb2..186dbb43f01ef7 100644
--- a/clang/include/clang/CodeGen/CodeGenAction.h
+++ b/clang/include/clang/CodeGen/CodeGenAction.h
@@ -57,6 +57,8 @@ class CodeGenAction : public ASTFrontendAction {
   bool loadLinkModules(CompilerInstance &CI);
 
 protected:
+  bool BeginSourceFileAction(CompilerInstance &CI) override;
+
   /// Create a new code generation action.  If the optional \p _VMContext
   /// parameter is supplied, the action uses it without taking ownership,
   /// otherwise it creates a fresh LLVM context and takes ownership.
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index aca8c9b0d5487a..b8ceeff9362df9 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3018,6 +3018,7 @@ defm prebuilt_implicit_modules : BoolFOption<"prebuilt-implicit-modules",
 
 def fmodule_output_EQ : Joined<["-"], "fmodule-output=">,
   Flags<[NoXarchOption]>, Visibility<[ClangOption, CC1Option]>,
+  MarshallingInfoString<FrontendOpts<"ModuleOutputPath">>,
   HelpText<"Save intermediate module file results when compiling a standard C++ module unit.">;
 def fmodule_output : Flag<["-"], "fmodule-output">, Flags<[NoXarchOption]>,
   Visibility<[ClangOption, CC1Option]>,
@@ -3031,6 +3032,11 @@ 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 gen_reduced_bmi : Flag<["-"], "fgen-reduced-bmi">,
+  Group<i_Group>, Visibility<[ClangOption, CC1Option]>,
+  HelpText<"Generate the reduced BMI">,
+  MarshallingInfoFlag<FrontendOpts<"GenReducedBMI">>;
+
 def fmodules_prune_interval : Joined<["-"], "fmodules-prune-interval=">, Group<i_Group>,
   Visibility<[ClangOption, CC1Option]>, MetaVarName<"<seconds>">,
   HelpText<"Specify the interval (in seconds) between attempts to prune the module cache">,
diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h
index 8085dbcbf671a6..ddfd4f30d1b773 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -387,6 +387,10 @@ class FrontendOptions {
   LLVM_PREFERRED_TYPE(bool)
   unsigned ModulesShareFileManager : 1;
 
+  /// Whether to generate reduced BMI for C++20 named modules.
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned GenReducedBMI : 1;
+
   CodeCompleteOptions CodeCompleteOpts;
 
   /// Specifies the output format of the AST.
@@ -553,6 +557,9 @@ class FrontendOptions {
   /// Path which stores the output files for -ftime-trace
   std::string TimeTracePath;
 
+  /// Output Path for module output file.
+  std::string ModuleOutputPath;
+
 public:
   FrontendOptions()
       : DisableFree(false), RelocatablePCH(false), ShowHelp(false),
@@ -565,7 +572,7 @@ class FrontendOptions {
         BuildingImplicitModuleUsesLock(true), ModulesEmbedAllFiles(false),
         IncludeTimestamps(true), UseTemporary(true),
         AllowPCMWithCompilerErrors(false), ModulesShareFileManager(true),
-        TimeTraceGranularity(500) {}
+        GenReducedBMI(false), TimeTraceGranularity(500) {}
 
   /// getInputKindForExtension - Return the appropriate input kind for a file
   /// extension. For example, "c" would return Language::C.
diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h
index 3ed9803fa3745b..bd310b6c7a5cdd 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -846,7 +846,7 @@ class ASTWriter : public ASTDeserializationListener,
 /// AST and semantic-analysis consumer that generates a
 /// precompiled header from the parsed source code.
 class PCHGenerator : public SemaConsumer {
-  const Preprocessor &PP;
+  Preprocessor &PP;
   std::string OutputFile;
   std::string isysroot;
   Sema *SemaPtr;
@@ -867,11 +867,12 @@ class PCHGenerator : public SemaConsumer {
   DiagnosticsEngine &getDiagnostics() const {
     return SemaPtr->getDiagnostics();
   }
+  Preprocessor &getPreprocessor() { return PP; }
 
   virtual Module *getEmittingModule(ASTContext &Ctx);
 
 public:
-  PCHGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache,
+  PCHGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
                StringRef OutputFile, StringRef isysroot,
                std::shared_ptr<PCHBuffer> Buffer,
                ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
@@ -893,7 +894,7 @@ class ReducedBMIGenerator : public PCHGenerator {
   virtual Module *getEmittingModule(ASTContext &Ctx) override;
 
 public:
-  ReducedBMIGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache,
+  ReducedBMIGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
                       StringRef OutputFile);
 
   void HandleTranslationUnit(ASTContext &Ctx) override;
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index bb9aaba025fa59..3737c99847f04f 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -25,8 +25,11 @@
 #include "clang/CodeGen/ModuleBuilder.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Serialization/ASTWriter.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
@@ -1003,6 +1006,12 @@ CodeGenerator *CodeGenAction::getCodeGenerator() const {
   return BEConsumer->getCodeGenerator();
 }
 
+bool CodeGenAction::BeginSourceFileAction(CompilerInstance &CI) {
+  if (CI.getFrontendOpts().GenReducedBMI)
+    CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface);
+  return true;
+}
+
 static std::unique_ptr<raw_pwrite_stream>
 GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {
   switch (Action) {
@@ -1061,6 +1070,16 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
     CI.getPreprocessor().addPPCallbacks(std::move(Callbacks));
   }
 
+  if (CI.getFrontendOpts().GenReducedBMI &&
+      !CI.getFrontendOpts().ModuleOutputPath.empty()) {
+    std::vector<std::unique_ptr<ASTConsumer>> Consumers{2};
+    Consumers[0] = std::move(Result);
+    Consumers[1] = std::make_unique<ReducedBMIGenerator>(
+        CI.getPreprocessor(), CI.getModuleCache(),
+        CI.getFrontendOpts().ModuleOutputPath);
+    return std::make_unique<MultiplexConsumer>(std::move(Consumers));
+  }
+
   return std::move(Result);
 }
 
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 190782a79a2456..872ea905f01a03 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -4737,6 +4737,14 @@ Action *Driver::ConstructPhaseAction(
     if (Args.hasArg(options::OPT_extract_api))
       return C.MakeAction<ExtractAPIJobAction>(Input, types::TY_API_INFO);
 
+    // With '-fgen-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_gen_reduced_bmi) &&
+        !Args.getLastArg(options::OPT__precompile))
+      return Input;
+
     types::ID OutputTy = getPrecompiledType(Input->getType());
     assert(OutputTy != types::TY_INVALID &&
            "Cannot precompile this input type!");
@@ -5802,19 +5810,8 @@ static const char *GetModuleOutputPath(Compilation &C, const JobAction &JA,
          (C.getArgs().hasArg(options::OPT_fmodule_output) ||
           C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
 
-  if (Arg *ModuleOutputEQ =
-          C.getArgs().getLastArg(options::OPT_fmodule_output_EQ))
-    return C.addResultFile(ModuleOutputEQ->getValue(), &JA);
-
-  SmallString<64> OutputPath;
-  Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);
-  if (FinalOutput && C.getArgs().hasArg(options::OPT_c))
-    OutputPath = FinalOutput->getValue();
-  else
-    OutputPath = BaseInput;
-
-  const char *Extension = types::getTypeTempSuffix(JA.getType());
-  llvm::sys::path::replace_extension(OutputPath, Extension);
+  SmallString<256> OutputPath =
+      tools::getCXX20NamedModuleOutputPath(C.getArgs(), BaseInput);
   return C.addResultFile(C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
 }
 
@@ -5901,8 +5898,10 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
   // If we're emitting a module output with the specified option
   // `-fmodule-output`.
   if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
-      JA.getType() == types::TY_ModuleFile && SpecifiedModuleOutput)
+      JA.getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
+    assert(!C.getArgs().hasArg(options::OPT_gen_reduced_bmi));
     return GetModuleOutputPath(C, JA, BaseInput);
+  }
 
   // Output to a temporary file?
   if ((!AtTopLevel && !isSaveTempsEnabled() &&
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 3a7a1cf99c79ac..7877c1d873bb04 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3777,6 +3777,24 @@ bool Driver::getDefaultModuleCachePath(SmallVectorImpl<char> &Result) {
   return false;
 }
 
+llvm::SmallString<256>
+clang::driver::tools::getCXX20NamedModuleOutputPath(const ArgList &Args,
+                                                    const char *BaseInput) {
+  if (Arg *ModuleOutputEQ = Args.getLastArg(options::OPT_fmodule_output_EQ))
+    return StringRef(ModuleOutputEQ->getValue());
+
+  SmallString<256> OutputPath;
+  if (Arg *FinalOutput = Args.getLastArg(options::OPT_o);
+      FinalOutput && Args.hasArg(options::OPT_c))
+    OutputPath = FinalOutput->getValue();
+  else
+    OutputPath = BaseInput;
+
+  const char *Extension = types::getTypeTempSuffix(types::TY_ModuleFile);
+  llvm::sys::path::replace_extension(OutputPath, Extension);
+  return OutputPath;
+}
+
 static bool RenderModulesOptions(Compilation &C, const Driver &D,
                                  const ArgList &Args, const InputInfo &Input,
                                  const InputInfo &Output, bool HaveStd20,
@@ -3965,9 +3983,26 @@ static bool RenderModulesOptions(Compilation &C, const Driver &D,
   // module fragment.
   CmdArgs.push_back("-fskip-odr-check-in-gmf");
 
-  // Claim `-fmodule-output` and `-fmodule-output=` to avoid unused warnings.
-  Args.ClaimAllArgs(options::OPT_fmodule_output);
-  Args.ClaimAllArgs(options::OPT_fmodule_output_EQ);
+  // Noop if we see '-fgen-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.
+  if (Args.hasArg(options::OPT_gen_reduced_bmi) &&
+      (Input.getType() == driver::types::TY_CXXModule ||
+       Input.getType() == driver::types::TY_PP_CXXModule)) {
+    CmdArgs.push_back("-fgen-reduced-bmi");
+
+    if (Args.hasArg(options::OPT_fmodule_output_EQ))
+      Args.AddLastArg(CmdArgs, options::OPT_fmodule_output_EQ);
+    else
+      CmdArgs.push_back(Args.MakeArgString(
+          "-fmodule-output=" +
+          getCXX20NamedModuleOutputPath(Args, Input.getBaseInput())));
+  } else {
+    // To avoid unused warnings.
+    Args.ClaimAllArgs(options::OPT_gen_reduced_bmi);
+    Args.ClaimAllArgs(options::OPT_fmodule_output);
+    Args.ClaimAllArgs(options::OPT_fmodule_output_EQ);
+  }
 
   return HaveModules;
 }
diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h
index 0f503c4bd1c4fe..3b2639b4cc49f4 100644
--- a/clang/lib/Driver/ToolChains/Clang.h
+++ b/clang/lib/Driver/ToolChains/Clang.h
@@ -193,6 +193,20 @@ DwarfFissionKind getDebugFissionKind(const Driver &D,
                                      const llvm::opt::ArgList &Args,
                                      llvm::opt::Arg *&Arg);
 
+// Calculate the output path of the module file when compiling a module unit
+// with the `-fmodule-output` option or `-fmodule-output=` option specified.
+// The behavior is:
+// - If `-fmodule-output=` is specfied, then the module file is
+//   writing to the value.
+// - Otherwise if the output object file of the module unit is specified, the
+// output path
+//   of the module file should be the same with the output object file except
+//   the corresponding suffix. This requires both `-o` and `-c` are specified.
+// - Otherwise, the output path of the module file will be the same with the
+//   input with the corresponding suffix.
+llvm::SmallString<256>
+getCXX20NamedModuleOutputPath(const llvm::opt::ArgList &Args,
+                              const char *BaseInput);
 } // end namespace tools
 
 } // end namespace driver
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 81fcd8d5ae9bd3..7f1052c165d124 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -281,6 +281,13 @@ GenerateModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI,
   if (Consumers.empty())
     return nullptr;
 
+  if (CI.getFrontendOpts().GenReducedBMI &&
+      !CI.getFrontendOpts().ModuleOutputPath.empty()) {
+    Consumers.push_back(std::make_unique<ReducedBMIGenerator>(
+        CI.getPreprocessor(), CI.getModuleCache(),
+        CI.getFrontendOpts().ModuleOutputPath));
+  }
+
   return std::make_unique<MultiplexConsumer>(std::move(Consumers));
 }
 
diff --git a/clang/lib/Frontend/PrecompiledPreamble.cpp b/clang/lib/Frontend/PrecompiledPreamble.cpp
index 9b0ef30a14121b..fdf05c3613c956 100644
--- a/clang/lib/Frontend/PrecompiledPreamble.cpp
+++ b/clang/lib/Frontend/PrecompiledPreamble.cpp
@@ -290,8 +290,7 @@ class PrecompilePreambleAction : public ASTFrontendAction {
 
 class PrecompilePreambleConsumer : public PCHGenerator {
 public:
-  PrecompilePreambleConsumer(PrecompilePreambleAction &Action,
-                             const Preprocessor &PP,
+  PrecompilePreambleConsumer(PrecompilePreambleAction &Action, Preprocessor &PP,
                              InMemoryModuleCache &ModuleCache,
                              StringRef isysroot,
                              std::shared_ptr<PCHBuffer> Buffer)
diff --git a/clang/lib/Serialization/GeneratePCH.cpp b/clang/lib/Serialization/GeneratePCH.cpp
index f54db36d4a0199..4260ba867ad28b 100644
--- a/clang/lib/Serialization/GeneratePCH.cpp
+++ b/clang/lib/Serialization/GeneratePCH.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/HeaderSearchOptions.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/SemaConsumer.h"
 #include "clang/Serialization/ASTReader.h"
@@ -23,8 +24,8 @@
 using namespace clang;
 
 PCHGenerator::PCHGenerator(
-    const Preprocessor &PP, InMemoryModuleCache &ModuleCache,
-    StringRef OutputFile, StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
+    Preprocessor &PP, InMemoryModuleCache &ModuleCache, StringRef OutputFile,
+    StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
     ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
     bool AllowASTWithErrors, bool IncludeTimestamps,
     bool BuildingImplicitModule, bool ShouldCacheASTInMemory,
@@ -88,7 +89,7 @@ ASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() {
   return &Writer;
 }
 
-ReducedBMIGenerator::ReducedBMIGenerator(const Preprocessor &PP,
+ReducedBMIGenerator::ReducedBMIGenerator(Preprocessor &PP,
                                          InMemoryModuleCache &ModuleCache,
                                          StringRef OutputFile)
     : PCHGenerator(
@@ -101,12 +102,26 @@ ReducedBMIGenerator::ReducedBMIGenerator(const Preprocessor &PP,
 
 Module *ReducedBMIGenerator::getEmittingModule(ASTContext &Ctx) {
   Module *M = Ctx.getCurrentNamedModule();
-  assert(M->isNamedModuleUnit() &&
+  assert(M && M->isNamedModuleUnit() &&
          "ReducedBMIGenerator should only be used with C++20 Named modules.");
   return M;
 }
 
 void ReducedBMIGenerator::HandleTranslationUnit(ASTContext &Ctx) {
+  // FIMXE: We'd better to wrap such options to a new class ASTWriterOptions.
+  getPreprocessor()
+      .getHeaderSearchInfo()
+      .getHeaderSearchOpts()
+      .ModulesSkipDiagnosticOptions = true;
+  getPreprocessor()
+      .getHeaderSearchInfo()
+      .getHeaderSearchOpts()
+      .ModulesSkipHeaderSearchPaths = true;
+  getPreprocessor()
+      .getHeaderSearchInfo()
+      .getHeaderSearchOpts()
+      .ModulesSkipPragmaDiagnosticMappings = true;
+
   PCHGenerator::HandleTranslationUnit(Ctx);
 
   if (!isComplete())
diff --git a/clang/test/Driver/module-fgen-reduced-bmi.cppm b/clang/test/Driver/module-fgen-reduced-bmi.cppm
new file mode 100644
index 00000000000000..77afdf3e74e505
--- /dev/null
+++ b/clang/test/Driver/module-fgen-reduced-bmi.cppm
@@ -0,0 +1,53 @@
+// It is annoying to handle different slash direction
+// in Windows and Linux. So we disable the test on Windows
+// here.
+// REQUIRES: !system-windows
+// On AIX, the default output for `-c` may be `.s` instead of `.o`,
+// which makes the test fail. So disable the test on AIX.
+// REQUIRES: !system-aix
+//
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: split-file %s %t
+//
+// RUN: %clang -std=c++20 %t/Hello.cppm -fmodule-output=%t/Hello.pcm \
+// RUN:     -fgen-reduced-bmi -c -o %t/Hello.o -### 2>&1 | FileCheck %t/Hello.cppm
+//
+// RUN: %clang -std=c++20 %t/Hello.cppm \
+// RUN:     -fgen-reduced-bmi -c -o %t/Hello.o -### 2>&1 | \
+// RUN:         FileCheck %t/Hello.cppm --check-prefix=CHECK-UNSPECIFIED
+//
+// RUN: %clang -std=c++20 %t/Hello.cppm \
+// RUN:     -fgen-reduced-bmi -c -### 2>&1 | \
+// RUN:         FileCheck %t/Hello.cppm --check-prefix=CHECK-NO-O
+//
+// RUN: %clang -std=c++20 %t/Hello.cppm \
+// RUN:     -fgen-reduced-bmi -c -o %t/AnotherName.o -### 2>&1 | \
+// RUN:         FileCheck %t/Hello.cppm --check-prefix=CHECK-ANOTHER-NAME
+//
+// RUN: %clang -std=c++20 %t/Hello.cppm --precompile -fgen-reduced-bmi \
+// RUN:     -o %t/Hello.full.pcm -### 2>&1 | FileCheck %t/Hello.cppm \
+// RUN:     --check-prefix=CHECK-EMIT-MODULE-INTERFACE
+//
+// RUN: %clang -std=c++20 %t/Hello.cc -fgen-reduced-bmi -Wall -Werror \
+// RUN:     -c -o %t/Hello.o -### 2>&1 | FileCheck %t/Hello.cc
+
+//--- Hello.cppm
+export module Hello;
+
+// Test that we won't generate the emit-module-interface as 2 phase compilation model.
+// CHECK-NOT: -emit-module-interface
+// CHECK: "-fgen-reduced-bmi"
+
+// CHECK-UNSPECIFIED: -fmodule-output={{.*}}/Hello.pcm
+
+// CHECK-NO-O: -fmodule-output={{.*}}/Hello.pcm
+// CHECK-ANOTHER-NAME: -fmodule-output={{.*}}/AnotherName.pcm
+
+// With `-emit-module-interface` specified, we should still see the `-emit-module-interface`
+// flag.
+// CHECK-EMIT-MODULE-INTERFACE: -emit-module-interface
+
+//--- Hello.cc
+
+// CHECK-NOT: "-fgen-reduced-bmi"
diff --git a/clang/test/Modules/gen-reduced-bmi.cppm b/clang/test/Modules/gen-reduced-bmi.cppm
new file mode 100644
index 00000000000000..8c08795ce4e453
--- /dev/null
+++ b/clang/test/Modules/gen-reduced-bmi.cppm
@@ -0,0 +1,36 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-reduced-module-interface -o %t/a.reduced.pcm
+// RUN: %clang_cc1 -std=c++20 %t/a.cppm -fgen-reduced-bmi -fmodule-output=%t/a.pcm \
+// RUN:     -S -emit-llvm -o %t/a.ll
+//
+// Test that the generated BMI from `-fgen-reduced-bmi -fmodule-output=` is same with
+// `-emit-reduced-module-interface`.
+// RUN: diff %t/a.reduced.pcm %t/a.pcm
+//
+// Test that we can consume the produced BMI correctly.
+// RUN: %clang_cc1 -std=c++20 %t/b.cppm -fmodule-file=a=%t/a.pcm -fsyntax-only -verify
+//
+// RUN: rm -f %t/a.pcm
+// RUN: %clang_cc1 -std=c++20 %t/a.cppm -fgen-reduced-bmi -fmodule-output=%t/a.pcm \
+// RUN:     -emit-module-interface -o %t/a.full.pcm
+// RUN: diff %t/a.reduced.pcm %t/a.pcm
+// RUN: not diff %t/a.pcm %t/a.full.pcm
+//
+// RUN: %clang_cc1 -std=c++20 %t/b.cppm -...
[truncated]

@ChuanqiXu9 ChuanqiXu9 marked this pull request as draft March 13, 2024 09:52
@ChuanqiXu9 ChuanqiXu9 marked this pull request as ready for review March 13, 2024 11:02
@koplas
Copy link

koplas commented Mar 15, 2024

Using -fgen-reduced-bmi currently fails for me with a case that looks like this:

// a.hpp
  template <typename T>
  void ignore(T const &) noexcept {}
  
  inline void resultCheck(char const *message) {
      ignore(message);
  }
  
// b.cppm
    module;
    #include "a.hpp"
    export module b;
    
    export {
        using ignore;
        using resultCheck;
    }
    
// c.cppm
    export module c;
    import b;
    
    export void test() {
        resultCheck(nullptr);
    }

This will result in this linker error: undefined reference to void ignore<char const*>(char const* const&).
Removing -fgen-reduced-bmi will result in linking without errors. Do I need to pass certain flags to CMake?

@koplas
Copy link

koplas commented Mar 15, 2024

Do I miss something? The performance and file size is similar with and without -fgen-reduced-bmi.
To reproduce clone https://github.com/koplas/clang-modules-test and run build.sh and build_thin_bmi.sh.

Copy link
Contributor

@iains iains left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no issue with the general intention or phasing here; my main concern is that we are introducing [yet] another user-facing modules option that actually we intend will become irrelevant after a few releases.

In practice, removing user-facing options is not very easy.

So:

  1. Perhaps we could have only the cc1 option and you could introduce some temporary handling in the driver to recognise it and amend the --precompile behaviour?
  2. Maybe the project could introduce something like -fexperimental-xxxx-xxxx with a clear statement that fexperimental flags cannot be relied on to be stable (or even present) in any future release)?

@@ -3031,6 +3032,11 @@ 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 gen_reduced_bmi : Flag<["-"], "fgen-reduced-bmi">,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is going to be a user-facing flag (even for a few releases) then I think it should be spelled in a way that make it modules-relatated (e.g. -fmodules-reduce-bmi, or -fmodules-minimise-bmi), as you know I'm not a fan of increasing the already huge number of modules-related user-facing options... (but I'll comment on that separately)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done by using -fmodules-reduce-bmi

@dwblaikie
Copy link
Collaborator

+1 to @iains's comments about being careful about the introduction and naming of driver flags & probably avoid it in this case, if possible, or try to make it clearly experimental.

Copy link

github-actions bot commented Mar 26, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@ChuanqiXu9
Copy link
Member Author

@iains @dwblaikie Understood. And I thought the major problem is that there are a lot flags from clang modules. And it is indeed confusing. But given we have to introduce new flags in this case, probably we can only try to make it more clear by better documents.

@ChuanqiXu9
Copy link
Member Author

Using -fgen-reduced-bmi currently fails for me with a case that looks like this:

// a.hpp
  template <typename T>
  void ignore(T const &) noexcept {}
  
  inline void resultCheck(char const *message) {
      ignore(message);
  }
  
// b.cppm
    module;
    #include "a.hpp"
    export module b;
    
    export {
        using ignore;
        using resultCheck;
    }
    
// c.cppm
    export module c;
    import b;
    
    export void test() {
        resultCheck(nullptr);
    }

This will result in this linker error: undefined reference to void ignore<char const*>(char const* const&). Removing -fgen-reduced-bmi will result in linking without errors. Do I need to pass certain flags to CMake?

This may be fixed in trunk. This should be a bug in Reduced BMI. Note that the current patch is only the driver part of Reduced BMI. And this is the reason why we need a new flag. Otherwise I'll propose to enable it by default : )

@ChuanqiXu9
Copy link
Member Author

Do I miss something? The performance and file size is similar with and without -fgen-reduced-bmi. To reproduce clone https://github.com/koplas/clang-modules-test and run build.sh and build_thin_bmi.sh.

Currently, the Reduced BMI will only remove function bodies for non-inline functions and definitions for some variables...

And declarations in headers or GMF are primarily inline, so probably the current Reduced BMI won't produce a strong impact on modules whose contents are primarily in GMF as expectedly.

For example, I can observe some impact on https://github.com/alibaba/async_simple/tree/CXX20Modules, where the repo has more use codes in the module purview instead of the GMF.

Further, in my mind, we can reduce more things in Reduced BMI. An example may be #76930.

Thanks for testing : )

@ChuanqiXu9 ChuanqiXu9 changed the title [C++20] [Modules] Introduce -fgen-reduced-bmi [C++20] [Modules] Introduce -fmodules-reduced-bmi Mar 26, 2024
@iains
Copy link
Contributor

iains commented Mar 26, 2024

@iains @dwblaikie Understood. And I thought the major problem is that there are a lot flags from clang modules. And it is indeed confusing. But given we have to introduce new flags in this case, probably we can only try to make it more clear by better documents.

So you do not think it possible to restrict the new flag to be "internal" (i.e. cc1-only) and to put some temporary driver processing to handle that? (I agree that this is an unusual mechanism, but the idea is to recognise that the driver-side processing is only expected to me temporary).

@ChuanqiXu9
Copy link
Member Author

@iains @dwblaikie Understood. And I thought the major problem is that there are a lot flags from clang modules. And it is indeed confusing. But given we have to introduce new flags in this case, probably we can only try to make it more clear by better documents.

So you do not think it possible to restrict the new flag to be "internal" (i.e. cc1-only) and to put some temporary driver processing to handle that? (I agree that this is an unusual mechanism, but the idea is to recognise that the driver-side processing is only expected to me temporary).

I have no idea how can we make that. We still need the users to provide something to enable reduced BMI. And I think it is symmetric to a new flag.

@iains
Copy link
Contributor

iains commented Mar 26, 2024

@iains @dwblaikie Understood. And I thought the major problem is that there are a lot flags from clang modules. And it is indeed confusing. But given we have to introduce new flags in this case, probably we can only try to make it more clear by better documents.

So you do not think it possible to restrict the new flag to be "internal" (i.e. cc1-only) and to put some temporary driver processing to handle that? (I agree that this is an unusual mechanism, but the idea is to recognise that the driver-side processing is only expected to me temporary).

I have no idea how can we make that. We still need the users to provide something to enable reduced BMI. And I think it is symmetric to a new flag.

What I mean is that (a) we need the internal 'cc1' flag permanently; but (b) we do not expect to need a user-facing driver flag permanently. and (c) We want to allow users to try this out.

I am suggesting we could say "to try this out use -Xclang -fmodules-reduced-bmi" and have temporary code in the driver to deal with the changes needed to phasing.

If this is not possible. then I suppose I am a bit sad that we keep saying 'there are too many modules options' - but yet still add more. however - we need to make progress, so if the suggestion here is really a non-starter .. then such is life.

Perhaps the second suggestion (-fexperimental-xxxxx options) could be discussed at the project level.

@ChuanqiXu9
Copy link
Member Author

@iains @dwblaikie Understood. And I thought the major problem is that there are a lot flags from clang modules. And it is indeed confusing. But given we have to introduce new flags in this case, probably we can only try to make it more clear by better documents.

So you do not think it possible to restrict the new flag to be "internal" (i.e. cc1-only) and to put some temporary driver processing to handle that? (I agree that this is an unusual mechanism, but the idea is to recognise that the driver-side processing is only expected to me temporary).

I have no idea how can we make that. We still need the users to provide something to enable reduced BMI. And I think it is symmetric to a new flag.

What I mean is that (a) we need the internal 'cc1' flag permanently; but (b) we do not expect to need a user-facing driver flag permanently. and (c) We want to allow users to try this out.

I am suggesting we could say "to try this out use -Xclang -fmodules-reduced-bmi" and have temporary code in the driver to deal with the changes needed to phasing.

If this is not possible. then I suppose I am a bit sad that we keep saying 'there are too many modules options' - but yet still add more. however - we need to make progress, so if the suggestion here is really a non-starter .. then such is life.

Perhaps the second suggestion (-fexperimental-xxxxx options) could be discussed at the project level.

Got your point. But I feel the -Xclang xxx style or the -fexperimental-xxx style may make people feel, "oh, this is not ready, let's wait". Then we may lose more testing opportunity. Also I feel such options are symmetric to the existing one. It still makes the interfaces to be more complicated. I don't feel they are better than the existing one.

And yes, it is indeed that we have a lot modules options. But I think this may not be the blocking point for adding new modules options if we think it is really needed. If there are things needed to be added by flags really and we don't do that due to we feel we have too many flags, I feel it is somewhat "not eating for fear of choking". I think what we need to do for this case is to be pretty careful when adding new flags and I think we already make it for Reduced BMI.

@dwblaikie
Copy link
Collaborator

@iains @dwblaikie Understood. And I thought the major problem is that there are a lot flags from clang modules. And it is indeed confusing. But given we have to introduce new flags in this case, probably we can only try to make it more clear by better documents.

So you do not think it possible to restrict the new flag to be "internal" (i.e. cc1-only) and to put some temporary driver processing to handle that? (I agree that this is an unusual mechanism, but the idea is to recognise that the driver-side processing is only expected to me temporary).

I have no idea how can we make that. We still need the users to provide something to enable reduced BMI. And I think it is symmetric to a new flag.

What I mean is that (a) we need the internal 'cc1' flag permanently; but (b) we do not expect to need a user-facing driver flag permanently. and (c) We want to allow users to try this out.
I am suggesting we could say "to try this out use -Xclang -fmodules-reduced-bmi" and have temporary code in the driver to deal with the changes needed to phasing.
If this is not possible. then I suppose I am a bit sad that we keep saying 'there are too many modules options' - but yet still add more. however - we need to make progress, so if the suggestion here is really a non-starter .. then such is life.
Perhaps the second suggestion (-fexperimental-xxxxx options) could be discussed at the project level.

Got your point. But I feel the -Xclang xxx style or the -fexperimental-xxx style may make people feel, "oh, this is not ready, let's wait". Then we may lose more testing opportunity.

That seems good to me - these are pretty experimental directions we're going in. We haven't figured out how this stuff should work long term - we are experimenting.

Also I feel such options are symmetric to the existing one.

What do you mean by "symmetric"?

The difference @iains is trying to highlight is that adding driver flags is a long-term commitment burden - adding cc1 flags, clarifying that these are not long term supported/guaranteed parts of the interface, but a way to experiment with some things until we figure out what the long term supported interface is.

Especially if we think the long-term future is always (or, at least by default) reduced BMIs, experimenting with it under a flag until we have confidence in that direction - then maybe just changing the Clang behavior (again, perhaps with a cc1 flag to opt-out as an escape hatch that's intended to be short-term while we figure out whatever bugs lead to the need to use that escape hatch - then when we fixt he bugs and remove the flag, the people on the bleeding edge will need to remove the flag, which is fine/good - rather than leaving these weird flags around forever).

@ChuanqiXu9 ChuanqiXu9 changed the title [C++20] [Modules] Introduce -fmodules-reduced-bmi [C++20] [Modules] Introduce -fexperimental-modules-reduced-bmi Mar 29, 2024
@ChuanqiXu9
Copy link
Member Author

Got it. I've renamed the flag as -fexperimental-modules-reduced-bmi. I feel the suggestion like let users to use -Xclang options look odd..


What do you mean by "symmetric"?

I mean, we always want the users to do something explicitly to enable the feature. But this might not be important now.

@iains
Copy link
Contributor

iains commented Mar 29, 2024

Got it. I've renamed the flag as -fexperimental-modules-reduced-bmi.

Thanks.

I feel the suggestion like let users to use -Xclang options look odd..

I think the point here is that we want expert users to try this out (with understanding that it might not behave exactly as they expect). Because it is experimental, it is not yet ready for "end users" - I would expect expert users to be able to deal with -Xclang xxxxx (but I will not insist, it's just a suggestion)

@ChuanqiXu9
Copy link
Member Author

Got it. I've renamed the flag as -fexperimental-modules-reduced-bmi.

Thanks.

I feel the suggestion like let users to use -Xclang options look odd..

I think the point here is that we want expert users to try this out (with understanding that it might not behave exactly as they expect). Because it is experimental, it is not yet ready for "end users" - I would expect expert users to be able to deal with -Xclang xxxxx (but I will not insist, it's just a suggestion)

Agreed.

@ChuanqiXu9
Copy link
Member Author

I'd like to land this patch in next week if no objection comes in.

@@ -3017,6 +3017,7 @@ defm prebuilt_implicit_modules : BoolFOption<"prebuilt-implicit-modules",

def fmodule_output_EQ : Joined<["-"], "fmodule-output=">,
Flags<[NoXarchOption]>, Visibility<[ClangOption, CC1Option]>,
MarshallingInfoString<FrontendOpts<"ModuleOutputPath">>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the motivation to include this change in this patch? Could it be separated?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the flag was only used in drivers. So we didn't need a variable. But after this patch, we need a variable. If we separate this out, we may get a unused variable in that patch. I feel it is not so good.

ChuanqiXu9 added a commit that referenced this pull request Apr 2, 2024
…o a seperate function

Required in the review process of
#85050.
"ReducedBMIGenerator should only be used with C++20 Named modules.");
return M;
}

void ReducedBMIGenerator::HandleTranslationUnit(ASTContext &Ctx) {
// FIMXE: We'd better to wrap such options to a new class ASTWriterOptions.
getPreprocessor()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the motivation for this change/how does it relate to the purpose of this patch?

(& it might be easier to read if the HeaderSearchOpts were accessed once, stored in a reference, then the various settings were made:

HeaderSearchOptions& Opts = getPreprocessor().getHeaderSearchInfo().getHeaderSearchOpts();
Opts.ModulesSkipDiagnosticOptions = true;
Opts.ModulesSkipHeaderSearchPaths = true;
Opts.ModulesSkipPragmaDiagnosticMappings = true;

)

Copy link
Member Author

@ChuanqiXu9 ChuanqiXu9 Apr 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, my bad. The motivation is that during my local testing, I found the size of the reduced BMI may be larger than the full BMI, which should be incorrect. And then I tried to fix this on the fly... I've splitted this into a NFC patch ed1cfff

Thanks.

ChuanqiXu9 added a commit that referenced this pull request Apr 3, 2024
…rtion

This was part of #85050.

It is suggested to split the unrelated change as much as possible. So
here is the patch.
@ChuanqiXu9 ChuanqiXu9 force-pushed the introduce-fgen-reduced-bmi branch 2 times, most recently from 8baafcd to 8c51aa5 Compare April 7, 2024 02:16
@ChuanqiXu9
Copy link
Member Author

Rebased with main. @dwblaikie may you have more comments?

Copy link
Collaborator

@dwblaikie dwblaikie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give it a go

Comment on lines 1073 to 1081
if (CI.getFrontendOpts().GenReducedBMI &&
!CI.getFrontendOpts().ModuleOutputPath.empty()) {
std::vector<std::unique_ptr<ASTConsumer>> Consumers{2};
Consumers[0] = std::make_unique<ReducedBMIGenerator>(
CI.getPreprocessor(), CI.getModuleCache(),
CI.getFrontendOpts().ModuleOutputPath);
Consumers[1] = std::move(Result);
return std::make_unique<MultiplexConsumer>(std::move(Consumers));
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this new code, rather than an alternative codepath of existing code? (like some code that was producing the BMI would go from producing the unreduced BMI to producing the reduced BMI)

Figuring this out would help me unedrstand why ModuleOutputPath is new (this patch doesn't add the functionality to output a module to a path - we had that already, this just changes the content that goes there)

I guess because maybe this patch is changing the way we output the BMI - or that the reduced BMI is being output in a different way than the non-reduced BMI?

Should we address that? Make the current full BMI emission work the same way as the reduced BMI? (or, more precisely, in a pre-patch, change the full BMI emission to use a mechanism that can then be reused for the reduced BMI?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For full BMI, the workflow is:

.cpp -> .pcm -> .o

no matter if -fmodule-output is specified or not. If -fmodule-output is not specified, the .pcm file will be generated in /tmp directory.

And for reduced BMI, the workflow is:

.cpp ---------> .o
               -----> .pcm

that said, we generate the .o directly from the .cpp then we don't need the .pcm to contain the full information to generate the .o .

Then for the original question, can we make the full BMI in the same way with the reduced BMI? Maybe we can, but it looks like an overkill. Since if the .o don't need the .pcm, we don't need the .pcm to be full.

Copy link
Contributor

@mizvekov mizvekov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I share the objections that it may be too soon to introduce a driver flag for this. Only a frontend flag is ok for now, but it's non blocking on my side because it doesn't look like it will be particularly hard to deprecate it later.

clang/lib/CodeGen/CodeGenAction.cpp Outdated Show resolved Hide resolved
Comment on lines +4057 to +4058
"-fmodule-output=" +
getCXX20NamedModuleOutputPath(Args, Input.getBaseInput())));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be reasonable to push two separate arguments, instead of concatenating them?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure. I tried to not concat it but the test gets failing. I didn't see why but I see almost we always concat it in such cases (appending a variable to some flag ends with =). So I feel it may not be problematic or we can fix such things together if we want.

@ChuanqiXu9
Copy link
Member Author

Thanks for reviewing.

@ChuanqiXu9 ChuanqiXu9 merged commit f811d7b into llvm:main Apr 15, 2024
3 of 4 checks passed
bazuzi pushed a commit to bazuzi/llvm-project that referenced this pull request Apr 15, 2024
…85050)

This is the driver part of
llvm#75894.

This patch introduces '-fexperimental-modules-reduced-bmi' to enable
generating the reduced BMI.

This patch did:
- When `-fexperimental-modules-reduced-bmi` is specified but
`--precompile` is not specified for a module unit, we'll skip the
precompile phase to avoid unnecessary two-phase compilation phases. Then
if `-c` is specified, we will generate the reduced BMI in CodeGenAction
as a by-product.
- When `-fexperimental-modules-reduced-bmi` is specified and
`--precompile` is specified, we will generate the reduced BMI in
GenerateModuleInterfaceAction as a by-product.
- When `-fexperimental-modules-reduced-bmi` is specified for a
non-module unit. We don't do anything nor try to give a warn. This is
more user friendly so that the end users can try to test and experiment
with the feature without asking help from the build systems.

The core design idea is that users should be able to enable this easily
with the existing cmake mechanisms.

The future plan for the flag is:
- Add this to clang19 and make it opt-in for 1~2 releases. It depends on
the testing feedback to decide how long we like to make it opt-in.
- Then we can announce the existing BMI generating may be deprecated and
suggesting people (end users or build systems) to enable this for 1~2
releases.
- Finally we will enable this by default. When that time comes, the term
`BMI` will refer to the reduced BMI today and the existing BMI will only
be meaningful to build systems which loves to support two phase
compilations.

I'll send release notes and document in seperate commits after this get
landed.
aniplcc pushed a commit to aniplcc/llvm-project that referenced this pull request Apr 15, 2024
…85050)

This is the driver part of
llvm#75894.

This patch introduces '-fexperimental-modules-reduced-bmi' to enable
generating the reduced BMI.

This patch did:
- When `-fexperimental-modules-reduced-bmi` is specified but
`--precompile` is not specified for a module unit, we'll skip the
precompile phase to avoid unnecessary two-phase compilation phases. Then
if `-c` is specified, we will generate the reduced BMI in CodeGenAction
as a by-product.
- When `-fexperimental-modules-reduced-bmi` is specified and
`--precompile` is specified, we will generate the reduced BMI in
GenerateModuleInterfaceAction as a by-product.
- When `-fexperimental-modules-reduced-bmi` is specified for a
non-module unit. We don't do anything nor try to give a warn. This is
more user friendly so that the end users can try to test and experiment
with the feature without asking help from the build systems.

The core design idea is that users should be able to enable this easily
with the existing cmake mechanisms.

The future plan for the flag is:
- Add this to clang19 and make it opt-in for 1~2 releases. It depends on
the testing feedback to decide how long we like to make it opt-in.
- Then we can announce the existing BMI generating may be deprecated and
suggesting people (end users or build systems) to enable this for 1~2
releases.
- Finally we will enable this by default. When that time comes, the term
`BMI` will refer to the reduced BMI today and the existing BMI will only
be meaningful to build systems which loves to support two phase
compilations.

I'll send release notes and document in seperate commits after this get
landed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:modules C++20 modules and Clang Header Modules clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants