diff options
Diffstat (limited to 'lib/Expr')
-rw-r--r-- | lib/Expr/ArrayCache.cpp | 47 | ||||
-rw-r--r-- | lib/Expr/Expr.cpp | 35 | ||||
-rw-r--r-- | lib/Expr/Parser.cpp | 12 |
3 files changed, 55 insertions, 39 deletions
diff --git a/lib/Expr/ArrayCache.cpp b/lib/Expr/ArrayCache.cpp new file mode 100644 index 00000000..b669f237 --- /dev/null +++ b/lib/Expr/ArrayCache.cpp @@ -0,0 +1,47 @@ +#include "klee/util/ArrayCache.h" + +namespace klee { + +ArrayCache::~ArrayCache() { + // Free Allocated Array objects + for (ArrayHashMap::iterator ai = cachedSymbolicArrays.begin(), + e = cachedSymbolicArrays.end(); + ai != e; ++ai) { + delete *ai; + } + for (ArrayPtrVec::iterator ai = concreteArrays.begin(), + e = concreteArrays.end(); + ai != e; ++ai) { + delete *ai; + } +} + +const Array * +ArrayCache::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->isSymbolicArray()) { + std::pair<ArrayHashMap::const_iterator, bool> success = + cachedSymbolicArrays.insert(array); + if (success.second) { + // Cache miss + return array; + } + // Cache hit + delete array; + array = *(success.first); + assert(array->isSymbolicArray() && + "Cached symbolic array is no longer symbolic"); + return array; + } else { + // Treat every constant array as distinct so we never cache them + assert(array->isConstantArray()); + concreteArrays.push_back(array); // For deletion later + return array; + } +} +} diff --git a/lib/Expr/Expr.cpp b/lib/Expr/Expr.cpp index baa85663..2c64aff4 100644 --- a/lib/Expr/Expr.cpp +++ b/lib/Expr/Expr.cpp @@ -494,41 +494,6 @@ unsigned Array::computeHash() { 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) { // symbolic array - 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 { // concrete array - 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 23a292fa..854f6d52 100644 --- a/lib/Expr/Parser.cpp +++ b/lib/Expr/Parser.cpp @@ -16,6 +16,7 @@ #include "klee/ExprBuilder.h" #include "klee/Solver.h" #include "klee/util/ExprPPrinter.h" +#include "klee/util/ArrayCache.h" #include "llvm/ADT/APInt.h" #include "llvm/Support/MemoryBuffer.h" @@ -109,6 +110,7 @@ namespace { const std::string Filename; const MemoryBuffer *TheMemoryBuffer; ExprBuilder *Builder; + ArrayCache TheArrayCache; Lexer TheLexer; unsigned MaxErrors; @@ -521,10 +523,10 @@ DeclResult ParserImpl::ParseArrayDecl() { const Identifier *Label = GetOrCreateIdentifier(Name); const Array *Root; if (!Values.empty()) - Root = Array::CreateArray(Label->Name, Size.get(), - &Values[0], &Values[0] + Values.size()); + Root = TheArrayCache.CreateArray(Label->Name, Size.get(), &Values[0], + &Values[0] + Values.size()); else - Root = Array::CreateArray(Label->Name, Size.get()); + Root = TheArrayCache.CreateArray(Label->Name, Size.get()); ArrayDecl *AD = new ArrayDecl(Label, Size.get(), DomainType.get(), RangeType.get(), Root); @@ -1306,7 +1308,9 @@ VersionResult ParserImpl::ParseVersionSpecifier() { VersionResult Res = ParseVersion(); // Define update list to avoid use-of-undef errors. if (!Res.isValid()) { - Res = VersionResult(true, UpdateList(Array::CreateArray("", 0), NULL)); + // FIXME: I'm not sure if this is right. Do we need a unique array here? + Res = + VersionResult(true, UpdateList(TheArrayCache.CreateArray("", 0), NULL)); } if (Label) |