-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[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
base: main
Are you sure you want to change the base?
Conversation
Some `LangOptions` duplicate their `CodeGenOptions` counterparts. My understanding is that this was done solely because some infrastructure (like serialization, module compatibility checks, etc.) were only implemented for `LangOptions`. This PR starts adds support for `CodeGenOptions`, serializes them into AST files and implements compatibility checking, which allows deduplicating some of these fields.
@llvm/pr-subscribers-clang-tidy @llvm/pr-subscribers-clang-codegen Author: Jan Svoboda (jansvoboda11) ChangesSome Patch is 71.27 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/146422.diff 30 Files Affected:
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index e5566a540dc65..0526ac2a7f2b7 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -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
@@ -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
@@ -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
@@ -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)
@@ -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
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 584c8d62280bf..49eb6c195715c 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -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 "
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 789761c1f3647..2a6eed0fdc9b3 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -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")
@@ -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")
diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h
index 1485192e8f1e3..f0076d2a7cdb0 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -107,6 +107,7 @@ class ASTUnit {
private:
std::unique_ptr<LangOptions> LangOpts;
+ std::unique_ptr<CodeGenOptions> CGOpts = std::make_unique<CodeGenOptions>();
// 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
diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h
index 604e42067a3f1..fe6dc923363d6 100644
--- a/clang/include/clang/Frontend/Utils.h
+++ b/clang/include/clang/Frontend/Utils.h
@@ -49,8 +49,7 @@ class CodeGenOptions;
/// environment ready to process a single file.
void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts,
const PCHContainerReader &PCHContainerRdr,
- const FrontendOptions &FEOpts,
- const CodeGenOptions &CodeGenOpts);
+ const FrontendOptions &FEOpts);
/// DoPrintPreprocessedInput - Implement -E mode.
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index 4d82e20e5d4f3..237ae290be698 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
#define LLVM_CLANG_LEX_PREPROCESSOR_H
+#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/IdentifierTable.h"
@@ -155,6 +156,7 @@ class Preprocessor {
const PreprocessorOptions &PPOpts;
DiagnosticsEngine *Diags;
const LangOptions &LangOpts;
+ const CodeGenOptions &CGOpts;
const TargetInfo *Target = nullptr;
const TargetInfo *AuxTarget = nullptr;
FileManager &FileMgr;
@@ -1181,8 +1183,9 @@ class Preprocessor {
public:
Preprocessor(const PreprocessorOptions &PPOpts, DiagnosticsEngine &diags,
- const LangOptions &LangOpts, SourceManager &SM,
- HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
+ const LangOptions &LangOpts, const CodeGenOptions &CGOPts,
+ SourceManager &SM, HeaderSearch &Headers,
+ ModuleLoader &TheModuleLoader,
IdentifierInfoLookup *IILookup = nullptr,
bool OwnsHeaderSearch = false,
TranslationUnitKind TUKind = TU_Complete);
@@ -1216,6 +1219,7 @@ class Preprocessor {
void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; }
const LangOptions &getLangOpts() const { return LangOpts; }
+ const CodeGenOptions &getCodeGenOpts() const { return CGOpts; }
const TargetInfo &getTargetInfo() const { return *Target; }
const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
FileManager &getFileManager() const { return FileMgr; }
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 9d265f27b8e31..441047d64f48c 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -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.
@@ -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.
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index 7d4b4467eb97d..303b4c5941877 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -72,6 +72,7 @@ class ASTContext;
class ASTDeserializationListener;
class ASTReader;
class ASTRecordReader;
+class CodeGenOptions;
class CXXTemporary;
class Decl;
class DeclarationName;
@@ -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
@@ -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;
@@ -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;
@@ -1586,6 +1602,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,
@@ -1996,14 +2016,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
diff --git a/clang/lib/Basic/CodeGenOptions.cpp b/clang/lib/Basic/CodeGenOptions.cpp
index 1f899dee48dbd..4b077c6071da5 100644
--- a/clang/lib/Basic/CodeGenOptions.cpp
+++ b/clang/lib/Basic/CodeGenOptions.cpp
@@ -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
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 3feadf1ba0c7d..f2ff0f6d55da1 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -797,7 +797,8 @@ void CGDebugInfo::CreateCompileUnit() {
// Create new compile unit.
TheCU = DBuilder.createCompileUnit(
LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer : "",
- LO.Optimize || CGOpts.PrepareForLTO || CGOpts.PrepareForThinLTO,
+ CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
+ CGOpts.PrepareForThinLTO,
CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
NameTableKind, CGOpts.DebugRangesBaseAddress, remapDIPath(Sysroot), SDK);
@@ -2273,7 +2274,7 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
Flags |= llvm::DINode::FlagRValueReference;
if (!Method->isExternallyVisible())
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
// In this debug mode, emit type info for a class when its constructor type
@@ -4344,7 +4345,7 @@ llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
FD->getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
if (!FD->isExternallyVisible())
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
if (Stub) {
@@ -4664,7 +4665,7 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
if (Fn->hasLocalLinkage())
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
@@ -4747,7 +4748,7 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
unsigned LineNo = getLineNumber(Loc);
unsigned ScopeLine = 0;
llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
@@ -5079,7 +5080,8 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
// Use VarDecl's Tag, Scope and Line number.
auto FieldAlign = getDeclAlignIfRequired(Field, CGM.getContext());
auto *D = DBuilder.createAutoVariable(
- Scope, FieldName, Unit, Line, FieldTy, CGM.getLangOpts().Optimize,
+ Scope, FieldName, Unit, Line, FieldTy,
+ CGM.getCodeGenOpts().OptimizationLevel != 0,
Flags | llvm::DINode::FlagArtificial, FieldAlign);
// Insert an llvm.dbg.declare into the current block.
@@ -5105,9 +5107,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
llvm::DILocalVariable *D = nullptr;
if (ArgNo) {
llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
- D = DBuilder.createParameterVariable(Scope, Name, *ArgNo, Unit, Line, Ty,
- CGM.getLangOpts().Optimize, Flags,
- Annotations);
+ D = DBuilder.createParameterVariable(
+ Scope, Name, *ArgNo, Unit, Line, Ty,
+ CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
} else {
// For normal local variable, we will try to find out whether 'VD' is the
// copy parameter of coroutine.
@@ -5148,8 +5150,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
D = RemapCoroArgToLocalVar();
// Or we will create a new DIVariable for this Decl if D dose not exists.
if (!D)
- D = DBuilder.createAutoVariable(Scope, Name, Unit, Line, Ty,
- CGM.getLangOpts().Optimize, Flags, Align);
+ D = DBuilder.createAutoVariable(
+ Scope, Name, Unit, Line, Ty,
+ CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
}
// Insert an llvm.dbg.declare into the current block.
DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
@@ -5203,7 +5206,7 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const BindingDecl *BD,
auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
// Create the descriptor for the variable.
llvm::DILocalVariable *D = DBuilder.createAutoVariable(
- Scope, Name, Unit, Line, Ty, CGM.getLangOpts().Optimize,
+ Scope, Name, Unit, Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
llvm::DINode::FlagZero, Align);
if (const MemberExpr *ME = dyn_cast<MemberExpr>(BD->getBinding())) {
@@ -5301,8 +5304,8 @@ void CGDebugInfo::EmitLabel(const LabelDecl *D, CGBuilderTy &Builder) {
StringRef Name = D->getName();
// Create the descriptor for the label.
- auto *L =
- DBuilder.createLabel(Scope, Name, Unit, Line, CGM.getLangOpts().Optimize);
+ auto *L = DBuilder.createLabel(Scope, Name, Unit, Line,
+ CGM.getCodeGenOpts().OptimizationLevel != 0);
// Insert an llvm.dbg.label into the current block.
DBuilder.insertLabel(L,
@@ -5565,7 +5568,8 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockIn...
[truncated]
|
@llvm/pr-subscribers-debuginfo Author: Jan Svoboda (jansvoboda11) ChangesSome Patch is 71.27 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/146422.diff 30 Files Affected:
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index e5566a540dc65..0526ac2a7f2b7 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -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
@@ -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
@@ -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
@@ -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)
@@ -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
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 584c8d62280bf..49eb6c195715c 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -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 "
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 789761c1f3647..2a6eed0fdc9b3 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -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")
@@ -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")
diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h
index 1485192e8f1e3..f0076d2a7cdb0 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -107,6 +107,7 @@ class ASTUnit {
private:
std::unique_ptr<LangOptions> LangOpts;
+ std::unique_ptr<CodeGenOptions> CGOpts = std::make_unique<CodeGenOptions>();
// 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
diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h
index 604e42067a3f1..fe6dc923363d6 100644
--- a/clang/include/clang/Frontend/Utils.h
+++ b/clang/include/clang/Frontend/Utils.h
@@ -49,8 +49,7 @@ class CodeGenOptions;
/// environment ready to process a single file.
void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts,
const PCHContainerReader &PCHContainerRdr,
- const FrontendOptions &FEOpts,
- const CodeGenOptions &CodeGenOpts);
+ const FrontendOptions &FEOpts);
/// DoPrintPreprocessedInput - Implement -E mode.
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index 4d82e20e5d4f3..237ae290be698 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
#define LLVM_CLANG_LEX_PREPROCESSOR_H
+#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/IdentifierTable.h"
@@ -155,6 +156,7 @@ class Preprocessor {
const PreprocessorOptions &PPOpts;
DiagnosticsEngine *Diags;
const LangOptions &LangOpts;
+ const CodeGenOptions &CGOpts;
const TargetInfo *Target = nullptr;
const TargetInfo *AuxTarget = nullptr;
FileManager &FileMgr;
@@ -1181,8 +1183,9 @@ class Preprocessor {
public:
Preprocessor(const PreprocessorOptions &PPOpts, DiagnosticsEngine &diags,
- const LangOptions &LangOpts, SourceManager &SM,
- HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
+ const LangOptions &LangOpts, const CodeGenOptions &CGOPts,
+ SourceManager &SM, HeaderSearch &Headers,
+ ModuleLoader &TheModuleLoader,
IdentifierInfoLookup *IILookup = nullptr,
bool OwnsHeaderSearch = false,
TranslationUnitKind TUKind = TU_Complete);
@@ -1216,6 +1219,7 @@ class Preprocessor {
void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; }
const LangOptions &getLangOpts() const { return LangOpts; }
+ const CodeGenOptions &getCodeGenOpts() const { return CGOpts; }
const TargetInfo &getTargetInfo() const { return *Target; }
const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
FileManager &getFileManager() const { return FileMgr; }
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 9d265f27b8e31..441047d64f48c 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -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.
@@ -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.
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index 7d4b4467eb97d..303b4c5941877 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -72,6 +72,7 @@ class ASTContext;
class ASTDeserializationListener;
class ASTReader;
class ASTRecordReader;
+class CodeGenOptions;
class CXXTemporary;
class Decl;
class DeclarationName;
@@ -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
@@ -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;
@@ -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;
@@ -1586,6 +1602,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,
@@ -1996,14 +2016,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
diff --git a/clang/lib/Basic/CodeGenOptions.cpp b/clang/lib/Basic/CodeGenOptions.cpp
index 1f899dee48dbd..4b077c6071da5 100644
--- a/clang/lib/Basic/CodeGenOptions.cpp
+++ b/clang/lib/Basic/CodeGenOptions.cpp
@@ -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
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 3feadf1ba0c7d..f2ff0f6d55da1 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -797,7 +797,8 @@ void CGDebugInfo::CreateCompileUnit() {
// Create new compile unit.
TheCU = DBuilder.createCompileUnit(
LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer : "",
- LO.Optimize || CGOpts.PrepareForLTO || CGOpts.PrepareForThinLTO,
+ CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
+ CGOpts.PrepareForThinLTO,
CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
NameTableKind, CGOpts.DebugRangesBaseAddress, remapDIPath(Sysroot), SDK);
@@ -2273,7 +2274,7 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
Flags |= llvm::DINode::FlagRValueReference;
if (!Method->isExternallyVisible())
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
// In this debug mode, emit type info for a class when its constructor type
@@ -4344,7 +4345,7 @@ llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
FD->getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
if (!FD->isExternallyVisible())
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
if (Stub) {
@@ -4664,7 +4665,7 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
if (Fn->hasLocalLinkage())
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
@@ -4747,7 +4748,7 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
unsigned LineNo = getLineNumber(Loc);
unsigned ScopeLine = 0;
llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
@@ -5079,7 +5080,8 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
// Use VarDecl's Tag, Scope and Line number.
auto FieldAlign = getDeclAlignIfRequired(Field, CGM.getContext());
auto *D = DBuilder.createAutoVariable(
- Scope, FieldName, Unit, Line, FieldTy, CGM.getLangOpts().Optimize,
+ Scope, FieldName, Unit, Line, FieldTy,
+ CGM.getCodeGenOpts().OptimizationLevel != 0,
Flags | llvm::DINode::FlagArtificial, FieldAlign);
// Insert an llvm.dbg.declare into the current block.
@@ -5105,9 +5107,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
llvm::DILocalVariable *D = nullptr;
if (ArgNo) {
llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
- D = DBuilder.createParameterVariable(Scope, Name, *ArgNo, Unit, Line, Ty,
- CGM.getLangOpts().Optimize, Flags,
- Annotations);
+ D = DBuilder.createParameterVariable(
+ Scope, Name, *ArgNo, Unit, Line, Ty,
+ CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
} else {
// For normal local variable, we will try to find out whether 'VD' is the
// copy parameter of coroutine.
@@ -5148,8 +5150,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
D = RemapCoroArgToLocalVar();
// Or we will create a new DIVariable for this Decl if D dose not exists.
if (!D)
- D = DBuilder.createAutoVariable(Scope, Name, Unit, Line, Ty,
- CGM.getLangOpts().Optimize, Flags, Align);
+ D = DBuilder.createAutoVariable(
+ Scope, Name, Unit, Line, Ty,
+ CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
}
// Insert an llvm.dbg.declare into the current block.
DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
@@ -5203,7 +5206,7 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const BindingDecl *BD,
auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
// Create the descriptor for the variable.
llvm::DILocalVariable *D = DBuilder.createAutoVariable(
- Scope, Name, Unit, Line, Ty, CGM.getLangOpts().Optimize,
+ Scope, Name, Unit, Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
llvm::DINode::FlagZero, Align);
if (const MemberExpr *ME = dyn_cast<MemberExpr>(BD->getBinding())) {
@@ -5301,8 +5304,8 @@ void CGDebugInfo::EmitLabel(const LabelDecl *D, CGBuilderTy &Builder) {
StringRef Name = D->getName();
// Create the descriptor for the label.
- auto *L =
- DBuilder.createLabel(Scope, Name, Unit, Line, CGM.getLangOpts().Optimize);
+ auto *L = DBuilder.createLabel(Scope, Name, Unit, Line,
+ CGM.getCodeGenOpts().OptimizationLevel != 0);
// Insert an llvm.dbg.label into the current block.
DBuilder.insertLabel(L,
@@ -5565,7 +5568,8 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockIn...
[truncated]
|
@llvm/pr-subscribers-clang-modules Author: Jan Svoboda (jansvoboda11) ChangesSome Patch is 71.27 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/146422.diff 30 Files Affected:
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index e5566a540dc65..0526ac2a7f2b7 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -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
@@ -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
@@ -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
@@ -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)
@@ -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
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 584c8d62280bf..49eb6c195715c 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -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 "
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 789761c1f3647..2a6eed0fdc9b3 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -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")
@@ -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")
diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h
index 1485192e8f1e3..f0076d2a7cdb0 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -107,6 +107,7 @@ class ASTUnit {
private:
std::unique_ptr<LangOptions> LangOpts;
+ std::unique_ptr<CodeGenOptions> CGOpts = std::make_unique<CodeGenOptions>();
// 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
diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h
index 604e42067a3f1..fe6dc923363d6 100644
--- a/clang/include/clang/Frontend/Utils.h
+++ b/clang/include/clang/Frontend/Utils.h
@@ -49,8 +49,7 @@ class CodeGenOptions;
/// environment ready to process a single file.
void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts,
const PCHContainerReader &PCHContainerRdr,
- const FrontendOptions &FEOpts,
- const CodeGenOptions &CodeGenOpts);
+ const FrontendOptions &FEOpts);
/// DoPrintPreprocessedInput - Implement -E mode.
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index 4d82e20e5d4f3..237ae290be698 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
#define LLVM_CLANG_LEX_PREPROCESSOR_H
+#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/IdentifierTable.h"
@@ -155,6 +156,7 @@ class Preprocessor {
const PreprocessorOptions &PPOpts;
DiagnosticsEngine *Diags;
const LangOptions &LangOpts;
+ const CodeGenOptions &CGOpts;
const TargetInfo *Target = nullptr;
const TargetInfo *AuxTarget = nullptr;
FileManager &FileMgr;
@@ -1181,8 +1183,9 @@ class Preprocessor {
public:
Preprocessor(const PreprocessorOptions &PPOpts, DiagnosticsEngine &diags,
- const LangOptions &LangOpts, SourceManager &SM,
- HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
+ const LangOptions &LangOpts, const CodeGenOptions &CGOPts,
+ SourceManager &SM, HeaderSearch &Headers,
+ ModuleLoader &TheModuleLoader,
IdentifierInfoLookup *IILookup = nullptr,
bool OwnsHeaderSearch = false,
TranslationUnitKind TUKind = TU_Complete);
@@ -1216,6 +1219,7 @@ class Preprocessor {
void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; }
const LangOptions &getLangOpts() const { return LangOpts; }
+ const CodeGenOptions &getCodeGenOpts() const { return CGOpts; }
const TargetInfo &getTargetInfo() const { return *Target; }
const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
FileManager &getFileManager() const { return FileMgr; }
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 9d265f27b8e31..441047d64f48c 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -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.
@@ -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.
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index 7d4b4467eb97d..303b4c5941877 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -72,6 +72,7 @@ class ASTContext;
class ASTDeserializationListener;
class ASTReader;
class ASTRecordReader;
+class CodeGenOptions;
class CXXTemporary;
class Decl;
class DeclarationName;
@@ -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
@@ -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;
@@ -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;
@@ -1586,6 +1602,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,
@@ -1996,14 +2016,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
diff --git a/clang/lib/Basic/CodeGenOptions.cpp b/clang/lib/Basic/CodeGenOptions.cpp
index 1f899dee48dbd..4b077c6071da5 100644
--- a/clang/lib/Basic/CodeGenOptions.cpp
+++ b/clang/lib/Basic/CodeGenOptions.cpp
@@ -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
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 3feadf1ba0c7d..f2ff0f6d55da1 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -797,7 +797,8 @@ void CGDebugInfo::CreateCompileUnit() {
// Create new compile unit.
TheCU = DBuilder.createCompileUnit(
LangTag, CUFile, CGOpts.EmitVersionIdentMetadata ? Producer : "",
- LO.Optimize || CGOpts.PrepareForLTO || CGOpts.PrepareForThinLTO,
+ CGOpts.OptimizationLevel != 0 || CGOpts.PrepareForLTO ||
+ CGOpts.PrepareForThinLTO,
CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.SplitDwarfFile, EmissionKind,
DwoId, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
NameTableKind, CGOpts.DebugRangesBaseAddress, remapDIPath(Sysroot), SDK);
@@ -2273,7 +2274,7 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
Flags |= llvm::DINode::FlagRValueReference;
if (!Method->isExternallyVisible())
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
// In this debug mode, emit type info for a class when its constructor type
@@ -4344,7 +4345,7 @@ llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
FD->getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
if (!FD->isExternallyVisible())
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
if (Stub) {
@@ -4664,7 +4665,7 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
if (Fn->hasLocalLinkage())
SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
@@ -4747,7 +4748,7 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
unsigned LineNo = getLineNumber(Loc);
unsigned ScopeLine = 0;
llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
- if (CGM.getLangOpts().Optimize)
+ if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
@@ -5079,7 +5080,8 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
// Use VarDecl's Tag, Scope and Line number.
auto FieldAlign = getDeclAlignIfRequired(Field, CGM.getContext());
auto *D = DBuilder.createAutoVariable(
- Scope, FieldName, Unit, Line, FieldTy, CGM.getLangOpts().Optimize,
+ Scope, FieldName, Unit, Line, FieldTy,
+ CGM.getCodeGenOpts().OptimizationLevel != 0,
Flags | llvm::DINode::FlagArtificial, FieldAlign);
// Insert an llvm.dbg.declare into the current block.
@@ -5105,9 +5107,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
llvm::DILocalVariable *D = nullptr;
if (ArgNo) {
llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(VD);
- D = DBuilder.createParameterVariable(Scope, Name, *ArgNo, Unit, Line, Ty,
- CGM.getLangOpts().Optimize, Flags,
- Annotations);
+ D = DBuilder.createParameterVariable(
+ Scope, Name, *ArgNo, Unit, Line, Ty,
+ CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Annotations);
} else {
// For normal local variable, we will try to find out whether 'VD' is the
// copy parameter of coroutine.
@@ -5148,8 +5150,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
D = RemapCoroArgToLocalVar();
// Or we will create a new DIVariable for this Decl if D dose not exists.
if (!D)
- D = DBuilder.createAutoVariable(Scope, Name, Unit, Line, Ty,
- CGM.getLangOpts().Optimize, Flags, Align);
+ D = DBuilder.createAutoVariable(
+ Scope, Name, Unit, Line, Ty,
+ CGM.getCodeGenOpts().OptimizationLevel != 0, Flags, Align);
}
// Insert an llvm.dbg.declare into the current block.
DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
@@ -5203,7 +5206,7 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const BindingDecl *BD,
auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
// Create the descriptor for the variable.
llvm::DILocalVariable *D = DBuilder.createAutoVariable(
- Scope, Name, Unit, Line, Ty, CGM.getLangOpts().Optimize,
+ Scope, Name, Unit, Line, Ty, CGM.getCodeGenOpts().OptimizationLevel != 0,
llvm::DINode::FlagZero, Align);
if (const MemberExpr *ME = dyn_cast<MemberExpr>(BD->getBinding())) {
@@ -5301,8 +5304,8 @@ void CGDebugInfo::EmitLabel(const LabelDecl *D, CGBuilderTy &Builder) {
StringRef Name = D->getName();
// Create the descriptor for the label.
- auto *L =
- DBuilder.createLabel(Scope, Name, Unit, Line, CGM.getLangOpts().Optimize);
+ auto *L = DBuilder.createLabel(Scope, Name, Unit, Line,
+ CGM.getCodeGenOpts().OptimizationLevel != 0);
// Insert an llvm.dbg.label into the current block.
DBuilder.insertLabel(L,
@@ -5565,7 +5568,8 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockIn...
[truncated]
|
A bit off-topic, but I'd suggest to separate NFC formatting changes from functional. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has a stronger impact on C++20 modules since C++20 modules need to generate codes.
How does this patch handle consistency issue? e.g., What if a.pcm
is compiled with -O0
but the consumer is compiled with -O1
? I hope we won't break such things.
Some
LangOptions
duplicate theirCodeGenOptions
counterparts. My understanding is that this was done solely because some infrastructure (like preprocessor initialization, serialization, module compatibility checks, etc.) were only possible/convenient forLangOptions
. This PR implements the missing support forCodeGenOptions
, which makes it possible to remove some duplicateLangOptions
fields and simplify the logic. Motivated by #146342.