[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