r312440 - [analyzer] MinComplexityConstraint now early exits and only does one macro stack lookup

Raphael Isemann via cfe-commits cfe-commits at lists.llvm.org
Sun Sep 3 06:45:33 PDT 2017


Author: teemperor
Date: Sun Sep  3 06:45:33 2017
New Revision: 312440

URL: http://llvm.org/viewvc/llvm-project?rev=312440&view=rev
Log:
[analyzer] MinComplexityConstraint now early exits and only does one macro stack lookup

Summary:
This patch contains performance improvements for the `MinComplexityConstraint`. It reduces the constraint time when running on the SQLite codebase by around 43% (from 0.085s down to 0.049s).

The patch is essentially doing two things:

* It introduces a possibility for the complexity value to early exit when reaching the limit we were checking for. This means that once we noticed that the current clone is larger than the limit the user has set, we instantly exit and no longer traverse the tree or do further expensive lookups in the macro stack.

* It also removes half of the macro stack lookups we do so far. Previously we always checked the start and the end location of a Stmt for macros, which was only a middle way between checking all locations of the Stmt and just checking one location. In practice I rarely found cases where it really matters if we check start/end or just the start of a statement as code with lots of macros that somehow just produce half a statement are very rare.

Reviewers: NoQ

Subscribers: cfe-commits, xazax.hun, v.g.vassilev

Differential Revision: https://reviews.llvm.org/D34361

Modified:
    cfe/trunk/include/clang/Analysis/CloneDetection.h
    cfe/trunk/lib/Analysis/CloneDetection.cpp

Modified: cfe/trunk/include/clang/Analysis/CloneDetection.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CloneDetection.h?rev=312440&r1=312439&r2=312440&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/CloneDetection.h (original)
+++ cfe/trunk/include/clang/Analysis/CloneDetection.h Sun Sep  3 06:45:33 2017
@@ -288,14 +288,19 @@ public:
   MinComplexityConstraint(unsigned MinComplexity)
       : MinComplexity(MinComplexity) {}
 
-  size_t calculateStmtComplexity(const StmtSequence &Seq,
+  /// Calculates the complexity of the given StmtSequence.
+  /// \param Limit The limit of complexity we probe for. After reaching
+  ///              this limit during calculation, this method is exiting
+  ///              early to improve performance and returns this limit.
+  size_t calculateStmtComplexity(const StmtSequence &Seq, std::size_t Limit,
                                  const std::string &ParentMacroStack = "");
 
   void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
     CloneConstraint::filterGroups(
         CloneGroups, [this](const CloneDetector::CloneGroup &A) {
           if (!A.empty())
-            return calculateStmtComplexity(A.front()) < MinComplexity;
+            return calculateStmtComplexity(A.front(), MinComplexity) <
+                   MinComplexity;
           else
             return false;
         });

Modified: cfe/trunk/lib/Analysis/CloneDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CloneDetection.cpp?rev=312440&r1=312439&r2=312440&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CloneDetection.cpp (original)
+++ cfe/trunk/lib/Analysis/CloneDetection.cpp Sun Sep  3 06:45:33 2017
@@ -422,7 +422,8 @@ void RecursiveCloneTypeIIVerifyConstrain
 }
 
 size_t MinComplexityConstraint::calculateStmtComplexity(
-    const StmtSequence &Seq, const std::string &ParentMacroStack) {
+    const StmtSequence &Seq, std::size_t Limit,
+    const std::string &ParentMacroStack) {
   if (Seq.empty())
     return 0;
 
@@ -431,10 +432,8 @@ size_t MinComplexityConstraint::calculat
   ASTContext &Context = Seq.getASTContext();
 
   // Look up what macros expanded into the current statement.
-  std::string StartMacroStack =
+  std::string MacroStack =
       data_collection::getMacroStack(Seq.getStartLoc(), Context);
-  std::string EndMacroStack =
-      data_collection::getMacroStack(Seq.getEndLoc(), Context);
 
   // First, check if ParentMacroStack is not empty which means we are currently
   // dealing with a parent statement which was expanded from a macro.
@@ -444,8 +443,7 @@ size_t MinComplexityConstraint::calculat
   // macro expansion will only increase the total complexity by one.
   // Note: This is not the final complexity of this statement as we still
   // add the complexity of the child statements to the complexity value.
-  if (!ParentMacroStack.empty() && (StartMacroStack == ParentMacroStack &&
-                                    EndMacroStack == ParentMacroStack)) {
+  if (!ParentMacroStack.empty() && MacroStack == ParentMacroStack) {
     Complexity = 0;
   }
 
@@ -454,12 +452,16 @@ size_t MinComplexityConstraint::calculat
   if (Seq.holdsSequence()) {
     for (const Stmt *S : Seq) {
       Complexity += calculateStmtComplexity(
-          StmtSequence(S, Seq.getContainingDecl()), StartMacroStack);
+          StmtSequence(S, Seq.getContainingDecl()), Limit, MacroStack);
+      if (Complexity >= Limit)
+        return Limit;
     }
   } else {
     for (const Stmt *S : Seq.front()->children()) {
       Complexity += calculateStmtComplexity(
-          StmtSequence(S, Seq.getContainingDecl()), StartMacroStack);
+          StmtSequence(S, Seq.getContainingDecl()), Limit, MacroStack);
+      if (Complexity >= Limit)
+        return Limit;
     }
   }
   return Complexity;




More information about the cfe-commits mailing list