Skip to content

Commit 778eca3

Browse files
committed
Create AlphaEquvalenceSolver
1 parent 6356637 commit 778eca3

20 files changed

+462
-6
lines changed

include/klee/Expr/AlphaBuilder.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//===-- AlphaBuilder.h -----------------------------------*- C++ -*-===//
2+
//
3+
// The KLEE Symbolic Virtual Machine
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef KLEE_ALPHA_BUILDER_H
11+
#define KLEE_ALPHA_BUILDER_H
12+
13+
#include "klee/Expr/ArrayCache.h"
14+
#include "klee/Expr/ExprHashMap.h"
15+
#include "klee/Expr/ExprVisitor.h"
16+
17+
namespace klee {
18+
19+
class AlphaBuilder : public ExprVisitor {
20+
public:
21+
ExprHashMap<ref<Expr>> reverseExprMap;
22+
ArrayCache::ArrayHashMap<const Array *> reverseAlphaArrayMap;
23+
ArrayCache::ArrayHashMap<const Array *> alphaArrayMap;
24+
25+
private:
26+
ArrayCache &arrayCache;
27+
unsigned index = 0;
28+
29+
const Array *visitArray(const Array *arr);
30+
UpdateList visitUpdateList(UpdateList u);
31+
Action visitRead(const ReadExpr &re);
32+
33+
public:
34+
AlphaBuilder(ArrayCache &_arrayCache);
35+
constraints_ty visitConstraints(constraints_ty cs);
36+
ref<Expr> visitExpr(ref<Expr> v);
37+
};
38+
39+
} // namespace klee
40+
41+
#endif /*KLEE_ALPHA_VERSION_BUILDER_H*/

include/klee/Expr/Parser/Parser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ class Parser {
220220
static Parser *Create(const std::string Name, const llvm::MemoryBuffer *MB,
221221
ExprBuilder *Builder, ArrayCache *TheArrayCache,
222222
KModule *km, bool ClearArrayAfterQuery);
223+
224+
virtual ArrayCache &getArrayCache() = 0;
223225
};
224226
} // namespace expr
225227
} // namespace klee

include/klee/Expr/SourceBuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class SourceBuilder {
3232
static ref<SymbolicSource> value(const llvm::Value &_allocSite, int _index,
3333
KModule *km);
3434
static ref<SymbolicSource> irreproducible(const std::string &name);
35+
static ref<SymbolicSource> alpha(int _index);
3536
};
3637

3738
}; // namespace klee

include/klee/Expr/SymbolicSource.h

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ class SymbolicSource {
4545
LazyInitializationSize,
4646
Instruction,
4747
Argument,
48-
Irreproducible
48+
Irreproducible,
49+
Alpha
4950
};
5051

5152
public:
@@ -349,6 +350,37 @@ class IrreproducibleSource : public SymbolicSource {
349350
}
350351
};
351352

353+
class AlphaSource : public SymbolicSource {
354+
public:
355+
const unsigned index;
356+
357+
AlphaSource(unsigned _index) : index(_index) {}
358+
Kind getKind() const override { return Kind::Alpha; }
359+
virtual std::string getName() const override { return "alpha"; }
360+
361+
static bool classof(const SymbolicSource *S) {
362+
return S->getKind() == Kind::Alpha;
363+
}
364+
static bool classof(const AlphaSource *) { return true; }
365+
366+
virtual unsigned computeHash() override {
367+
unsigned res = getKind();
368+
hashValue = res ^ (index * SymbolicSource::MAGIC_HASH_CONSTANT);
369+
return hashValue;
370+
}
371+
372+
virtual int internalCompare(const SymbolicSource &b) const override {
373+
if (getKind() != b.getKind()) {
374+
return getKind() < b.getKind() ? -1 : 1;
375+
}
376+
const AlphaSource &amb = static_cast<const AlphaSource &>(b);
377+
if (index != amb.index) {
378+
return index < amb.index ? -1 : 1;
379+
}
380+
return 0;
381+
}
382+
};
383+
352384
} // namespace klee
353385

354386
#endif /* KLEE_SYMBOLICSOURCE_H */

include/klee/Solver/Common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ std::unique_ptr<Solver> constructSolverChain(
2929
std::unique_ptr<Solver> coreSolver, std::string querySMT2LogPath,
3030
std::string baseSolverQuerySMT2LogPath, std::string queryKQueryLogPath,
3131
std::string baseSolverQueryKQueryLogPath,
32-
AddressGenerator *addressGenerator);
32+
AddressGenerator *addressGenerator, ArrayCache &arrayCache);
3333
} // namespace klee
3434

3535
#endif /* KLEE_COMMON_H */

include/klee/Solver/Solver.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,14 @@ std::unique_ptr<Solver> createFastCexSolver(std::unique_ptr<Solver> s);
244244
/// \param s - The underlying solver to use.
245245
std::unique_ptr<Solver> createIndependentSolver(std::unique_ptr<Solver> s);
246246

247+
/// createAlphaEquivalenceSolver - Create a solver which will change
248+
/// independent queries to their alpha-equvalent version
249+
///
250+
/// \param s - The underlying solver to use.
251+
/// \param arrayCache - Class to create new arrays.
252+
std::unique_ptr<Solver> createAlphaEquivalenceSolver(std::unique_ptr<Solver> s,
253+
ArrayCache &arrayCache);
254+
247255
/// createKQueryLoggingSolver - Create a solver which will forward all queries
248256
/// after writing them to the given path in .kquery format.
249257
std::unique_ptr<Solver> createKQueryLoggingSolver(std::unique_ptr<Solver> s,

include/klee/Solver/SolverCmdLine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ extern llvm::cl::opt<bool> UseCexCache;
3232

3333
extern llvm::cl::opt<bool> UseBranchCache;
3434

35+
extern llvm::cl::opt<bool> UseAlphaEquivalence;
36+
3537
extern llvm::cl::opt<bool> UseConcretizingSolver;
3638

3739
extern llvm::cl::opt<bool> UseIndependentSolver;

lib/Core/Executor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ Executor::Executor(LLVMContext &ctx, const InterpreterOptions &opts,
515515
interpreterHandler->getOutputFilename(SOLVER_QUERIES_SMT2_FILE_NAME),
516516
interpreterHandler->getOutputFilename(ALL_QUERIES_KQUERY_FILE_NAME),
517517
interpreterHandler->getOutputFilename(SOLVER_QUERIES_KQUERY_FILE_NAME),
518-
addressManager.get());
518+
addressManager.get(), arrayCache);
519519

520520
this->solver = std::make_unique<TimingSolver>(std::move(solver), optimizer,
521521
EqualitySubstitution);

lib/Expr/AlphaBuilder.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//===-- AlphaBuilder.cpp ---------------------------------*- C++ -*-===//
2+
//
3+
// The KLEE Symbolic Virtual Machine
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "klee/Expr/AlphaBuilder.h"
11+
#include "klee/Expr/ArrayCache.h"
12+
#include "klee/Expr/SourceBuilder.h"
13+
14+
#include <vector>
15+
16+
namespace klee {
17+
18+
const Array *AlphaBuilder::visitArray(const Array *arr) {
19+
if (alphaArrayMap.find(arr) == alphaArrayMap.end()) {
20+
ref<SymbolicSource> source = arr->source;
21+
ref<Expr> size = visit(arr->getSize());
22+
23+
if (!arr->isConstantArray()) {
24+
source = SourceBuilder::alpha(index);
25+
index++;
26+
alphaArrayMap[arr] = arrayCache.CreateArray(
27+
size, source, arr->getDomain(), arr->getRange());
28+
reverseAlphaArrayMap[alphaArrayMap[arr]] = arr;
29+
} else if (size != arr->getSize()) {
30+
alphaArrayMap[arr] = arrayCache.CreateArray(
31+
size, source, arr->getDomain(), arr->getRange());
32+
reverseAlphaArrayMap[alphaArrayMap[arr]] = arr;
33+
} else {
34+
alphaArrayMap[arr] = arr;
35+
reverseAlphaArrayMap[arr] = arr;
36+
}
37+
}
38+
return alphaArrayMap[arr];
39+
}
40+
41+
UpdateList AlphaBuilder::visitUpdateList(UpdateList u) {
42+
const Array *root = visitArray(u.root);
43+
std::vector<ref<UpdateNode>> updates;
44+
45+
for (auto un = u.head; un; un = un->next) {
46+
updates.push_back(un);
47+
}
48+
49+
updates.push_back(nullptr);
50+
51+
for (int i = updates.size() - 2; i >= 0; i--) {
52+
ref<Expr> index = visit(updates[i]->index);
53+
ref<Expr> value = visit(updates[i]->value);
54+
updates[i] = new UpdateNode(updates[i + 1], index, value);
55+
}
56+
return UpdateList(root, updates[0]);
57+
}
58+
59+
ExprVisitor::Action AlphaBuilder::visitRead(const ReadExpr &re) {
60+
ref<Expr> v = visit(re.index);
61+
UpdateList u = visitUpdateList(re.updates);
62+
ref<Expr> e = ReadExpr::create(u, v);
63+
return Action::changeTo(e);
64+
}
65+
66+
AlphaBuilder::AlphaBuilder(ArrayCache &_arrayCache) : arrayCache(_arrayCache) {}
67+
68+
constraints_ty AlphaBuilder::visitConstraints(constraints_ty cs) {
69+
constraints_ty result;
70+
for (auto arg : cs) {
71+
ref<Expr> v = visit(arg);
72+
reverseExprMap[v] = arg;
73+
reverseExprMap[Expr::createIsZero(v)] = Expr::createIsZero(arg);
74+
result.insert(v);
75+
}
76+
return result;
77+
}
78+
ref<Expr> AlphaBuilder::visitExpr(ref<Expr> v) {
79+
ref<Expr> e = visit(v);
80+
reverseExprMap[e] = v;
81+
reverseExprMap[Expr::createIsZero(e)] = Expr::createIsZero(v);
82+
return e;
83+
}
84+
85+
} // namespace klee

lib/Expr/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#
88
#===------------------------------------------------------------------------===#
99
add_library(kleaverExpr
10+
AlphaBuilder.cpp
1011
APFloatEval.cpp
1112
ArrayCache.cpp
1213
ArrayExprOptimizer.cpp

0 commit comments

Comments
 (0)