[clang-tools-extra] a199d8f - [clang-tidy][NFC] Improve compilation time of IntegralLiteralExpressionMatcher

Piotr Zegar via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 31 12:23:04 PDT 2023


Author: Piotr Zegar
Date: 2023-08-31T19:22:17Z
New Revision: a199d8fac027c226577ffb0c47b014015980dbb5

URL: https://github.com/llvm/llvm-project/commit/a199d8fac027c226577ffb0c47b014015980dbb5
DIFF: https://github.com/llvm/llvm-project/commit/a199d8fac027c226577ffb0c47b014015980dbb5.diff

LOG: [clang-tidy][NFC] Improve compilation time of IntegralLiteralExpressionMatcher

When using agressive inlining -Xclang -mllvm -Xclang -inline-threshold=500,
this file takes 10-18 min to compile. This is caused by in-direct recursion.
Looks like transforming code to use templates and lambdas instead of
std::function and member function pointer reduces this time to 0.5s.

Fixes: #59658

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.cpp
    clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.h

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.cpp b/clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.cpp
index 9b97b46d580eeda..ecf3a18199ffec4 100644
--- a/clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.cpp
@@ -10,7 +10,6 @@
 
 #include <algorithm>
 #include <cctype>
-#include <stdexcept>
 
 namespace clang::tidy::modernize {
 
@@ -48,10 +47,10 @@ bool IntegralLiteralExpressionMatcher::consume(tok::TokenKind Kind) {
   return false;
 }
 
+template <typename NonTerminalFunctor, typename IsKindFunctor>
 bool IntegralLiteralExpressionMatcher::nonTerminalChainedExpr(
-    bool (IntegralLiteralExpressionMatcher::*NonTerminal)(),
-    const std::function<bool(Token)> &IsKind) {
-  if (!(this->*NonTerminal)())
+    const NonTerminalFunctor &NonTerminal, const IsKindFunctor &IsKind) {
+  if (!NonTerminal())
     return false;
   if (Current == End)
     return true;
@@ -63,13 +62,28 @@ bool IntegralLiteralExpressionMatcher::nonTerminalChainedExpr(
     if (!advance())
       return false;
 
-    if (!(this->*NonTerminal)())
+    if (!NonTerminal())
       return false;
   }
 
   return true;
 }
 
+template <tok::TokenKind Kind, typename NonTerminalFunctor>
+bool IntegralLiteralExpressionMatcher::nonTerminalChainedExpr(
+    const NonTerminalFunctor &NonTerminal) {
+  return nonTerminalChainedExpr(NonTerminal,
+                                [](Token Tok) { return Tok.is(Kind); });
+}
+
+template <tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind... Ks,
+          typename NonTerminalFunctor>
+bool IntegralLiteralExpressionMatcher::nonTerminalChainedExpr(
+    const NonTerminalFunctor &NonTerminal) {
+  return nonTerminalChainedExpr(
+      NonTerminal, [](Token Tok) { return Tok.isOneOf(K1, K2, Ks...); });
+}
+
 // Advance over unary operators.
 bool IntegralLiteralExpressionMatcher::unaryOperator() {
   if (Current->isOneOf(tok::TokenKind::minus, tok::TokenKind::plus,
@@ -155,18 +169,18 @@ bool IntegralLiteralExpressionMatcher::unaryExpr() {
 bool IntegralLiteralExpressionMatcher::multiplicativeExpr() {
   return nonTerminalChainedExpr<tok::TokenKind::star, tok::TokenKind::slash,
                                 tok::TokenKind::percent>(
-      &IntegralLiteralExpressionMatcher::unaryExpr);
+      [this] { return unaryExpr(); });
 }
 
 bool IntegralLiteralExpressionMatcher::additiveExpr() {
   return nonTerminalChainedExpr<tok::plus, tok::minus>(
-      &IntegralLiteralExpressionMatcher::multiplicativeExpr);
+      [this] { return multiplicativeExpr(); });
 }
 
 bool IntegralLiteralExpressionMatcher::shiftExpr() {
   return nonTerminalChainedExpr<tok::TokenKind::lessless,
                                 tok::TokenKind::greatergreater>(
-      &IntegralLiteralExpressionMatcher::additiveExpr);
+      [this] { return additiveExpr(); });
 }
 
 bool IntegralLiteralExpressionMatcher::compareExpr() {
@@ -190,38 +204,38 @@ bool IntegralLiteralExpressionMatcher::relationalExpr() {
   return nonTerminalChainedExpr<tok::TokenKind::less, tok::TokenKind::greater,
                                 tok::TokenKind::lessequal,
                                 tok::TokenKind::greaterequal>(
-      &IntegralLiteralExpressionMatcher::compareExpr);
+      [this] { return compareExpr(); });
 }
 
 bool IntegralLiteralExpressionMatcher::equalityExpr() {
   return nonTerminalChainedExpr<tok::TokenKind::equalequal,
                                 tok::TokenKind::exclaimequal>(
-      &IntegralLiteralExpressionMatcher::relationalExpr);
+      [this] { return relationalExpr(); });
 }
 
 bool IntegralLiteralExpressionMatcher::andExpr() {
   return nonTerminalChainedExpr<tok::TokenKind::amp>(
-      &IntegralLiteralExpressionMatcher::equalityExpr);
+      [this] { return equalityExpr(); });
 }
 
 bool IntegralLiteralExpressionMatcher::exclusiveOrExpr() {
   return nonTerminalChainedExpr<tok::TokenKind::caret>(
-      &IntegralLiteralExpressionMatcher::andExpr);
+      [this] { return andExpr(); });
 }
 
 bool IntegralLiteralExpressionMatcher::inclusiveOrExpr() {
   return nonTerminalChainedExpr<tok::TokenKind::pipe>(
-      &IntegralLiteralExpressionMatcher::exclusiveOrExpr);
+      [this] { return exclusiveOrExpr(); });
 }
 
 bool IntegralLiteralExpressionMatcher::logicalAndExpr() {
   return nonTerminalChainedExpr<tok::TokenKind::ampamp>(
-      &IntegralLiteralExpressionMatcher::inclusiveOrExpr);
+      [this] { return inclusiveOrExpr(); });
 }
 
 bool IntegralLiteralExpressionMatcher::logicalOrExpr() {
   return nonTerminalChainedExpr<tok::TokenKind::pipepipe>(
-      &IntegralLiteralExpressionMatcher::logicalAndExpr);
+      [this] { return logicalAndExpr(); });
 }
 
 bool IntegralLiteralExpressionMatcher::conditionalExpr() {
@@ -263,12 +277,10 @@ bool IntegralLiteralExpressionMatcher::conditionalExpr() {
 }
 
 bool IntegralLiteralExpressionMatcher::commaExpr() {
-  auto Pred = CommaAllowed
-                  ? std::function<bool(Token)>(
-                        [](Token Tok) { return Tok.is(tok::TokenKind::comma); })
-                  : std::function<bool(Token)>([](Token) { return false; });
-  return nonTerminalChainedExpr(
-      &IntegralLiteralExpressionMatcher::conditionalExpr, Pred);
+  auto NonTerminal = [this] { return conditionalExpr(); };
+  if (CommaAllowed)
+    return nonTerminalChainedExpr<tok::TokenKind::comma>(NonTerminal);
+  return nonTerminalChainedExpr(NonTerminal, [](Token) { return false; });
 }
 
 bool IntegralLiteralExpressionMatcher::expr() { return commaExpr(); }

diff  --git a/clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.h b/clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.h
index e8ccb5bd8df9f0b..22893784b07f88f 100644
--- a/clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.h
+++ b/clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.h
@@ -39,21 +39,14 @@ class IntegralLiteralExpressionMatcher {
 private:
   bool advance();
   bool consume(tok::TokenKind Kind);
-  bool nonTerminalChainedExpr(
-      bool (IntegralLiteralExpressionMatcher::*NonTerminal)(),
-      const std::function<bool(Token)> &IsKind);
-  template <tok::TokenKind Kind>
-  bool nonTerminalChainedExpr(
-      bool (IntegralLiteralExpressionMatcher::*NonTerminal)()) {
-    return nonTerminalChainedExpr(NonTerminal,
-                                  [](Token Tok) { return Tok.is(Kind); });
-  }
-  template <tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind... Ks>
-  bool nonTerminalChainedExpr(
-      bool (IntegralLiteralExpressionMatcher::*NonTerminal)()) {
-    return nonTerminalChainedExpr(
-        NonTerminal, [](Token Tok) { return Tok.isOneOf(K1, K2, Ks...); });
-  }
+  template <typename NonTerminalFunctor, typename IsKindFunctor>
+  bool nonTerminalChainedExpr(const NonTerminalFunctor &NonTerminal,
+                              const IsKindFunctor &IsKind);
+  template <tok::TokenKind Kind, typename NonTerminalFunctor>
+  bool nonTerminalChainedExpr(const NonTerminalFunctor &NonTerminal);
+  template <tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind... Ks,
+            typename NonTerminalFunctor>
+  bool nonTerminalChainedExpr(const NonTerminalFunctor &NonTerminal);
 
   bool unaryOperator();
   bool unaryExpr();


        


More information about the cfe-commits mailing list