Author: mandymi
Date: 2024-12-03T11:22:56-05:00
New Revision: c9fbabfdc92f12b2b0148762e6e789157a172e4d

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

LOG: [ASTMatcher] Fix redundant macro expansion checks in 
getExpansionLocOfMacro (#117143)

A performance issue was descibed in #114521 

**Root Cause**: The function getExpansionLocOfMacro is responsible for
finding the expansion location of macros. When dealing with macro
parameters, it recursively calls itself to check the expansion of macro
arguments. This recursive logic redundantly checks previous macro
expansions, leading to significant performance degradation when macros
are heavily nested.
Solution
**Modification**: Track already processed macros during recursion.
Implementation Details:
Introduced a data structure to record processed macros.
Before each recursive call, check if the macro has already been
processed to avoid redundant calculations.
**Testing**: 
1. refer to #114521 
Finder->addMatcher(expr(isExpandedFromMacro("NULL")).bind("E"), this);
run clang-tidy on freecad/src/Mod/Path/App/AreaPyImp.cpp 
clang-tidy src/Mod/Path/App/AreaPyImp.cpp -checks=-*,testchecker
-p=build/compile_commands.json
checker runs normally
2. check-clang-unit pass

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/ASTMatchers/ASTMatchersInternal.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 395da768f7c322..922f49c453e15d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -971,6 +971,8 @@ AST Matchers
 - Ensure ``hasName`` matches template specializations across inline namespaces,
   making `matchesNodeFullSlow` and `matchesNodeFullFast` consistent.
 
+- Improved the performance of the ``getExpansionLocOfMacro`` by tracking 
already processed macros during recursion.
+
 - Add ``exportDecl`` matcher to match export declaration.
 
 clang-format

diff  --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp 
b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index cdbdb65195409f..84a7fa4d36b480 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -21,6 +21,7 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
@@ -697,20 +698,27 @@ static bool isTokenAtLoc(const SourceManager &SM, const 
LangOptions &LangOpts,
   return !Invalid && Text == TokenText;
 }
 
-std::optional<SourceLocation>
-getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
-                       const ASTContext &Context) {
+static std::optional<SourceLocation> getExpansionLocOfMacroRecursive(
+    StringRef MacroName, SourceLocation Loc, const ASTContext &Context,
+    llvm::DenseSet<SourceLocation> &CheckedLocations) {
   auto &SM = Context.getSourceManager();
   const LangOptions &LangOpts = Context.getLangOpts();
   while (Loc.isMacroID()) {
+    if (CheckedLocations.count(Loc))
+      return std::nullopt;
+    CheckedLocations.insert(Loc);
     SrcMgr::ExpansionInfo Expansion =
         SM.getSLocEntry(SM.getFileID(Loc)).getExpansion();
-    if (Expansion.isMacroArgExpansion())
+    if (Expansion.isMacroArgExpansion()) {
       // Check macro argument for an expansion of the given macro. For example,
       // `F(G(3))`, where `MacroName` is `G`.
-      if (std::optional<SourceLocation> ArgLoc = getExpansionLocOfMacro(
-              MacroName, Expansion.getSpellingLoc(), Context))
+      if (std::optional<SourceLocation> ArgLoc =
+              getExpansionLocOfMacroRecursive(MacroName,
+                                              Expansion.getSpellingLoc(),
+                                              Context, CheckedLocations)) {
         return ArgLoc;
+      }
+    }
     Loc = Expansion.getExpansionLocStart();
     if (isTokenAtLoc(SM, LangOpts, MacroName, Loc))
       return Loc;
@@ -718,6 +726,14 @@ getExpansionLocOfMacro(StringRef MacroName, SourceLocation 
Loc,
   return std::nullopt;
 }
 
+std::optional<SourceLocation>
+getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
+                       const ASTContext &Context) {
+  llvm::DenseSet<SourceLocation> CheckedLocations;
+  return getExpansionLocOfMacroRecursive(MacroName, Loc, Context,
+                                         CheckedLocations);
+}
+
 std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex,
                                                   llvm::Regex::RegexFlags 
Flags,
                                                   StringRef MatcherID) {


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to