Skip to content

Commit eac0027

Browse files
authored
Merge pull request #5 from chrisr-diffblue/sharing-map-arrays
Use sharing_mapt in constant_array_abstract_objectt
2 parents 5aba170 + 2d09d66 commit eac0027

File tree

4 files changed

+98
-41
lines changed

4 files changed

+98
-41
lines changed

src/analyses/variable-sensitivity/abstract_object.h

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,11 @@ class abstract_objectt:public std::enable_shared_from_this<abstract_objectt>
244244
std::map<keyt, abstract_object_pointert> &out_map);
245245

246246

247-
template<class keyt>
247+
template<class keyt, typename hash>
248248
static bool merge_shared_maps(
249-
const sharing_mapt<keyt, abstract_object_pointert, irep_id_hash> &map1,
250-
const sharing_mapt<keyt, abstract_object_pointert, irep_id_hash> &map2,
251-
sharing_mapt<keyt, abstract_object_pointert, irep_id_hash> &out_map);
249+
const sharing_mapt<keyt, abstract_object_pointert, hash> &map1,
250+
const sharing_mapt<keyt, abstract_object_pointert, hash> &map2,
251+
sharing_mapt<keyt, abstract_object_pointert, hash> &out_map);
252252

253253

254254

@@ -302,20 +302,15 @@ bool abstract_objectt::merge_maps(
302302
return modified;
303303
}
304304

305-
template<typename keyt>
305+
template<typename keyt, typename hash>
306306
bool abstract_objectt::merge_shared_maps(
307-
const sharing_mapt<keyt, abstract_object_pointert, irep_id_hash> &m1,
308-
const sharing_mapt<keyt, abstract_object_pointert, irep_id_hash> &m2,
309-
sharing_mapt<keyt, abstract_object_pointert, irep_id_hash> &out_map)
307+
const sharing_mapt<keyt, abstract_object_pointert, hash> &m1,
308+
const sharing_mapt<keyt, abstract_object_pointert, hash> &m2,
309+
sharing_mapt<keyt, abstract_object_pointert, hash> &out_map)
310310
{
311-
typedef sharing_mapt<irep_idt, abstract_object_pointert,
312-
irep_id_hash>
313-
abstract_object_mapt;
314-
315311
bool modified=false;
316312

317-
abstract_object_mapt::delta_viewt delta_view;
318-
m1.get_delta_view(m2, delta_view, true);
313+
auto delta_view = m1.get_delta_view(m2, true);
319314

320315
for(auto &item : delta_view)
321316
{

src/analyses/variable-sensitivity/constant_array_abstract_object.cpp

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ abstract_object_pointert constant_array_abstract_objectt::constant_array_merge(
139139
}
140140
else
141141
{
142-
array_mapt merged_map=array_mapt();
142+
shared_array_mapt merged_map(map);
143143
bool modified=
144-
abstract_objectt::merge_maps<mp_integer>(map, other->map, merged_map);
144+
abstract_objectt::merge_shared_maps<mp_integer, mp_integer_hash>(map, other->map, merged_map);
145145
if(!modified)
146146
{
147147
return shared_from_this();
@@ -188,8 +188,11 @@ void constant_array_abstract_objectt::output(
188188
}
189189
else
190190
{
191+
shared_array_mapt::sorted_viewt view;
192+
map.get_view(view);
193+
191194
out << "{";
192-
for(const auto &entry : map)
195+
for(const auto &entry : view)
193196
{
194197
out << "[" << entry.first << "] = ";
195198
entry.second->output(out, ai, ns);
@@ -281,14 +284,16 @@ abstract_object_pointert constant_array_abstract_objectt::read_index(
281284
mp_integer index_value;
282285
if(eval_index(index, env, ns, index_value))
283286
{
287+
shared_array_mapt::const_find_type value = map.find(index_value);
288+
284289
// Here we are assuming it is always in bounds
285-
if(map.find(index_value)==map.cend())
290+
if(!value.second)
286291
{
287292
return env.abstract_object_factory(type().subtype(), ns, true, false);
288293
}
289294
else
290295
{
291-
return map.find(index_value)->second;
296+
return value.first;
292297
}
293298
}
294299
else
@@ -339,7 +344,7 @@ sharing_ptrt<array_abstract_objectt>
339344
{
340345
if(stack.empty())
341346
{
342-
auto copy=
347+
auto result=
343348
internal_sharing_ptrt<constant_array_abstract_objectt>(
344349
new constant_array_abstract_objectt(*this));
345350

@@ -348,11 +353,11 @@ sharing_ptrt<array_abstract_objectt>
348353
{
349354
if(is_top())
350355
{
351-
copy->clear_top();
356+
result->clear_top();
352357
}
353358

354-
copy->map[index_value]=value;
355-
return copy;
359+
result->map[index_value]=value;
360+
return result;
356361
}
357362
else
358363
{
@@ -364,7 +369,7 @@ sharing_ptrt<array_abstract_objectt>
364369
}
365370
else
366371
{
367-
auto copy=
372+
auto result=
368373
internal_sharing_ptrt<constant_array_abstract_objectt>(
369374
new constant_array_abstract_objectt(*this));
370375

@@ -373,9 +378,11 @@ sharing_ptrt<array_abstract_objectt>
373378
{
374379
// Here we assume the write is in bounds
375380
abstract_object_pointert array_entry;
376-
if(map.find(index_value)!=map.cend())
381+
shared_array_mapt::const_find_type old_value = map.find(index_value);
382+
383+
if(old_value.second)
377384
{
378-
array_entry=map.at(index_value);
385+
array_entry=old_value.first;
379386
}
380387
else
381388
{
@@ -384,28 +391,31 @@ sharing_ptrt<array_abstract_objectt>
384391

385392
if(is_top())
386393
{
387-
copy->clear_top();
394+
result->clear_top();
388395
}
389-
copy->map[index_value]=environment.write(
396+
result->map[index_value]=environment.write(
390397
array_entry, value, stack, ns, merging_write);
391398

392-
return copy;
399+
return result;
393400
}
394401
else
395402
{
396-
for(const auto &array_entry : map)
403+
shared_array_mapt::viewt view;
404+
map.get_view(view);
405+
406+
for(const auto &array_entry : view)
397407
{
398408
// Merging write since we don't know which index we are writing to
399-
copy->map[array_entry.first]=
409+
result->map[array_entry.first]=
400410
environment.write(
401411
array_entry.second, value, stack, ns, true);
402412
if(is_top())
403413
{
404-
copy->clear_top();
414+
result->clear_top();
405415
}
406416
}
407417

408-
return copy;
418+
return result;
409419
}
410420
}
411421
}
@@ -486,10 +496,27 @@ constant_array_abstract_objectt::visit_sub_elements(
486496
std::dynamic_pointer_cast<constant_array_abstract_objectt>(
487497
mutable_clone());
488498

489-
for(auto &item : result->map)
499+
bool modified = false;
500+
501+
shared_array_mapt::viewt view;
502+
result->map.get_view(view);
503+
504+
for(auto &item : view)
490505
{
491-
item.second=visitor.visit(item.second);
506+
auto newval = visitor.visit(item.second);
507+
if(newval != item.second)
508+
{
509+
result->map[item.first]=newval;
510+
modified = true;
511+
}
492512
}
493513

494-
return result;
514+
if(modified)
515+
{
516+
return result;
517+
}
518+
else
519+
{
520+
return shared_from_this();
521+
}
495522
}

src/analyses/variable-sensitivity/constant_array_abstract_object.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,15 @@ class constant_array_abstract_objectt:public array_abstract_objectt
7474
// Since we don't store for any index where the value is top
7575
// we don't use a regular array but instead a map of array indices
7676
// to the value at that index
77-
typedef std::map<mp_integer, abstract_object_pointert> array_mapt;
78-
array_mapt map;
77+
struct mp_integer_hash
78+
{
79+
size_t operator()(const mp_integer &i) const { return std::hash<BigInt::ullong_t>{}(i.to_ulong()); }
80+
};
81+
82+
typedef sharing_mapt<mp_integer, abstract_object_pointert, mp_integer_hash>
83+
shared_array_mapt;
84+
85+
shared_array_mapt map;
7986

8087
bool eval_index(
8188
const index_exprt &index,

src/util/sharing_map.h

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ Author: Daniel Poetzl
3939
CV typename sharing_mapt<keyT, valueT, hashT, predT>::ST \
4040
sharing_mapt<keyT, valueT, hashT, predT>
4141

42+
#define SHARING_MAPTV(R, V) \
43+
template <class keyT, class valueT, class hashT, class predT> \
44+
template <class V> \
45+
R sharing_mapt<keyT, valueT, hashT, predT>
46+
4247
template <
4348
class keyT,
4449
class valueT,
@@ -175,6 +180,17 @@ class sharing_mapt
175180

176181
typedef std::pair<const key_type &, const mapped_type &> view_itemt;
177182
typedef std::vector<view_itemt> viewt;
183+
typedef std::set<view_itemt> sorted_viewt;
184+
185+
void insert_view_item(viewt &v, view_itemt &&vi) const
186+
{
187+
v.push_back(vi);
188+
}
189+
190+
void insert_view_item(sorted_viewt &v, view_itemt &&vi) const
191+
{
192+
v.insert(vi);
193+
}
178194

179195
class delta_view_itemt
180196
{
@@ -201,7 +217,7 @@ class sharing_mapt
201217

202218
typedef std::vector<delta_view_itemt> delta_viewt;
203219

204-
void get_view(viewt &view) const;
220+
template <class V> void get_view(V&) const;
205221
viewt get_view() const
206222
{
207223
viewt result;
@@ -214,6 +230,9 @@ class sharing_mapt
214230
delta_viewt &delta_view,
215231
const bool only_common=true) const;
216232

233+
delta_viewt get_delta_view(
234+
const self_type &other, const bool only_common=true) const;
235+
217236
protected:
218237
// helpers
219238

@@ -225,7 +244,7 @@ class sharing_mapt
225244
void gather_all(const node_type &n, delta_viewt &delta_view) const;
226245
};
227246

228-
SHARING_MAPT(void)::get_view(viewt &view) const
247+
SHARING_MAPTV(void, view_type)::get_view(view_type &view) const
229248
{
230249
assert(view.empty());
231250

@@ -245,7 +264,7 @@ SHARING_MAPT(void)::get_view(viewt &view) const
245264
{
246265
for(const auto &child : n->get_container())
247266
{
248-
view.push_back(view_itemt(child.get_key(), child.get_value()));
267+
insert_view_item(view, view_itemt(child.get_key(), child.get_value()));
249268
}
250269
}
251270
else
@@ -403,6 +422,15 @@ SHARING_MAPT(void)::get_delta_view(
403422
while(!stack.empty());
404423
}
405424

425+
SHARING_MAPT2(, delta_viewt)::get_delta_view(
426+
const self_type &other,
427+
const bool only_common) const
428+
{
429+
delta_viewt delta_view;
430+
get_delta_view(other, delta_view, only_common);
431+
return delta_view;
432+
}
433+
406434
SHARING_MAPT2(, node_type *)::get_container_node(const key_type &k)
407435
{
408436
size_t key=hash()(k);

0 commit comments

Comments
 (0)