Skip to content

[clang][deps] Cherry-pick the 1st batch of performance improvements #7206

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

Merged
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
4 changes: 4 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -2443,6 +2443,10 @@ defm modules_search_all : BoolFOption<"modules-search-all",
defm implicit_modules : BoolFOption<"implicit-modules",
LangOpts<"ImplicitModules">, DefaultTrue,
NegFlag<SetFalse, [CC1Option]>, PosFlag<SetTrue>, BothFlags<[NoXarchOption,CoreOption]>>;
def fno_modules_check_relocated : Joined<["-"], "fno-modules-check-relocated">,
Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Skip checks for relocated modules when loading PCM files">,
MarshallingInfoNegativeFlag<PreprocessorOpts<"ModulesCheckRelocated">>;
def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>,
MarshallingInfoFlag<LangOpts<"RetainCommentsFromSystemHeaders">>;
def fmodule_header : Flag <["-"], "fmodule-header">, Group<f_Group>,
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Lex/Preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,7 @@ class Preprocessor {

/// Return true if this header has already been included.
bool alreadyIncluded(const FileEntry *File) const {
HeaderInfo.getFileInfo(File);
return IncludedFiles.count(File);
}

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Lex/PreprocessorOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ class PreprocessorOptions {
std::vector<std::string> Includes;
std::vector<std::string> MacroIncludes;

/// Perform extra checks when loading PCM files for mutable file systems.
bool ModulesCheckRelocated = true;

/// Initialize the preprocessor with the compiler and target specific
/// predefines.
bool UsePredefines = true;
Expand Down
5 changes: 2 additions & 3 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,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 = 26;
const unsigned VERSION_MAJOR = 27;

/// AST file minor version number supported by this version of
/// Clang.
Expand Down Expand Up @@ -707,8 +707,7 @@ enum ASTRecordTypes {
/// Record code for \#pragma float_control options.
FLOAT_CONTROL_PRAGMA_OPTIONS = 65,

/// Record code for included files.
PP_INCLUDED_FILES = 66,
/// ID 66 used to be the list of included files.

/// Record code for an unterminated \#pragma clang assume_nonnull begin
/// recorded in a preamble.
Expand Down
1 change: 0 additions & 1 deletion clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -1379,7 +1379,6 @@ class ASTReader
llvm::Error ReadSourceManagerBlock(ModuleFile &F);
llvm::BitstreamCursor &SLocCursorForID(int ID);
SourceLocation getImportLocation(ModuleFile *F);
void readIncludedFiles(ModuleFile &F, StringRef Blob, Preprocessor &PP);
ASTReadResult ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
const ModuleFile *ImportedBy,
unsigned ClientLoadCapabilities);
Expand Down
1 change: 0 additions & 1 deletion clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,6 @@ class ASTWriter : public ASTDeserializationListener,
void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts);
void WriteSourceManagerBlock(SourceManager &SourceMgr,
const Preprocessor &PP);
void writeIncludedFiles(raw_ostream &Out, const Preprocessor &PP);
void WritePreprocessor(const Preprocessor &PP, bool IsModule);
void WriteHeaderSearch(const HeaderSearch &HS);
void WritePreprocessorDetail(PreprocessingRecord &PPRec,
Expand Down
20 changes: 10 additions & 10 deletions clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,10 @@ class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
#undef ANALYZER_OPTION
#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE

// Create an array of all -analyzer-config command line options. Sort it in
// the constructor.
std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = {
bool isUnknownAnalyzerConfig(llvm::StringRef Name) {
static std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = []() {
// Create an array of all -analyzer-config command line options.
std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = {
#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
SHALLOW_VAL, DEEP_VAL) \
ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
Expand All @@ -274,10 +275,11 @@ class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
#undef ANALYZER_OPTION
#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
};

bool isUnknownAnalyzerConfig(StringRef Name) const {
assert(llvm::is_sorted(AnalyzerConfigCmdFlags));
};
// FIXME: Sort this at compile-time when we get constexpr sort (C++20).
llvm::sort(AnalyzerConfigCmdFlags);
return AnalyzerConfigCmdFlags;
}();

return !std::binary_search(AnalyzerConfigCmdFlags.begin(),
AnalyzerConfigCmdFlags.end(), Name);
Expand All @@ -293,9 +295,7 @@ class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
AnalyzerDisplayProgress(false), eagerlyAssumeBinOpBifurcation(false),
TrimGraph(false), visualizeExplodedGraphWithGraphViz(false),
UnoptimizedCFG(false), PrintStats(false), NoRetryExhausted(false),
AnalyzerWerror(false) {
llvm::sort(AnalyzerConfigCmdFlags);
}
AnalyzerWerror(false) {}

/// Interprets an option's string value as a boolean. The "true" string is
/// interpreted as true and the "false" string is interpreted as false.
Expand Down
5 changes: 1 addition & 4 deletions clang/lib/Lex/HeaderSearch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1735,9 +1735,6 @@ HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) {

Module *HeaderSearch::loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir,
bool IsSystem) {
if (Module *Module = ModMap.findModule(Name))
return Module;

// Try to load a module map file.
switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) {
case LMM_InvalidModuleMap:
Expand All @@ -1746,10 +1743,10 @@ Module *HeaderSearch::loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir,
ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr);
break;

case LMM_AlreadyLoaded:
case LMM_NoDirectory:
return nullptr;

case LMM_AlreadyLoaded:
case LMM_NewlyLoaded:
break;
}
Expand Down
43 changes: 38 additions & 5 deletions clang/lib/Lex/ModuleMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ Module *ModuleMap::findModule(StringRef Name) const {
if (Known != Modules.end()) {
Module *M = Known->getValue();
// Notify callbacks that we found a module map for the module.
if (!M->DefinitionLoc.isInvalid())
if (M->DefinitionLoc.isValid() && !M->IsFromModuleFile)
for (const auto &Cb : Callbacks)
Cb->moduleMapFoundForModule(
**getContainingModuleMapFile(M), M,
Expand Down Expand Up @@ -1265,6 +1265,20 @@ void ModuleMap::resolveHeaderDirectives(
Mod->UnresolvedHeaders.swap(NewHeaders);
}

// FIXME: duplicates code in PPDirectives
static bool isForModuleBuilding(const Module *M, StringRef CurrentModule,
StringRef ModuleName) {
StringRef TopLevelName = M->getTopLevelModuleName();

// When building framework Foo, we wanna make sure that Foo *and* Foo_Private
// are textually included and no modules are built for both.
if (M->getTopLevelModule()->IsFramework && CurrentModule == ModuleName &&
!CurrentModule.endswith("_Private") && TopLevelName.endswith("_Private"))
TopLevelName = TopLevelName.drop_back(8);

return TopLevelName == CurrentModule;
}

void ModuleMap::addHeader(Module *Mod, Module::Header Header,
ModuleHeaderRole Role, bool Imported) {
KnownHeader KH(Mod, Role);
Expand All @@ -1280,7 +1294,7 @@ void ModuleMap::addHeader(Module *Mod, Module::Header Header,
Mod->Headers[headerRoleToKind(Role)].push_back(Header);

bool isCompilingModuleHeader =
LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
isForModuleBuilding(Mod, LangOpts.CurrentModule, LangOpts.ModuleName);
if (!Imported || isCompilingModuleHeader) {
// When we import HeaderFileInfo, the external source is expected to
// set the isModuleHeader flag itself.
Expand Down Expand Up @@ -2040,18 +2054,37 @@ void ModuleMapParser::parseModuleDecl() {
Module *ShadowingModule = nullptr;
if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
// We might see a (re)definition of a module that we already have a
// definition for in two cases:
// definition for in four cases:
// - If we loaded one definition from an AST file and we've just found a
// corresponding definition in a module map file, or
bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid();
bool LoadedFromASTFile = Existing->IsFromModuleFile;
// - If we previously inferred this module from different module map file.
bool Inferred = Existing->IsInferred;
// - If we're building a framework that vends a module map, we might've
// previously seen the one in intermediate products and now the system
// one.
// FIXME: If we're parsing module map file that looks like this:
// framework module FW { ... }
// module FW.Sub { ... }
// We can't check the framework qualifier, since it's not attached to
// the definition of Sub. Checking that qualifier on \c Existing is
// not correct either, since we might've previously seen:
// module FW { ... }
// module FW.Sub { ... }
// We should enforce consistency of redefinitions so that we can rely
// that \c Existing is part of a framework iff the redefinition of FW
// we have just skipped had it too. Once we do that, stop checking
// the local framework qualifier and only rely on \c Existing.
bool PartOfFramework = Framework || Existing->isPartOfFramework();
// - If we're building a (preprocessed) module and we've just loaded the
// module map file from which it was created.
bool ParsedAsMainInput =
Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
Map.LangOpts.CurrentModule == ModuleName &&
SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) {
ActiveModule = PreviousActiveModule;
// Skip the module definition.
skipUntil(MMToken::RBrace);
if (Tok.is(MMToken::RBrace))
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Sema/SemaModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,10 @@ Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc,
// module map defining it already.
if (auto *M = Map.findModule(ModuleName)) {
Diag(Path[0].second, diag::err_module_redefinition) << ModuleName;
if (M->DefinitionLoc.isValid())
if (M->DefinitionLoc.isValid() && !M->IsFromModuleFile)
Diag(M->DefinitionLoc, diag::note_prev_module_definition);
else if (Optional<FileEntryRef> FE = M->getASTFile())
Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file)
Diag(SourceLocation(), diag::note_prev_module_definition_from_ast_file)
<< FE->getName();
Mod = M;
break;
Expand Down
Loading