[PATCH] D50773: [analyzer] added cache for SMT queries in the SMTConstraintManager

Phabricator via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 23 06:22:40 PDT 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rC340535: [analyzer] added cache for SMT queries in the SMTConstraintManager (authored by mramalho, committed by ).
Herald added a subscriber: cfe-commits.

Repository:
  rC Clang

https://reviews.llvm.org/D50773

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h


Index: include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
@@ -86,29 +86,15 @@
     SMTExprRef NotExp =
         SMTConv::getZeroExpr(Solver, Ctx, VarExp, RetTy, /*Assumption=*/false);
 
-    Solver->reset();
-    addStateConstraints(State);
-
-    Solver->push();
-    Solver->addConstraint(Exp);
-
-    Optional<bool> isSat = Solver->check();
-    if (!isSat.hasValue())
-      return ConditionTruthVal();
-
-    Solver->pop();
-    Solver->addConstraint(NotExp);
-
-    Optional<bool> isNotSat = Solver->check();
-    if (!isNotSat.hasValue())
-      return ConditionTruthVal();
+    ConditionTruthVal isSat = checkModel(State, Sym, Exp);
+    ConditionTruthVal isNotSat = checkModel(State, Sym, NotExp);
 
     // Zero is the only possible solution
-    if (isSat.getValue() && !isNotSat.getValue())
+    if (isSat.isConstrainedTrue() && isNotSat.isConstrainedFalse())
       return true;
 
     // Zero is not a solution
-    if (!isSat.getValue() && isNotSat.getValue())
+    if (isSat.isConstrainedFalse() && isNotSat.isConstrainedTrue())
       return false;
 
     // Zero may be a solution
@@ -126,6 +112,10 @@
       llvm::APSInt Value(Ctx.getTypeSize(Ty),
                          !Ty->isSignedIntegerOrEnumerationType());
 
+      // TODO: this should call checkModel so we can use the cache, however,
+      // this method tries to get the interpretation (the actual value) from
+      // the solver, which is currently not cached.
+
       SMTExprRef Exp =
           SMTConv::fromData(Solver, SD->getSymbolID(), Ty, Ctx.getTypeSize(Ty));
 
@@ -236,7 +226,7 @@
   virtual ProgramStateRef assumeExpr(ProgramStateRef State, SymbolRef Sym,
                                      const SMTExprRef &Exp) {
     // Check the model, avoid simplifying AST to save time
-    if (checkModel(State, Exp).isConstrainedTrue())
+    if (checkModel(State, Sym, Exp).isConstrainedTrue())
       return State->add<ConstraintSMT>(
           std::make_pair(Sym, static_cast<const SMTExprTy &>(*Exp)));
 
@@ -264,18 +254,34 @@
   }
 
   // Generate and check a Z3 model, using the given constraint.
-  ConditionTruthVal checkModel(ProgramStateRef State,
+  ConditionTruthVal checkModel(ProgramStateRef State, SymbolRef Sym,
                                const SMTExprRef &Exp) const {
+    ProgramStateRef NewState = State->add<ConstraintSMT>(
+        std::make_pair(Sym, static_cast<const SMTExprTy &>(*Exp)));
+
+    llvm::FoldingSetNodeID ID;
+    NewState->get<ConstraintSMT>().Profile(ID);
+
+    unsigned hash = ID.ComputeHash();
+    auto I = Cached.find(hash);
+    if (I != Cached.end())
+      return I->second;
+
     Solver->reset();
-    Solver->addConstraint(Exp);
-    addStateConstraints(State);
+    addStateConstraints(NewState);
 
     Optional<bool> res = Solver->check();
     if (!res.hasValue())
-      return ConditionTruthVal();
+      Cached[hash] = ConditionTruthVal();
+    else
+      Cached[hash] = ConditionTruthVal(res.getValue());
 
-    return ConditionTruthVal(res.getValue());
+    return Cached[hash];
   }
+
+  // Cache the result of an SMT query (true, false, unknown). The key is the
+  // hash of the constraints in a state
+  mutable llvm::DenseMap<unsigned, ConditionTruthVal> Cached;
 }; // end class SMTConstraintManager
 
 } // namespace ento


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D50773.162164.patch
Type: text/x-patch
Size: 3525 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180823/b30a4957/attachment.bin>


More information about the cfe-commits mailing list