Author: alexfh Date: Wed May 17 20:13:51 2017 New Revision: 303321 URL: http://llvm.org/viewvc/llvm-project?rev=303321&view=rev Log: [clang-tidy] Optimize GlobList::contains
With large lists of checks and large number of warnings GlobList::contains starts being ridiculously CPU hungry, since it runs regexp match per glob. Caching results of glob matching in a StringMap significantly speeds up check filtering even for small GlobLists. /tmp/q.cc: void f() { int I; {int I;} {int I;} {int I;} ... // 200k times } Before the patch: GlobList with 2 entries: $ time clang-tidy-old -checks=-*,modernize-use-override /tmp/q.cc -- -Wshadow 200000 warnings generated. Suppressed 200000 warnings (200000 with check filters). real 0m3.826s user 0m3.176s sys 0m0.504s GlobList with 28 entries: $ time clang-tidy-old -checks=-*,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,modernize-use-override /tmp/q.cc -- -Wshadow 200000 warnings generated. Suppressed 200000 warnings (200000 with check filters). real 0m5.000s user 0m4.744s sys 0m0.060s GlobList with 158 entries: $ time clang-tidy-old -checks=-*,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,modernize-use-override /tmp/q.cc -- -Wshadow 200000 warnings generated. Suppressed 200000 warnings (200000 with check filters). real 0m13.920s user 0m13.636s sys 0m0.104s With the patch runtime is practically independent from the length of the GlobList: $ time clang-tidy-new -checks=-*,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,modernize-use-override /tmp/q.cc -- -Wshadow 200000 warnings generated. Suppressed 200000 warnings (200000 with check filters). real 0m2.300s user 0m2.104s sys 0m0.044s Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp?rev=303321&r1=303320&r2=303321&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp Wed May 17 20:13:51 2017 @@ -158,6 +158,26 @@ bool GlobList::contains(StringRef S, boo return Contains; } +class ClangTidyContext::CachedGlobList { +public: + CachedGlobList(StringRef Globs) : Globs(Globs) {} + + bool contains(StringRef S) { + switch (auto &Result = Cache[S]) { + case Yes: return true; + case No: return false; + case None: + Result = Globs.contains(S) ? Yes : No; + return Result == Yes; + } + } + +private: + GlobList Globs; + enum Tristate { None, Yes, No }; + llvm::StringMap<Tristate> Cache; +}; + ClangTidyContext::ClangTidyContext( std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider) : DiagEngine(nullptr), OptionsProvider(std::move(OptionsProvider)), @@ -167,6 +187,8 @@ ClangTidyContext::ClangTidyContext( setCurrentFile(""); } +ClangTidyContext::~ClangTidyContext() = default; + DiagnosticBuilder ClangTidyContext::diag( StringRef CheckName, SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level /* = DiagnosticIDs::Warning*/) { @@ -188,8 +210,9 @@ void ClangTidyContext::setSourceManager( void ClangTidyContext::setCurrentFile(StringRef File) { CurrentFile = File; CurrentOptions = getOptionsForFile(CurrentFile); - CheckFilter.reset(new GlobList(*getOptions().Checks)); - WarningAsErrorFilter.reset(new GlobList(*getOptions().WarningsAsErrors)); + CheckFilter = llvm::make_unique<CachedGlobList>(*getOptions().Checks); + WarningAsErrorFilter = + llvm::make_unique<CachedGlobList>(*getOptions().WarningsAsErrors); } void ClangTidyContext::setASTContext(ASTContext *Context) { @@ -243,9 +266,9 @@ ClangTidyDiagnosticConsumer::ClangTidyDi LastErrorRelatesToUserCode(false), LastErrorPassesLineFilter(false), LastErrorWasIgnored(false) { IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); - Diags.reset(new DiagnosticsEngine( + Diags = llvm::make_unique<DiagnosticsEngine>( IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts, this, - /*ShouldOwnClient=*/false)); + /*ShouldOwnClient=*/false); Context.setDiagnosticsEngine(Diags.get()); } @@ -461,8 +484,8 @@ void ClangTidyDiagnosticConsumer::checkF llvm::Regex *ClangTidyDiagnosticConsumer::getHeaderFilter() { if (!HeaderFilter) - HeaderFilter.reset( - new llvm::Regex(*Context.getOptions().HeaderFilterRegex)); + HeaderFilter = + llvm::make_unique<llvm::Regex>(*Context.getOptions().HeaderFilterRegex); return HeaderFilter.get(); } Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h?rev=303321&r1=303320&r2=303321&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h Wed May 17 20:13:51 2017 @@ -106,6 +106,8 @@ public: /// \brief Initializes \c ClangTidyContext instance. ClangTidyContext(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider); + ~ClangTidyContext(); + /// \brief Report any errors detected using this method. /// /// This is still under heavy development and will likely change towards using @@ -202,8 +204,9 @@ private: std::string CurrentFile; ClangTidyOptions CurrentOptions; - std::unique_ptr<GlobList> CheckFilter; - std::unique_ptr<GlobList> WarningAsErrorFilter; + class CachedGlobList; + std::unique_ptr<CachedGlobList> CheckFilter; + std::unique_ptr<CachedGlobList> WarningAsErrorFilter; LangOptions LangOpts; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits