aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib
diff options
context:
space:
mode:
authorCristian Cadar <c.cadar@imperial.ac.uk>2015-02-27 18:12:53 +0000
committerCristian Cadar <c.cadar@imperial.ac.uk>2015-02-27 18:12:53 +0000
commit35117b9f9273d2465abe56ef11f89ca7477e3d91 (patch)
treeac8250c29aa33eb445af1edb60242e0bd53b1ca5 /lib
parent3bd3789c2009fc9976d6b2ab5d0cb716c3d35dc3 (diff)
parentf049ff3bc04daead8c3bb9f06e89e71e2054c82a (diff)
downloadklee-35117b9f9273d2465abe56ef11f89ca7477e3d91.tar.gz
Merge branch 'ArrayFactory' of https://github.com/holycrap872/klee into holycrap872-ArrayFactory
Diffstat (limited to 'lib')
-rw-r--r--lib/Core/Executor.cpp4
-rw-r--r--lib/Core/Memory.cpp4
-rw-r--r--lib/Expr/Expr.cpp36
-rw-r--r--lib/Expr/Parser.cpp8
-rw-r--r--lib/SMT/SMTParser.cpp2
5 files changed, 45 insertions, 9 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index cdd6ba54..8631061f 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -2924,7 +2924,7 @@ ref<Expr> Executor::replaceReadWithSymbolic(ExecutionState &state,
// and return it.
static unsigned id;
- const Array *array = new Array("rrws_arr" + llvm::utostr(++id),
+ const Array *array = Array::CreateArray("rrws_arr" + llvm::utostr(++id),
Expr::getMinBytesForWidth(e->getWidth()));
ref<Expr> res = Expr::createTempRead(array, e->getWidth());
ref<Expr> eq = NotOptimizedExpr::create(EqExpr::create(e, res));
@@ -3263,7 +3263,7 @@ void Executor::executeMakeSymbolic(ExecutionState &state,
while (!state.arrayNames.insert(uniqueName).second) {
uniqueName = name + "_" + llvm::utostr(++id);
}
- const Array *array = new Array(uniqueName, mo->size);
+ const Array *array = Array::CreateArray(uniqueName, mo->size);
bindObjectInState(state, mo, false, array);
state.addSymbolic(mo, array);
diff --git a/lib/Core/Memory.cpp b/lib/Core/Memory.cpp
index b6f225d1..b9f6afd0 100644
--- a/lib/Core/Memory.cpp
+++ b/lib/Core/Memory.cpp
@@ -113,7 +113,7 @@ ObjectState::ObjectState(const MemoryObject *mo)
if (!UseConstantArrays) {
// FIXME: Leaked.
static unsigned id = 0;
- const Array *array = new Array("tmp_arr" + llvm::utostr(++id), size);
+ const Array *array = Array::CreateArray("tmp_arr" + llvm::utostr(++id), size);
updates = UpdateList(array, 0);
}
memset(concreteStore, 0, size);
@@ -222,7 +222,7 @@ const UpdateList &ObjectState::getUpdates() const {
// Start a new update list.
// FIXME: Leaked.
static unsigned id = 0;
- const Array *array = new Array("const_arr" + llvm::utostr(++id), size,
+ const Array *array = Array::CreateArray("const_arr" + llvm::utostr(++id), size,
&Contents[0],
&Contents[0] + Contents.size());
updates = UpdateList(array, 0);
diff --git a/lib/Expr/Expr.cpp b/lib/Expr/Expr.cpp
index d54b8f4d..46ea30fc 100644
--- a/lib/Expr/Expr.cpp
+++ b/lib/Expr/Expr.cpp
@@ -490,10 +490,46 @@ unsigned Array::computeHash() {
unsigned res = 0;
for (unsigned i = 0, e = name.size(); i != e; ++i)
res = (res * Expr::MAGIC_HASH_CONSTANT) + name[i];
+ res = (res * Expr::MAGIC_HASH_CONSTANT) + size;
hashValue = res;
return hashValue;
}
+std::map<unsigned, std::vector<const Array *> *> Array::symbolicArraySingletonMap;
+
+const Array * Array::CreateArray(const std::string &_name, uint64_t _size,
+ const ref<ConstantExpr> *constantValuesBegin,
+ const ref<ConstantExpr> *constantValuesEnd,
+ Expr::Width _domain,
+ Expr::Width _range){
+
+ const Array * array = new Array(_name, _size, constantValuesBegin, constantValuesEnd, _domain,_range);
+ if(array->constantValues.size() == 0){
+ //means is a symbolic array and we should look up the values;
+ unsigned hash = array->hash();
+ std::vector<const Array *> * bucket = Array::symbolicArraySingletonMap[hash];
+ if(bucket){
+ for(std::vector<const Array*>::const_iterator it = bucket->begin();
+ it != bucket->end(); it ++){
+ const Array* prospect = *it;
+ if(prospect->size == array->size && prospect->name == array->name){
+ delete array;
+ return prospect;
+ }
+ }
+ bucket->push_back(array);
+ return array;
+ }else{
+ bucket = new std::vector<const Array *>();
+ bucket->push_back(array);
+ Array::symbolicArraySingletonMap[hash] = bucket;
+ return array;
+ }
+ }else{
+ return array;
+ }
+}
+
/***/
ref<Expr> ReadExpr::create(const UpdateList &ul, ref<Expr> index) {
diff --git a/lib/Expr/Parser.cpp b/lib/Expr/Parser.cpp
index aebce666..9df08903 100644
--- a/lib/Expr/Parser.cpp
+++ b/lib/Expr/Parser.cpp
@@ -519,12 +519,12 @@ DeclResult ParserImpl::ParseArrayDecl() {
// FIXME: Array should take domain and range.
const Identifier *Label = GetOrCreateIdentifier(Name);
- Array *Root;
+ const Array *Root;
if (!Values.empty())
- Root = new Array(Label->Name, Size.get(),
+ Root = Array::CreateArray(Label->Name, Size.get(),
&Values[0], &Values[0] + Values.size());
else
- Root = new Array(Label->Name, Size.get());
+ Root = Array::CreateArray(Label->Name, Size.get());
ArrayDecl *AD = new ArrayDecl(Label, Size.get(),
DomainType.get(), RangeType.get(), Root);
@@ -1306,7 +1306,7 @@ VersionResult ParserImpl::ParseVersionSpecifier() {
VersionResult Res = ParseVersion();
// Define update list to avoid use-of-undef errors.
if (!Res.isValid()) {
- Res = VersionResult(true, UpdateList(new Array("", 0), NULL));
+ Res = VersionResult(true, UpdateList(Array::CreateArray("", 0), NULL));
}
if (Label)
diff --git a/lib/SMT/SMTParser.cpp b/lib/SMT/SMTParser.cpp
index 03042fdd..eefe443a 100644
--- a/lib/SMT/SMTParser.cpp
+++ b/lib/SMT/SMTParser.cpp
@@ -165,7 +165,7 @@ void SMTParser::DeclareExpr(std::string name, Expr::Width w) {
std::cout << "Declaring " << name << " of width " << w << "\n";
#endif
- Array *arr = new Array(name, w / 8);
+ const Array *arr = Array::CreateArray(name, w / 8);
ref<Expr> *kids = new ref<Expr>[w/8];
for (unsigned i=0; i < w/8; i++)