From 74c4daaadf485a951f1474ae94ed3c7dbdf87c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Fri, 18 Aug 2023 20:41:50 +0200 Subject: [PATCH] optimized `Token::Match()` a bit by always inlining `Token::multiCompare()` (#5332) Scanning `mame_regtest` with `DISABLE_VALUEFLOW=1` and `--enable=all --inconclusive`: Clang 15 `1,170,770,173` -> `1,167,227,434` GGC 12 `1,370,070,422` -> `1,366,775,852` --- lib/token.cpp | 23 ++++++++++++++++++++--- lib/token.h | 4 ++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/token.cpp b/lib/token.cpp index 618979613..5259a7d6b 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -424,7 +424,13 @@ const std::string &Token::strAt(int index) const return tok ? tok->mStr : emptyString; } -static int multiComparePercent(const Token *tok, const char*& haystack, nonneg int varid) +static +#if defined(__GNUC__) +// GCC does not inline this by itself +// need to use the old syntax since the C++11 [[xxx:always_inline]] cannot be used here +inline __attribute__((always_inline)) +#endif +int multiComparePercent(const Token *tok, const char*& haystack, nonneg int varid) { ++haystack; // Compare only the first character of the string for optimization reasons @@ -556,7 +562,12 @@ static int multiComparePercent(const Token *tok, const char*& haystack, nonneg i return 0xFFFF; } -int Token::multiCompare(const Token *tok, const char *haystack, nonneg int varid) +static +#if defined(__GNUC__) +// need to use the old syntax since the C++11 [[xxx:always_inline]] cannot be used here +inline __attribute__((always_inline)) +#endif +int multiCompareImpl(const Token *tok, const char *haystack, nonneg int varid) { const char *needle = tok->str().c_str(); const char *needlePointer = needle; @@ -609,6 +620,12 @@ int Token::multiCompare(const Token *tok, const char *haystack, nonneg int varid return -1; } +// cppcheck-suppress unusedFunction - used in tests only +int Token::multiCompare(const Token *tok, const char *haystack, nonneg int varid) +{ + return multiCompareImpl(tok, haystack, varid); +} + bool Token::simpleMatch(const Token *tok, const char pattern[], size_t pattern_len) { if (!tok) @@ -730,7 +747,7 @@ bool Token::Match(const Token *tok, const char pattern[], nonneg int varid) // Parse multi options, such as void|int|char (accept token which is one of these 3) else { - const int res = multiCompare(tok, p, varid); + const int res = multiCompareImpl(tok, p, varid); if (res == 0) { // Empty alternative matches, use the same token on next round while (*p && *p != ' ') diff --git a/lib/token.h b/lib/token.h index e0ca0ed9d..b17c294bd 100644 --- a/lib/token.h +++ b/lib/token.h @@ -154,6 +154,8 @@ struct TokenImpl { * The Token class also has other functions for management of token list, matching tokens, etc. */ class CPPCHECKLIB Token { + friend class TestToken; + private: TokensFrontBack* mTokensFrontBack{}; @@ -788,6 +790,7 @@ public: return const_cast(findmatch(const_cast(startTok), pattern, end, varId)); } +private: /** * Needle is build from multiple alternatives. If one of * them is equal to haystack, return value is 1. If there @@ -804,6 +807,7 @@ public: */ static int multiCompare(const Token *tok, const char *haystack, nonneg int varid); +public: nonneg int fileIndex() const { return mImpl->mFileIndex; }