[cfe-commits] r153297 - /cfe/trunk/lib/Analysis/CFG.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Thu Mar 22 17:59:18 PDT 2012


Author: akirtzidis
Date: Thu Mar 22 19:59:17 2012
New Revision: 153297

URL: http://llvm.org/viewvc/llvm-project?rev=153297&view=rev
Log:
[CFG] Cache boolean evaluations of expressions to avoid multiple re-evaluations
during construction of branches for chained logical operators.

This makes -fsyntax-only for test/Sema/many-logical-ops.c about 32x times faster.

With measuring SemaExpr.cpp I see differences below the noise level.

Modified:
    cfe/trunk/lib/Analysis/CFG.cpp

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=153297&r1=153296&r2=153297&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Thu Mar 22 19:59:17 2012
@@ -286,6 +286,10 @@
   CFG::BuildOptions::ForcedBlkExprs::value_type *cachedEntry;
   const Stmt *lastLookup;
 
+  // Caches boolean evaluations of expressions to avoid multiple re-evaluations
+  // during construction of branches for chained logical operators.
+  llvm::DenseMap<Expr *, TryResult> CachedBoolEvals;
+
 public:
   explicit CFGBuilder(ASTContext *astContext,
                       const CFG::BuildOptions &buildOpts) 
@@ -439,12 +443,65 @@
   /// tryEvaluateBool - Try and evaluate the Stmt and return 0 or 1
   /// if we can evaluate to a known value, otherwise return -1.
   TryResult tryEvaluateBool(Expr *S) {
-    bool Result;
     if (!BuildOpts.PruneTriviallyFalseEdges ||
-        S->isTypeDependent() || S->isValueDependent() ||
-        !S->EvaluateAsBooleanCondition(Result, *Context))
+        S->isTypeDependent() || S->isValueDependent())
       return TryResult();
-    return Result;
+
+    if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(S)) {
+      if (Bop->isLogicalOp()) {
+        // Check the cache first.
+        typedef llvm::DenseMap<Expr *, TryResult>::iterator eval_iterator;
+        eval_iterator I;
+        bool Inserted;
+        llvm::tie(I, Inserted) =
+            CachedBoolEvals.insert(std::make_pair(S, TryResult()));
+        if (!Inserted)
+          return I->second; // already in map;
+    
+        return (I->second = evaluateAsBooleanConditionNoCache(S));
+      }
+    }
+
+    return evaluateAsBooleanConditionNoCache(S);
+  }
+
+  /// \brief Evaluate as boolean \param E without using the cache.
+  TryResult evaluateAsBooleanConditionNoCache(Expr *E) {
+    if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(E)) {
+      if (Bop->isLogicalOp()) {
+        TryResult LHS = tryEvaluateBool(Bop->getLHS());
+        if (LHS.isKnown()) {
+          // We were able to evaluate the LHS, see if we can get away with not
+          // evaluating the RHS: 0 && X -> 0, 1 || X -> 1
+          if (LHS.isTrue() == (Bop->getOpcode() == BO_LOr))
+            return LHS.isTrue();
+
+          TryResult RHS = tryEvaluateBool(Bop->getRHS());
+          if (RHS.isKnown()) {
+            if (Bop->getOpcode() == BO_LOr)
+              return LHS.isTrue() || RHS.isTrue();
+            else
+              return LHS.isTrue() && RHS.isTrue();
+          }
+        } else {
+          TryResult RHS = tryEvaluateBool(Bop->getRHS());
+          if (RHS.isKnown()) {
+            // We can't evaluate the LHS; however, sometimes the result
+            // is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
+            if (RHS.isTrue() == (Bop->getOpcode() == BO_LOr))
+              return RHS.isTrue();
+          }
+        }
+
+        return TryResult();
+      }
+    }
+
+    bool Result;
+    if (E->EvaluateAsBooleanCondition(Result, *Context))
+      return Result;
+
+    return TryResult();
   }
   
 };
@@ -1127,6 +1184,10 @@
       RHSBlock = createBlock();
     }
 
+    // Generate the blocks for evaluating the LHS.
+    Block = LHSBlock;
+    CFGBlock *EntryLHSBlock = addStmt(B->getLHS());
+
     // See if this is a known constant.
     TryResult KnownVal = tryEvaluateBool(B->getLHS());
     if (KnownVal.isKnown() && (B->getOpcode() == BO_LOr))
@@ -1142,9 +1203,7 @@
       addSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : ConfluenceBlock);
     }
 
-    // Generate the blocks for evaluating the LHS.
-    Block = LHSBlock;
-    return addStmt(B->getLHS());
+    return EntryLHSBlock;
   }
 
   if (B->getOpcode() == BO_Comma) { // ,





More information about the cfe-commits mailing list