Skip to content

[clang][modules] Serialize CodeGenOptions #146422

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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion clang-tools-extra/clangd/ModulesBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,9 @@ bool IsModuleFileUpToDate(PathRef ModuleFilePath,

IntrusiveRefCntPtr<ModuleCache> ModCache = createCrossProcessModuleCache();
PCHContainerOperations PCHOperations;
CodeGenOptions CodeGenOpts;
ASTReader Reader(PP, *ModCache, /*ASTContext=*/nullptr,
PCHOperations.getRawReader(), {});
PCHOperations.getRawReader(), CodeGenOpts, {});

// We don't need any listener here. By default it will use a validator
// listener.
Expand Down
26 changes: 17 additions & 9 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
// that have enumeration type and VALUE_CODEGENOPT is a code
// generation option that describes a value rather than a flag.
//
// AFFECTING_VALUE_CODEGENOPT is used for code generation options that can
// affect the AST.
// COMPATIBLE_VALUE_CODEGENOPT is used for code generation options that affect
// the construction of the AST in a way that doesn't prevent
// interoperability (that is, the value can be different between an explicit
// module and the user of that module).
//
//===----------------------------------------------------------------------===//
#ifndef CODEGENOPT
Expand All @@ -30,11 +32,16 @@ CODEGENOPT(Name, Bits, Default)
CODEGENOPT(Name, Bits, Default)
#endif

#ifndef AFFECTING_VALUE_CODEGENOPT
# define AFFECTING_VALUE_CODEGENOPT(Name, Bits, Default) \
#ifndef COMPATIBLE_VALUE_CODEGENOPT
# define COMPATIBLE_VALUE_CODEGENOPT(Name, Bits, Default, Description) \
VALUE_CODEGENOPT(Name, Bits, Default)
#endif

#ifndef COMPATIBLE_ENUM_CODEGENOPT
# define COMPATIBLE_ENUM_CODEGENOPT(Name, Type, Bits, Default, Description) \
ENUM_CODEGENOPT(Name, Type, Bits, Default)
#endif

CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
CODEGENOPT(Crel, 1, 0) ///< -Wa,--crel
CODEGENOPT(ImplicitMapSyms, 1, 0) ///< -Wa,-mmapsyms=implicit
Expand Down Expand Up @@ -216,9 +223,9 @@ CODEGENOPT(ObjCConvertMessagesToRuntimeCalls , 1, 1)
CODEGENOPT(ObjCAvoidHeapifyLocalBlocks, 1, 0)


// The optimization options affect frontend options, whicn in turn do affect the AST.
AFFECTING_VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
AFFECTING_VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
// The optimization options affect frontend options, which in turn do affect the AST.
COMPATIBLE_VALUE_CODEGENOPT(OptimizationLevel, 2, 0, "optimization level") ///< The -O[0-3] option specified.
COMPATIBLE_VALUE_CODEGENOPT(OptimizeSize, 2, 0, "optimizing for size") ///< If -Os (==1) or -Oz (==2) is specified.

CODEGENOPT(AtomicProfileUpdate , 1, 0) ///< Set -fprofile-update=atomic
CODEGENOPT(ContinuousProfileSync, 1, 0) ///< Enable continuous instrumentation profiling
Expand Down Expand Up @@ -383,7 +390,7 @@ VALUE_CODEGENOPT(SmallDataLimit, 32, 0)
VALUE_CODEGENOPT(SSPBufferSize, 32, 0)

/// The kind of inlining to perform.
ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NormalInlining)
COMPATIBLE_ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NormalInlining, "inlining kind")

/// The maximum stack size a function can have to be considered for inlining.
VALUE_CODEGENOPT(InlineMaxStackSize, 32, UINT_MAX)
Expand Down Expand Up @@ -494,4 +501,5 @@ ENUM_CODEGENOPT(WinX64EHUnwindV2, llvm::WinX64EHUnwindV2Mode,
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
#undef VALUE_CODEGENOPT
#undef AFFECTING_VALUE_CODEGENOPT
#undef COMPATIBLE_VALUE_CODEGENOPT
#undef COMPATIBLE_ENUM_CODEGENOPT
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticSerializationKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ def err_ast_file_langopt_mismatch : Error<"%0 was %select{disabled|enabled}1 in
"precompiled file '%3' but is currently %select{disabled|enabled}2">;
def err_ast_file_langopt_value_mismatch : Error<
"%0 differs in precompiled file '%1' vs. current file">;
def err_ast_file_codegenopt_value_mismatch
: Error<"%0 differs in precompiled file '%1' vs. current file">;
def err_ast_file_diagopt_mismatch : Error<"%0 is currently enabled, but was not in "
"the precompiled file '%1'">;
def err_ast_file_modulecache_mismatch : Error<"precompiled file '%2' was compiled with module cache "
Expand Down
3 changes: 0 additions & 3 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,6 @@ COMPATIBLE_LANGOPT(ModulesValidateTextualHeaderIncludes, 1, 1, "validation of te
BENIGN_LANGOPT(ModulesErrorRecovery, 1, 1, "automatically importing modules as needed when performing error recovery")
BENIGN_LANGOPT(ImplicitModules, 1, 1, "building modules that are not specified via -fmodule-file")
COMPATIBLE_LANGOPT(ModulesLocalVisibility, 1, 0, "local submodule visibility")
COMPATIBLE_LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro")
COMPATIBLE_LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
COMPATIBLE_LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)")
VALUE_LANGOPT(PackStruct , 32, 0,
"default struct packing maximum alignment")
Expand All @@ -224,7 +222,6 @@ COMPATIBLE_VALUE_LANGOPT(PIE , 1, 0, "is pie")
LANGOPT(ROPI , 1, 0, "Read-only position independence")
LANGOPT(RWPI , 1, 0, "Read-write position independence")
COMPATIBLE_LANGOPT(GNUInline , 1, 0, "GNU inline semantics")
COMPATIBLE_LANGOPT(NoInlineDefine , 1, 0, "__NO_INLINE__ predefined macro")
COMPATIBLE_LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro")
COMPATIBLE_LANGOPT(FastMath , 1, 0, "fast FP math optimizations, and __FAST_MATH__ predefined macro")
COMPATIBLE_LANGOPT(UnsafeFPMath , 1, 0, "Unsafe Floating Point Math")
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Frontend/ASTUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class ASTContext;
class ASTDeserializationListener;
class ASTMutationListener;
class ASTReader;
class CodeGenOptions;
class CompilerInstance;
class CompilerInvocation;
class Decl;
Expand Down Expand Up @@ -107,6 +108,7 @@ class ASTUnit {

private:
std::unique_ptr<LangOptions> LangOpts;
std::unique_ptr<CodeGenOptions> CodeGenOpts;
// FIXME: The documentation on \c LoadFrom* member functions states that the
// DiagnosticsEngine (and therefore DiagnosticOptions) must outlive the
// returned ASTUnit. This is not the case. Enfore it by storing non-owning
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Frontend/CompilerInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ class CompilerInstance : public ModuleLoader {
DisableValidationForModuleKind DisableValidation,
bool AllowPCHWithCompilerErrors, Preprocessor &PP, ModuleCache &ModCache,
ASTContext &Context, const PCHContainerReader &PCHContainerRdr,
const CodeGenOptions &CodeGenOpts,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
void *DeserializationListener, bool OwnDeserializationListener,
Expand Down
5 changes: 4 additions & 1 deletion clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace serialization {
/// Version 4 of AST files also requires that the version control branch and
/// revision match exactly, since there is no backward compatibility of
/// AST files at this time.
const unsigned VERSION_MAJOR = 34;
const unsigned VERSION_MAJOR = 35;

/// AST file minor version number supported by this version of
/// Clang.
Expand Down Expand Up @@ -399,6 +399,9 @@ enum OptionsRecordTypes {

/// Record code for the preprocessor options table.
PREPROCESSOR_OPTIONS,

/// Record code for the codegen options table.
CODEGEN_OPTIONS,
};

/// Record codes for the unhashed control block.
Expand Down
39 changes: 31 additions & 8 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class ASTContext;
class ASTDeserializationListener;
class ASTReader;
class ASTRecordReader;
class CodeGenOptions;
class CXXTemporary;
class Decl;
class DeclarationName;
Expand Down Expand Up @@ -137,6 +138,15 @@ class ASTReaderListener {
return false;
}

/// Receives the codegen options.
///
/// \returns true to indicate the options are invalid or false otherwise.
virtual bool ReadCodeGenOptions(const CodeGenOptions &CGOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) {
return false;
}

/// Receives the target options.
///
/// \returns true to indicate the target options are invalid, or false
Expand Down Expand Up @@ -281,6 +291,9 @@ class ChainedASTReaderListener : public ASTReaderListener {
bool ReadLanguageOptions(const LangOptions &LangOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) override;
bool ReadCodeGenOptions(const CodeGenOptions &CGOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) override;
bool ReadTargetOptions(const TargetOptions &TargetOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) override;
Expand Down Expand Up @@ -322,6 +335,9 @@ class PCHValidator : public ASTReaderListener {
bool ReadLanguageOptions(const LangOptions &LangOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) override;
bool ReadCodeGenOptions(const CodeGenOptions &CGOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) override;
bool ReadTargetOptions(const TargetOptions &TargetOpts,
StringRef ModuleFilename, bool Complain,
bool AllowCompatibleDifferences) override;
Expand Down Expand Up @@ -493,6 +509,9 @@ class ASTReader
/// The AST consumer.
ASTConsumer *Consumer = nullptr;

/// The codegen options.
const CodeGenOptions &CodeGenOpts;

/// The module manager which manages modules and their dependencies
ModuleManager ModuleMgr;

Expand Down Expand Up @@ -1586,6 +1605,10 @@ class ASTReader
StringRef ModuleFilename, bool Complain,
ASTReaderListener &Listener,
bool AllowCompatibleDifferences);
static bool ParseCodeGenOptions(const RecordData &Record,
StringRef ModuleFilename, bool Complain,
ASTReaderListener &Listener,
bool AllowCompatibleDifferences);
static bool ParseTargetOptions(const RecordData &Record,
StringRef ModuleFilename, bool Complain,
ASTReaderListener &Listener,
Expand Down Expand Up @@ -1777,6 +1800,7 @@ class ASTReader
/// deserializing.
ASTReader(Preprocessor &PP, ModuleCache &ModCache, ASTContext *Context,
const PCHContainerReader &PCHContainerRdr,
const CodeGenOptions &CodeGenOpts,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
StringRef isysroot = "",
DisableValidationForModuleKind DisableValidationKind =
Expand All @@ -1795,6 +1819,7 @@ class ASTReader
SourceManager &getSourceManager() const { return SourceMgr; }
FileManager &getFileManager() const { return FileMgr; }
DiagnosticsEngine &getDiags() const { return Diags; }
const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }

/// Flags that indicate what kind of AST loading failures the client
/// of the AST reader can directly handle.
Expand Down Expand Up @@ -1996,14 +2021,12 @@ class ASTReader

/// Determine whether the given AST file is acceptable to load into a
/// translation unit with the given language and target options.
static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
const ModuleCache &ModCache,
const PCHContainerReader &PCHContainerRdr,
const LangOptions &LangOpts,
const TargetOptions &TargetOpts,
const PreprocessorOptions &PPOpts,
StringRef ExistingModuleCachePath,
bool RequireStrictOptionMatches = false);
static bool isAcceptableASTFile(
StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache,
const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts,
const CodeGenOptions &CGOpts, const TargetOptions &TargetOpts,
const PreprocessorOptions &PPOpts, StringRef ExistingModuleCachePath,
bool RequireStrictOptionMatches = false);

/// Returns the suggested contents of the predefines buffer,
/// which contains a (typically-empty) subset of the predefines
Expand Down
21 changes: 14 additions & 7 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ namespace clang {
class ASTContext;
class ASTReader;
class Attr;
class CodeGenOptions;
class CXXRecordDecl;
class FileEntry;
class FPOptionsOverride;
Expand Down Expand Up @@ -124,6 +125,8 @@ class ASTWriter : public ASTDeserializationListener,
/// The PCM manager which manages memory buffers for pcm files.
ModuleCache &ModCache;

const CodeGenOptions &CodeGenOpts;

/// The preprocessor we're writing.
Preprocessor *PP = nullptr;

Expand Down Expand Up @@ -686,13 +689,14 @@ class ASTWriter : public ASTDeserializationListener,
/// Create a new precompiled header writer that outputs to
/// the given bitstream.
ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
ModuleCache &ModCache,
ModuleCache &ModCache, const CodeGenOptions &CodeGenOpts,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool IncludeTimestamps = true, bool BuildingImplicitModule = false,
bool GeneratingReducedBMI = false);
~ASTWriter() override;

const LangOptions &getLangOpts() const;
const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }

/// Get a timestamp for output into the AST file. The actual timestamp
/// of the specified file may be ignored if we have been instructed to not
Expand Down Expand Up @@ -999,6 +1003,7 @@ class PCHGenerator : public SemaConsumer {
public:
PCHGenerator(Preprocessor &PP, ModuleCache &ModCache, StringRef OutputFile,
StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
const CodeGenOptions &CodeGenOpts,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors = false, bool IncludeTimestamps = true,
bool BuildingImplicitModule = false,
Expand All @@ -1021,13 +1026,14 @@ class CXX20ModulesGenerator : public PCHGenerator {
virtual Module *getEmittingModule(ASTContext &Ctx) override;

CXX20ModulesGenerator(Preprocessor &PP, ModuleCache &ModCache,
StringRef OutputFile, bool GeneratingReducedBMI,
bool AllowASTWithErrors);
StringRef OutputFile, const CodeGenOptions &CodeGenOpts,
bool GeneratingReducedBMI, bool AllowASTWithErrors);

public:
CXX20ModulesGenerator(Preprocessor &PP, ModuleCache &ModCache,
StringRef OutputFile, bool AllowASTWithErrors = false)
: CXX20ModulesGenerator(PP, ModCache, OutputFile,
StringRef OutputFile, const CodeGenOptions &CodeGenOpts,
bool AllowASTWithErrors = false)
: CXX20ModulesGenerator(PP, ModCache, OutputFile, CodeGenOpts,
/*GeneratingReducedBMI=*/false,
AllowASTWithErrors) {}

Expand All @@ -1039,8 +1045,9 @@ class ReducedBMIGenerator : public CXX20ModulesGenerator {

public:
ReducedBMIGenerator(Preprocessor &PP, ModuleCache &ModCache,
StringRef OutputFile, bool AllowASTWithErrors = false)
: CXX20ModulesGenerator(PP, ModCache, OutputFile,
StringRef OutputFile, const CodeGenOptions &CodeGenOpts,
bool AllowASTWithErrors = false)
: CXX20ModulesGenerator(PP, ModCache, OutputFile, CodeGenOpts,
/*GeneratingReducedBMI=*/true,
AllowASTWithErrors) {}
};
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Basic/CodeGenOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ void CodeGenOptions::resetNonModularOptions(StringRef ModuleFormat) {
#define CODEGENOPT(Name, Bits, Default) Name = Default;
#define ENUM_CODEGENOPT(Name, Type, Bits, Default) set##Name(Default);
// Do not reset AST affecting code generation options.
#define AFFECTING_VALUE_CODEGENOPT(Name, Bits, Default)
#define COMPATIBLE_VALUE_CODEGENOPT(Name, Bits, Default, Description)
#define COMPATIBLE_ENUM_CODEGENOPT(Name, Type, Bits, Default, Description)
#include "clang/Basic/CodeGenOptions.def"

// Next reset all debug options that can always be reset, because they never
Expand Down
Loading