aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib/Expr
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Expr')
-rw-r--r--lib/Expr/Expr.cpp36
-rw-r--r--lib/Expr/Parser.cpp8
2 files changed, 40 insertions, 4 deletions
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)