aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib/Solver/FastCexSolver.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-06-16 16:10:26 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-06-16 16:10:26 +0000
commit5d475cf47080e97e76554a82a02fafa37d2ddbbb (patch)
tree191678446d8012742d3a765ee05198dce776d408 /lib/Solver/FastCexSolver.cpp
parent5a669f7567c4ee2c54bf7d9460316afded7349b0 (diff)
downloadklee-5d475cf47080e97e76554a82a02fafa37d2ddbbb.tar.gz
Improve FastCexSolver:
- Bug fix, unbreak Concat propogation (recent regression). - Also, add some simple propogation for Add. - These two knock off another 50% of the queries hitting STP from the first 30s of 'dd'. - Also, add some debugging code. git-svn-id: https://llvm.org/svn/llvm-project/klee/trunk@73488 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Solver/FastCexSolver.cpp')
-rw-r--r--lib/Solver/FastCexSolver.cpp66
1 files changed, 61 insertions, 5 deletions
diff --git a/lib/Solver/FastCexSolver.cpp b/lib/Solver/FastCexSolver.cpp
index e9f40a49..5a2db747 100644
--- a/lib/Solver/FastCexSolver.cpp
+++ b/lib/Solver/FastCexSolver.cpp
@@ -401,6 +401,10 @@ public:
: objects(_objects) {}
};
+#if 0
+#define DEBUG
+#endif
+
class CexData {
public:
std::map<const Array*, CexObjectData*> objects;
@@ -434,12 +438,15 @@ public:
}
void propogatePossibleValues(ref<Expr> e, CexValueData range) {
+ #ifdef DEBUG
+ llvm::cerr << "propogate: " << range << " for\n" << e << "\n";
+ #endif
+
switch (e->getKind()) {
- case Expr::Constant: {
+ case Expr::Constant:
// rather a pity if the constant isn't in the range, but how can
// we use this?
break;
- }
// Special
@@ -525,7 +532,8 @@ public:
ConcatExpr *ce = cast<ConcatExpr>(e);
Expr::Width LSBWidth = ce->getKid(1)->getWidth();
Expr::Width MSBWidth = ce->getKid(1)->getWidth();
- propogatePossibleValues(ce->getKid(0), range.extract(LSBWidth, MSBWidth));
+ propogatePossibleValues(ce->getKid(0),
+ range.extract(LSBWidth, LSBWidth + MSBWidth));
propogatePossibleValues(ce->getKid(1), range.extract(0, LSBWidth));
break;
}
@@ -568,6 +576,27 @@ public:
// Binary
+ case Expr::Add: {
+ BinaryExpr *be = cast<BinaryExpr>(e);
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(be->left)) {
+ // FIXME: Don't depend on width.
+ if (CE->getWidth() <= 64) {
+ // FIXME: Why do we ever propogate empty ranges? It doesn't make
+ // sense.
+ if (range.isEmpty())
+ break;
+
+ // C_0 + X \in [MIN, MAX) ==> X \in [MIN - C_0, MAX - C_0)
+ Expr::Width W = CE->getWidth();
+ CexValueData nrange(ConstantExpr::alloc(range.min(), W)->Sub(CE)->getZExtValue(),
+ ConstantExpr::alloc(range.max(), W)->Sub(CE)->getZExtValue());
+ if (!nrange.isEmpty())
+ propogatePossibleValues(be->right, nrange);
+ }
+ }
+ break;
+ }
+
case Expr::And: {
BinaryExpr *be = cast<BinaryExpr>(e);
if (be->getWidth()==Expr::Bool) {
@@ -743,8 +772,6 @@ public:
}
void propogateExactValues(ref<Expr> e, CexValueData range) {
- //llvm::cout << e << " \\in " << range << "\n";
-
switch (e->getKind()) {
case Expr::Constant: {
// FIXME: Assert that range contains this constant.
@@ -890,6 +917,31 @@ public:
ref<Expr> evaluateExact(ref<Expr> e) {
return CexExactEvaluator(objects).visit(e);
}
+
+ void dump() {
+ llvm::cerr << "-- propogated values --\n";
+ for (std::map<const Array*, CexObjectData*>::iterator
+ it = objects.begin(), ie = objects.end(); it != ie; ++it) {
+ const Array *A = it->first;
+ CexObjectData *COD = it->second;
+
+ llvm::cerr << A->name << "\n";
+ llvm::cerr << "possible: [";
+ for (unsigned i = 0; i < A->size; ++i) {
+ if (i)
+ llvm::cerr << ", ";
+ llvm::cerr << COD->getPossibleValues(i);
+ }
+ llvm::cerr << "]\n";
+ llvm::cerr << "exact : [";
+ for (unsigned i = 0; i < A->size; ++i) {
+ if (i)
+ llvm::cerr << ", ";
+ llvm::cerr << COD->getExactValues(i);
+ }
+ llvm::cerr << "]\n";
+ }
+ }
};
/* *** */
@@ -938,6 +990,10 @@ static bool propogateValues(const Query& query, CexData &cd,
cd.propogateExactValue(query.expr, 0);
}
+#ifdef DEBUG
+ cd.dump();
+#endif
+
// Check the result.
bool hasSatisfyingAssignment = true;
if (checkExpr) {