Skip to content

Commit

Permalink
[analyzer] added cache for SMT queries in the SMTConstraintManager
Browse files Browse the repository at this point in the history
Summary:
This patch implements a new cache for the result of SMT queries; with this patch the regression tests are 25% faster.

It's implemented as a `llvm::DenseMap` where the key is the hash of the set of the constraints in a state.

There is still one method that does not use the cache, `getSymVal`, because it needs to get a symbol interpretation from the SMT, which is not cached yet.

Reviewers: NoQ, george.karpenkov

Reviewed By: george.karpenkov

Subscribers: xazax.hun, szepet, a.sidorin, Szelethus

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@340535 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
mikhailramalho committed Aug 23, 2018
1 parent 60783c8 commit e29bf81
Showing 1 changed file with 30 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,29 +86,15 @@ class SMTConstraintManager : public clang::ento::SimpleConstraintManager {
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
Expand All @@ -126,6 +112,10 @@ class SMTConstraintManager : public clang::ento::SimpleConstraintManager {
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));

Expand Down Expand Up @@ -236,7 +226,7 @@ class SMTConstraintManager : public clang::ento::SimpleConstraintManager {
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)));

Expand Down Expand Up @@ -264,18 +254,34 @@ class SMTConstraintManager : public clang::ento::SimpleConstraintManager {
}

// 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
Expand Down

0 comments on commit e29bf81

Please sign in to comment.