Skip to content

Commit 77c6642

Browse files
committed
[C++20] [Modules] Introduce -fgen-reduced-bmi
1 parent 4d62929 commit 77c6642

File tree

13 files changed

+220
-27
lines changed

13 files changed

+220
-27
lines changed

clang/include/clang/CodeGen/CodeGenAction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class CodeGenAction : public ASTFrontendAction {
5757
bool loadLinkModules(CompilerInstance &CI);
5858

5959
protected:
60+
bool BeginSourceFileAction(CompilerInstance &CI) override;
61+
6062
/// Create a new code generation action. If the optional \p _VMContext
6163
/// parameter is supplied, the action uses it without taking ownership,
6264
/// otherwise it creates a fresh LLVM context and takes ownership.

clang/include/clang/Driver/Options.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3018,6 +3018,7 @@ defm prebuilt_implicit_modules : BoolFOption<"prebuilt-implicit-modules",
30183018

30193019
def fmodule_output_EQ : Joined<["-"], "fmodule-output=">,
30203020
Flags<[NoXarchOption]>, Visibility<[ClangOption, CC1Option]>,
3021+
MarshallingInfoString<FrontendOpts<"ModuleOutputPath">>,
30213022
HelpText<"Save intermediate module file results when compiling a standard C++ module unit.">;
30223023
def fmodule_output : Flag<["-"], "fmodule-output">, Flags<[NoXarchOption]>,
30233024
Visibility<[ClangOption, CC1Option]>,
@@ -3031,6 +3032,11 @@ defm skip_odr_check_in_gmf : BoolOption<"f", "skip-odr-check-in-gmf",
30313032
"Perform ODR checks for decls in the global module fragment.">>,
30323033
Group<f_Group>;
30333034

3035+
def gen_reduced_bmi : Flag<["-"], "fgen-reduced-bmi">,
3036+
Group<i_Group>, Visibility<[ClangOption, CC1Option]>,
3037+
HelpText<"Generate the reduced BMI">,
3038+
MarshallingInfoFlag<FrontendOpts<"GenReducedBMI">>;
3039+
30343040
def fmodules_prune_interval : Joined<["-"], "fmodules-prune-interval=">, Group<i_Group>,
30353041
Visibility<[ClangOption, CC1Option]>, MetaVarName<"<seconds>">,
30363042
HelpText<"Specify the interval (in seconds) between attempts to prune the module cache">,

clang/include/clang/Frontend/FrontendOptions.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,10 @@ class FrontendOptions {
387387
LLVM_PREFERRED_TYPE(bool)
388388
unsigned ModulesShareFileManager : 1;
389389

390+
/// Whether to generate reduced BMI for C++20 named modules.
391+
LLVM_PREFERRED_TYPE(bool)
392+
unsigned GenReducedBMI : 1;
393+
390394
CodeCompleteOptions CodeCompleteOpts;
391395

392396
/// Specifies the output format of the AST.
@@ -553,6 +557,9 @@ class FrontendOptions {
553557
/// Path which stores the output files for -ftime-trace
554558
std::string TimeTracePath;
555559

560+
/// Output Path for module output file.
561+
std::string ModuleOutputPath;
562+
556563
public:
557564
FrontendOptions()
558565
: DisableFree(false), RelocatablePCH(false), ShowHelp(false),
@@ -565,7 +572,7 @@ class FrontendOptions {
565572
BuildingImplicitModuleUsesLock(true), ModulesEmbedAllFiles(false),
566573
IncludeTimestamps(true), UseTemporary(true),
567574
AllowPCMWithCompilerErrors(false), ModulesShareFileManager(true),
568-
TimeTraceGranularity(500) {}
575+
GenReducedBMI(false), TimeTraceGranularity(500) {}
569576

570577
/// getInputKindForExtension - Return the appropriate input kind for a file
571578
/// extension. For example, "c" would return Language::C.

clang/include/clang/Serialization/ASTWriter.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,7 @@ class ASTWriter : public ASTDeserializationListener,
846846
/// AST and semantic-analysis consumer that generates a
847847
/// precompiled header from the parsed source code.
848848
class PCHGenerator : public SemaConsumer {
849-
const Preprocessor &PP;
849+
Preprocessor &PP;
850850
std::string OutputFile;
851851
std::string isysroot;
852852
Sema *SemaPtr;
@@ -867,11 +867,12 @@ class PCHGenerator : public SemaConsumer {
867867
DiagnosticsEngine &getDiagnostics() const {
868868
return SemaPtr->getDiagnostics();
869869
}
870+
Preprocessor &getPreprocessor() { return PP; }
870871

871872
virtual Module *getEmittingModule(ASTContext &Ctx);
872873

873874
public:
874-
PCHGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache,
875+
PCHGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
875876
StringRef OutputFile, StringRef isysroot,
876877
std::shared_ptr<PCHBuffer> Buffer,
877878
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
@@ -893,7 +894,7 @@ class ReducedBMIGenerator : public PCHGenerator {
893894
virtual Module *getEmittingModule(ASTContext &Ctx) override;
894895

895896
public:
896-
ReducedBMIGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache,
897+
ReducedBMIGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
897898
StringRef OutputFile);
898899

899900
void HandleTranslationUnit(ASTContext &Ctx) override;

clang/lib/CodeGen/CodeGenAction.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@
2525
#include "clang/CodeGen/ModuleBuilder.h"
2626
#include "clang/Driver/DriverDiagnostic.h"
2727
#include "clang/Frontend/CompilerInstance.h"
28+
#include "clang/Frontend/FrontendActions.h"
2829
#include "clang/Frontend/FrontendDiagnostic.h"
30+
#include "clang/Frontend/MultiplexConsumer.h"
2931
#include "clang/Lex/Preprocessor.h"
32+
#include "clang/Serialization/ASTWriter.h"
3033
#include "llvm/ADT/Hashing.h"
3134
#include "llvm/Bitcode/BitcodeReader.h"
3235
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
@@ -1003,6 +1006,12 @@ CodeGenerator *CodeGenAction::getCodeGenerator() const {
10031006
return BEConsumer->getCodeGenerator();
10041007
}
10051008

1009+
bool CodeGenAction::BeginSourceFileAction(CompilerInstance &CI) {
1010+
if (CI.getFrontendOpts().GenReducedBMI)
1011+
CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface);
1012+
return true;
1013+
}
1014+
10061015
static std::unique_ptr<raw_pwrite_stream>
10071016
GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {
10081017
switch (Action) {
@@ -1061,6 +1070,16 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
10611070
CI.getPreprocessor().addPPCallbacks(std::move(Callbacks));
10621071
}
10631072

1073+
if (CI.getFrontendOpts().GenReducedBMI &&
1074+
!CI.getFrontendOpts().ModuleOutputPath.empty()) {
1075+
std::vector<std::unique_ptr<ASTConsumer>> Consumers{2};
1076+
Consumers[0] = std::move(Result);
1077+
Consumers[1] = std::make_unique<ReducedBMIGenerator>(
1078+
CI.getPreprocessor(), CI.getModuleCache(),
1079+
CI.getFrontendOpts().ModuleOutputPath);
1080+
return std::make_unique<MultiplexConsumer>(std::move(Consumers));
1081+
}
1082+
10641083
return std::move(Result);
10651084
}
10661085

clang/lib/Driver/Driver.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4737,6 +4737,14 @@ Action *Driver::ConstructPhaseAction(
47374737
if (Args.hasArg(options::OPT_extract_api))
47384738
return C.MakeAction<ExtractAPIJobAction>(Input, types::TY_API_INFO);
47394739

4740+
// With '-fgen-reduced-bmi', we don't want to run the precompile phase
4741+
// unless the user specified '--precompile'. In the case the '--precompile'
4742+
// flag is enabled, we will try to emit the reduced BMI as a by product
4743+
// in GenerateModuleInterfaceAction.
4744+
if (Args.hasArg(options::OPT_gen_reduced_bmi) &&
4745+
!Args.getLastArg(options::OPT__precompile))
4746+
return Input;
4747+
47404748
types::ID OutputTy = getPrecompiledType(Input->getType());
47414749
assert(OutputTy != types::TY_INVALID &&
47424750
"Cannot precompile this input type!");
@@ -5802,19 +5810,8 @@ static const char *GetModuleOutputPath(Compilation &C, const JobAction &JA,
58025810
(C.getArgs().hasArg(options::OPT_fmodule_output) ||
58035811
C.getArgs().hasArg(options::OPT_fmodule_output_EQ)));
58045812

5805-
if (Arg *ModuleOutputEQ =
5806-
C.getArgs().getLastArg(options::OPT_fmodule_output_EQ))
5807-
return C.addResultFile(ModuleOutputEQ->getValue(), &JA);
5808-
5809-
SmallString<64> OutputPath;
5810-
Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);
5811-
if (FinalOutput && C.getArgs().hasArg(options::OPT_c))
5812-
OutputPath = FinalOutput->getValue();
5813-
else
5814-
OutputPath = BaseInput;
5815-
5816-
const char *Extension = types::getTypeTempSuffix(JA.getType());
5817-
llvm::sys::path::replace_extension(OutputPath, Extension);
5813+
SmallString<256> OutputPath =
5814+
tools::getCXX20NamedModuleOutputPath(C.getArgs(), BaseInput);
58185815
return C.addResultFile(C.getArgs().MakeArgString(OutputPath.c_str()), &JA);
58195816
}
58205817

@@ -5901,8 +5898,10 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
59015898
// If we're emitting a module output with the specified option
59025899
// `-fmodule-output`.
59035900
if (!AtTopLevel && isa<PrecompileJobAction>(JA) &&
5904-
JA.getType() == types::TY_ModuleFile && SpecifiedModuleOutput)
5901+
JA.getType() == types::TY_ModuleFile && SpecifiedModuleOutput) {
5902+
assert(!C.getArgs().hasArg(options::OPT_gen_reduced_bmi));
59055903
return GetModuleOutputPath(C, JA, BaseInput);
5904+
}
59065905

59075906
// Output to a temporary file?
59085907
if ((!AtTopLevel && !isSaveTempsEnabled() &&

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3777,6 +3777,24 @@ bool Driver::getDefaultModuleCachePath(SmallVectorImpl<char> &Result) {
37773777
return false;
37783778
}
37793779

3780+
llvm::SmallString<256>
3781+
clang::driver::tools::getCXX20NamedModuleOutputPath(const ArgList &Args,
3782+
const char *BaseInput) {
3783+
if (Arg *ModuleOutputEQ = Args.getLastArg(options::OPT_fmodule_output_EQ))
3784+
return StringRef(ModuleOutputEQ->getValue());
3785+
3786+
SmallString<256> OutputPath;
3787+
if (Arg *FinalOutput = Args.getLastArg(options::OPT_o);
3788+
FinalOutput && Args.hasArg(options::OPT_c))
3789+
OutputPath = FinalOutput->getValue();
3790+
else
3791+
OutputPath = BaseInput;
3792+
3793+
const char *Extension = types::getTypeTempSuffix(types::TY_ModuleFile);
3794+
llvm::sys::path::replace_extension(OutputPath, Extension);
3795+
return OutputPath;
3796+
}
3797+
37803798
static bool RenderModulesOptions(Compilation &C, const Driver &D,
37813799
const ArgList &Args, const InputInfo &Input,
37823800
const InputInfo &Output, bool HaveStd20,
@@ -3965,9 +3983,26 @@ static bool RenderModulesOptions(Compilation &C, const Driver &D,
39653983
// module fragment.
39663984
CmdArgs.push_back("-fskip-odr-check-in-gmf");
39673985

3968-
// Claim `-fmodule-output` and `-fmodule-output=` to avoid unused warnings.
3969-
Args.ClaimAllArgs(options::OPT_fmodule_output);
3970-
Args.ClaimAllArgs(options::OPT_fmodule_output_EQ);
3986+
// Noop if we see '-fgen-reduced-bmi' with other translation units than module
3987+
// units. This is more user friendly to allow end uers to enable this feature
3988+
// without asking for help from build systems.
3989+
if (Args.hasArg(options::OPT_gen_reduced_bmi) &&
3990+
(Input.getType() == driver::types::TY_CXXModule ||
3991+
Input.getType() == driver::types::TY_PP_CXXModule)) {
3992+
CmdArgs.push_back("-fgen-reduced-bmi");
3993+
3994+
if (Args.hasArg(options::OPT_fmodule_output_EQ))
3995+
Args.AddLastArg(CmdArgs, options::OPT_fmodule_output_EQ);
3996+
else
3997+
CmdArgs.push_back(Args.MakeArgString(
3998+
"-fmodule-output=" +
3999+
getCXX20NamedModuleOutputPath(Args, Input.getBaseInput())));
4000+
} else {
4001+
// To avoid unused warnings.
4002+
Args.ClaimAllArgs(options::OPT_gen_reduced_bmi);
4003+
Args.ClaimAllArgs(options::OPT_fmodule_output);
4004+
Args.ClaimAllArgs(options::OPT_fmodule_output_EQ);
4005+
}
39714006

39724007
return HaveModules;
39734008
}

clang/lib/Driver/ToolChains/Clang.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,20 @@ DwarfFissionKind getDebugFissionKind(const Driver &D,
193193
const llvm::opt::ArgList &Args,
194194
llvm::opt::Arg *&Arg);
195195

196+
// Calculate the output path of the module file when compiling a module unit
197+
// with the `-fmodule-output` option or `-fmodule-output=` option specified.
198+
// The behavior is:
199+
// - If `-fmodule-output=` is specfied, then the module file is
200+
// writing to the value.
201+
// - Otherwise if the output object file of the module unit is specified, the
202+
// output path
203+
// of the module file should be the same with the output object file except
204+
// the corresponding suffix. This requires both `-o` and `-c` are specified.
205+
// - Otherwise, the output path of the module file will be the same with the
206+
// input with the corresponding suffix.
207+
llvm::SmallString<256>
208+
getCXX20NamedModuleOutputPath(const llvm::opt::ArgList &Args,
209+
const char *BaseInput);
196210
} // end namespace tools
197211

198212
} // end namespace driver

clang/lib/Frontend/FrontendActions.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,13 @@ GenerateModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI,
281281
if (Consumers.empty())
282282
return nullptr;
283283

284+
if (CI.getFrontendOpts().GenReducedBMI &&
285+
!CI.getFrontendOpts().ModuleOutputPath.empty()) {
286+
Consumers.push_back(std::make_unique<ReducedBMIGenerator>(
287+
CI.getPreprocessor(), CI.getModuleCache(),
288+
CI.getFrontendOpts().ModuleOutputPath));
289+
}
290+
284291
return std::make_unique<MultiplexConsumer>(std::move(Consumers));
285292
}
286293

clang/lib/Frontend/PrecompiledPreamble.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,7 @@ class PrecompilePreambleAction : public ASTFrontendAction {
290290

291291
class PrecompilePreambleConsumer : public PCHGenerator {
292292
public:
293-
PrecompilePreambleConsumer(PrecompilePreambleAction &Action,
294-
const Preprocessor &PP,
293+
PrecompilePreambleConsumer(PrecompilePreambleAction &Action, Preprocessor &PP,
295294
InMemoryModuleCache &ModuleCache,
296295
StringRef isysroot,
297296
std::shared_ptr<PCHBuffer> Buffer)

0 commit comments

Comments
 (0)