[clang] 10c0eca - [clang][Lexer] Speed up HeaderSearch when there are many HeaderMaps
Author: Troy Johnson Date: 2022-10-18T08:21:14-07:00 New Revision: 10c0eca25523e3bf1872522bde4693aaa55513e0 URL: https://github.com/llvm/llvm-project/commit/10c0eca25523e3bf1872522bde4693aaa55513e0 DIFF: https://github.com/llvm/llvm-project/commit/10c0eca25523e3bf1872522bde4693aaa55513e0.diff LOG: [clang][Lexer] Speed up HeaderSearch when there are many HeaderMaps HeaderSearch already uses a caching system to avoid duplicate searches, but the initial cold miss can take a long time if a build system has supplied thousands of HeaderMaps. For this case, the SearchDirs vector begins with those HeaderMaps, so a cache miss requires testing if the sought filename is present in each of those maps. Instead, we can consolidate the keys of those HeaderMaps into one StringMap and then each cache miss can skip directly to the correct HeaderMap or continue its search beyond the initial sequence of HeaderMaps. In testing on TUs with ~15000 SearchDirs where the initial 99% are HeaderMaps, time spent in Clang was reduced by 15%. This patch is expected to be neutral for SearchDir vectors that do not begin with HeaderMaps. Differential Revision: https://reviews.llvm.org/D135801 Added: Modified: clang/include/clang/Lex/HeaderMap.h clang/include/clang/Lex/HeaderSearch.h clang/lib/Lex/HeaderSearch.cpp Removed: diff --git a/clang/include/clang/Lex/HeaderMap.h b/clang/include/clang/Lex/HeaderMap.h index ca6a49bae3bfe..7930cb83598ca 100644 --- a/clang/include/clang/Lex/HeaderMap.h +++ b/clang/include/clang/Lex/HeaderMap.h @@ -15,6 +15,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/LLVM.h" +#include "clang/Lex/HeaderMapTypes.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/Compiler.h" @@ -39,6 +40,21 @@ class HeaderMapImpl { // Check for a valid header and extract the byte swap. static bool checkHeader(const llvm::MemoryBuffer &File, bool &NeedsByteSwap); + // Make a call for every Key in the map. + template void forEachKey(Func Callback) const { +const HMapHeader &Hdr = getHeader(); +unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets); + +for (unsigned Bucket = 0; Bucket < NumBuckets; ++Bucket) { + HMapBucket B = getBucket(Bucket); + if (B.Key != HMAP_EmptyBucketKey) { +Optional Key = getString(B.Key); +if (Key) + Callback(Key.value()); + } +} + } + /// If the specified relative filename is located in this HeaderMap return /// the filename it is mapped to, otherwise return an empty StringRef. StringRef lookupFilename(StringRef Filename, @@ -78,6 +94,7 @@ class HeaderMap : private HeaderMapImpl { FileManager &FM); using HeaderMapImpl::dump; + using HeaderMapImpl::forEachKey; using HeaderMapImpl::getFileName; using HeaderMapImpl::lookupFilename; using HeaderMapImpl::reverseLookupFilename; diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h index d4b2306096972..4684f554dc24d 100644 --- a/clang/include/clang/Lex/HeaderSearch.h +++ b/clang/include/clang/Lex/HeaderSearch.h @@ -249,6 +249,14 @@ class HeaderSearch { unsigned SystemDirIdx = 0; bool NoCurDirSearch = false; + /// Maps HeaderMap keys to SearchDir indices. When HeaderMaps are used + /// heavily, SearchDirs can start with thousands of HeaderMaps, so this Index + /// lets us avoid scanning them all to find a match. + llvm::StringMap SearchDirHeaderMapIndex; + + /// The index of the first SearchDir that isn't a header map. + unsigned FirstNonHeaderMapSearchDirIdx = 0; + /// \#include prefixes for which the 'system header' property is /// overridden. /// @@ -330,6 +338,10 @@ class HeaderSearch { /// Entity used to look up stored header file information. ExternalHeaderFileInfoSource *ExternalSource = nullptr; + /// Scan all of the header maps at the beginning of SearchDirs and + /// map their keys to the SearchDir index of their header map. + void indexInitialHeaderMaps(); + public: HeaderSearch(std::shared_ptr HSOpts, SourceManager &SourceMgr, DiagnosticsEngine &Diags, @@ -801,6 +813,10 @@ class HeaderSearch { } ConstSearchDirIterator search_dir_begin() const { return quoted_dir_begin(); } + ConstSearchDirIterator search_dir_nth(size_t n) const { +assert(n < SearchDirs.size()); +return {*this, n}; + } ConstSearchDirIterator search_dir_end() const { return system_dir_end(); } ConstSearchDirRange search_dir_range() const { return {search_dir_begin(), search_dir_end()}; diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index bd69d8f697de8..dd82f4280edb5 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -116,6 +116,7 @@ void HeaderSearch::SetSearchPaths( NoCurDirSearch = n
[clang] 488cf10 - [clang][Sema][NFC] Remove redundant isTypeValid
Author: Troy Johnson Date: 2022-10-27T12:48:11-07:00 New Revision: 488cf1038c88a6d7e5378d493a253e1dc6a97cd9 URL: https://github.com/llvm/llvm-project/commit/488cf1038c88a6d7e5378d493a253e1dc6a97cd9 DIFF: https://github.com/llvm/llvm-project/commit/488cf1038c88a6d7e5378d493a253e1dc6a97cd9.diff LOG: [clang][Sema][NFC] Remove redundant isTypeValid These isTypeValid calls are redundant because the isDerivedFrom call performs the same checks. Differential Revision: https://reviews.llvm.org/D136190 Added: Modified: clang/lib/Sema/SemaOverload.cpp Removed: diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 2190720bdc2de..d21de7db3f53b 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -4606,15 +4606,6 @@ CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc, return ImplicitConversionSequence::Indistinguishable; } -/// Determine whether the given type is valid, e.g., it is not an invalid -/// C++ class. -static bool isTypeValid(QualType T) { - if (CXXRecordDecl *Record = T->getAsCXXRecordDecl()) -return !Record->isInvalidDecl(); - - return true; -} - static QualType withoutUnaligned(ASTContext &Ctx, QualType T) { if (!T.getQualifiers().hasUnaligned()) return T; @@ -4664,7 +4655,6 @@ Sema::CompareReferenceRelationship(SourceLocation Loc, if (UnqualT1 == UnqualT2) { // Nothing to do. } else if (isCompleteType(Loc, OrigT2) && - isTypeValid(UnqualT1) && isTypeValid(UnqualT2) && IsDerivedFrom(Loc, UnqualT2, UnqualT1)) Conv |= ReferenceConversions::DerivedToBase; else if (UnqualT1->isObjCObjectOrInterfaceType() && ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 00022c5 - [clang][Lex] Header map search case insensitivity
Author: Troy Johnson Date: 2022-11-01T11:33:00-07:00 New Revision: 00022c5613a7490148ae1147e25a695fc59c5f92 URL: https://github.com/llvm/llvm-project/commit/00022c5613a7490148ae1147e25a695fc59c5f92 DIFF: https://github.com/llvm/llvm-project/commit/00022c5613a7490148ae1147e25a695fc59c5f92.diff LOG: [clang][Lex] Header map search case insensitivity Correct D135801 to be case insensitive. Differential Revision: https://reviews.llvm.org/D137179 Added: Modified: clang/lib/Lex/HeaderSearch.cpp Removed: diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index 65316f4e79617..e6af122949709 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -388,7 +388,9 @@ void HeaderSearch::indexInitialHeaderMaps() { break; // Give earlier keys precedence over identical later keys. -auto Callback = [&](StringRef Filename) { Index.try_emplace(Filename, i); }; +auto Callback = [&](StringRef Filename) { + Index.try_emplace(Filename.lower(), i); +}; Dir.getHeaderMap()->forEachKey(Callback); } @@ -1021,7 +1023,7 @@ Optional HeaderSearch::LookupFile( // Handle cold misses of user includes in the presence of many header // maps. We avoid searching perhaps thousands of header maps by // jumping directly to the correct one or jumping beyond all of them. -auto Iter = SearchDirHeaderMapIndex.find(Filename); +auto Iter = SearchDirHeaderMapIndex.find(Filename.lower()); if (Iter == SearchDirHeaderMapIndex.end()) // Not in index => Skip to first SearchDir after initial header maps It = search_dir_nth(FirstNonHeaderMapSearchDirIdx); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] b62f5fb - [Clang][Sema] Narrow inline namespace filtration for unqualified friend declarations
Author: Troy Johnson Date: 2022-10-10T08:34:14-07:00 New Revision: b62f5fb64edec7f5917a233bf0a9a30e1e4b70f0 URL: https://github.com/llvm/llvm-project/commit/b62f5fb64edec7f5917a233bf0a9a30e1e4b70f0 DIFF: https://github.com/llvm/llvm-project/commit/b62f5fb64edec7f5917a233bf0a9a30e1e4b70f0.diff LOG: [Clang][Sema] Narrow inline namespace filtration for unqualified friend declarations rG04ba1856 introduced a call to FilterLookupForScope that is expensive for very large translation units where it was observed to cause a 6% compile time degradation. As the comment states, the only effect is to "remove declarations found in inline namespaces for friend declarations with unqualified names." This change limits the call to that scenario. The test that was added by rG04ba1856 continues to pass, but the observed degradation is cut in half. Differential Revision: https://reviews.llvm.org/D135370 Added: Modified: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp Removed: diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index b50ed6478e4b..dfae70209210 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2273,9 +2273,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl( // Filter out previous declarations that don't match the scope. The only // effect this has is to remove declarations found in inline namespaces // for friend declarations with unqualified names. -SemaRef.FilterLookupForScope(Previous, DC, /*Scope*/ nullptr, - /*ConsiderLinkage*/ true, - QualifierLoc.hasQualifier()); +if (isFriend && !QualifierLoc && !FunctionTemplate) { + SemaRef.FilterLookupForScope(Previous, DC, /*Scope=*/ nullptr, + /*ConsiderLinkage=*/ true, + QualifierLoc.hasQualifier()); +} } // Per [temp.inst], default arguments in function declarations at local scope ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 8628ed0 - [Driver] Allow both lib64 and lib in rocm-detect test.
Author: Troy Johnson Date: 2021-04-16T09:55:57-05:00 New Revision: 8628ed0310e2fc97e1536a8032327d746973069a URL: https://github.com/llvm/llvm-project/commit/8628ed0310e2fc97e1536a8032327d746973069a DIFF: https://github.com/llvm/llvm-project/commit/8628ed0310e2fc97e1536a8032327d746973069a.diff LOG: [Driver] Allow both lib64 and lib in rocm-detect test. Differential Revision: https://reviews.llvm.org/D100502 Added: Modified: clang/test/Driver/rocm-detect.hip Removed: diff --git a/clang/test/Driver/rocm-detect.hip b/clang/test/Driver/rocm-detect.hip index 5df5d2a9be067..68ae1edb4eb26 100644 --- a/clang/test/Driver/rocm-detect.hip +++ b/clang/test/Driver/rocm-detect.hip @@ -81,7 +81,7 @@ // SPACK: ROCm installation search path (Spack 4.0.0): [[DIR:.*]] // SPACK: ROCm installation search path: [[CLANG:.*]] -// SPACK: ROCm installation search path: [[CLANG]]/{{(llvm/)?}}lib/clang/{{[0-9.]+}} +// SPACK: ROCm installation search path: [[CLANG]]/{{(llvm/)?}}lib{{[0-9]*}}/clang/{{[0-9.]+}} // SPACK: ROCm installation search path: /opt/rocm // SPACK: InstalledDir: [[DIR]]/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin // SPACK: Found HIP installation: [[DIR]]/hip-4.0.0-5f63slrursbrvfe2txrrjkynbsywsob5, version 4.0.20214-a2917cd ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits