Skip to content

Commit d583164

Browse files
authored
Merge pull request #4463 from tautschnig/use-sharing-map-for-value-set
Use sharing_mapt as container in value_sett
2 parents 47bdb15 + d4b811b commit d583164

File tree

4 files changed

+118
-143
lines changed

4 files changed

+118
-143
lines changed

src/goto-symex/symex_main.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -676,16 +676,16 @@ void goto_symext::try_filter_value_sets(
676676
}
677677
if(jump_taken_value_set && !erase_from_jump_taken_value_set.empty())
678678
{
679-
value_sett::entryt *entry = jump_taken_value_set->get_entry_for_symbol(
679+
auto entry_index = jump_taken_value_set->get_index_of_symbol(
680680
symbol_expr->get_identifier(), symbol_type, "", ns);
681681
jump_taken_value_set->erase_values_from_entry(
682-
*entry, erase_from_jump_taken_value_set);
682+
*entry_index, erase_from_jump_taken_value_set);
683683
}
684684
if(jump_not_taken_value_set && !erase_from_jump_not_taken_value_set.empty())
685685
{
686-
value_sett::entryt *entry = jump_not_taken_value_set->get_entry_for_symbol(
686+
auto entry_index = jump_not_taken_value_set->get_index_of_symbol(
687687
symbol_expr->get_identifier(), symbol_type, "", ns);
688688
jump_not_taken_value_set->erase_values_from_entry(
689-
*entry, erase_from_jump_not_taken_value_set);
689+
*entry_index, erase_from_jump_not_taken_value_set);
690690
}
691691
}

src/pointer-analysis/value_set.cpp

Lines changed: 84 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,17 @@ bool value_sett::field_sensitive(const irep_idt &id, const typet &type)
4848
return type.id() == ID_struct || type.id() == ID_struct_tag;
4949
}
5050

51-
value_sett::entryt *value_sett::find_entry(const irep_idt &id)
52-
{
53-
auto found = values.find(id);
54-
return found == values.end() ? nullptr : &found->second;
55-
}
56-
5751
const value_sett::entryt *value_sett::find_entry(const irep_idt &id) const
5852
{
5953
auto found = values.find(id);
60-
return found == values.end() ? nullptr : &found->second;
54+
return !found.has_value() ? nullptr : &(found->get());
6155
}
6256

63-
value_sett::entryt &value_sett::get_entry(const entryt &e, const typet &type)
57+
void value_sett::update_entry(
58+
const entryt &e,
59+
const typet &type,
60+
const object_mapt &new_values,
61+
bool add_to_sets)
6462
{
6563
irep_idt index;
6664

@@ -69,10 +67,27 @@ value_sett::entryt &value_sett::get_entry(const entryt &e, const typet &type)
6967
else
7068
index=e.identifier;
7169

72-
std::pair<valuest::iterator, bool> r =
73-
values.insert(std::pair<irep_idt, entryt>(index, e));
74-
75-
return r.first->second;
70+
auto existing_entry = values.find(index);
71+
if(existing_entry.has_value())
72+
{
73+
entryt replacement = *existing_entry;
74+
if(add_to_sets)
75+
{
76+
if(make_union(replacement.object_map, new_values))
77+
values.replace(index, std::move(replacement));
78+
}
79+
else
80+
{
81+
replacement.object_map = new_values;
82+
values.replace(index, std::move(replacement));
83+
}
84+
}
85+
else
86+
{
87+
entryt new_entry = e;
88+
new_entry.object_map = new_values;
89+
values.insert(index, std::move(new_entry));
90+
}
7691
}
7792

7893
bool value_sett::insert(
@@ -103,7 +118,10 @@ void value_sett::output(
103118
const namespacet &ns,
104119
std::ostream &out) const
105120
{
106-
for(const auto &values_entry : values)
121+
valuest::viewt view;
122+
values.get_view(view);
123+
124+
for(const auto &values_entry : view)
107125
{
108126
irep_idt identifier, display_name;
109127

@@ -210,36 +228,26 @@ bool value_sett::make_union(const value_sett::valuest &new_values)
210228
{
211229
bool result=false;
212230

213-
valuest::iterator v_it=values.begin();
231+
value_sett::valuest::delta_viewt delta_view;
232+
233+
new_values.get_delta_view(values, delta_view, false);
214234

215-
for(valuest::const_iterator
216-
it=new_values.begin();
217-
it!=new_values.end();
218-
) // no it++
235+
for(const auto &delta_entry : delta_view)
219236
{
220-
if(v_it==values.end() || it->first<v_it->first)
237+
if(delta_entry.in_both)
221238
{
222-
values.insert(v_it, *it);
223-
result=true;
224-
it++;
225-
continue;
239+
entryt merged_entry = *values.find(delta_entry.k);
240+
if(make_union(merged_entry.object_map, delta_entry.m.object_map))
241+
{
242+
values.replace(delta_entry.k, std::move(merged_entry));
243+
result = true;
244+
}
226245
}
227-
else if(v_it->first<it->first)
246+
else
228247
{
229-
v_it++;
230-
continue;
248+
values.insert(delta_entry.k, delta_entry.m);
249+
result = true;
231250
}
232-
233-
assert(v_it->first==it->first);
234-
235-
entryt &e=v_it->second;
236-
const entryt &new_e=it->second;
237-
238-
if(make_union(e.object_map, new_e.object_map))
239-
result=true;
240-
241-
v_it++;
242-
it++;
243251
}
244252

245253
return result;
@@ -371,77 +379,55 @@ static std::string strip_first_field_from_suffix(
371379
return suffix.substr(field.length() + 1);
372380
}
373381

374-
template <class maybe_const_value_sett>
375-
auto value_sett::get_entry_for_symbol(
376-
maybe_const_value_sett &value_set,
377-
const irep_idt identifier,
382+
optionalt<irep_idt> value_sett::get_index_of_symbol(
383+
irep_idt identifier,
378384
const typet &type,
379385
const std::string &suffix,
380-
const namespacet &ns) ->
381-
typename std::conditional<std::is_const<maybe_const_value_sett>::value,
382-
const value_sett::entryt *,
383-
value_sett::entryt *>::type
386+
const namespacet &ns) const
384387
{
385388
if(
386389
type.id() != ID_pointer && type.id() != ID_signedbv &&
387390
type.id() != ID_unsignedbv && type.id() != ID_array &&
388391
type.id() != ID_struct && type.id() != ID_struct_tag &&
389392
type.id() != ID_union && type.id() != ID_union_tag)
390393
{
391-
return nullptr;
394+
return {};
392395
}
393396

397+
// look it up
398+
irep_idt index = id2string(identifier) + suffix;
399+
auto *entry = find_entry(index);
400+
if(entry)
401+
return std::move(index);
402+
394403
const typet &followed_type = type.id() == ID_struct_tag
395404
? ns.follow_tag(to_struct_tag_type(type))
396405
: type.id() == ID_union_tag
397406
? ns.follow_tag(to_union_tag_type(type))
398407
: type;
399408

400-
// look it up
401-
auto *entry = value_set.find_entry(id2string(identifier) + suffix);
402-
403409
// try first component name as suffix if not yet found
404-
if(
405-
!entry &&
406-
(followed_type.id() == ID_struct || followed_type.id() == ID_union))
410+
if(followed_type.id() == ID_struct || followed_type.id() == ID_union)
407411
{
408412
const struct_union_typet &struct_union_type =
409413
to_struct_union_type(followed_type);
410414

411415
const irep_idt &first_component_name =
412416
struct_union_type.components().front().get_name();
413417

414-
entry = value_set.find_entry(
415-
id2string(identifier) + "." + id2string(first_component_name) + suffix);
416-
}
417-
418-
if(!entry)
419-
{
420-
// not found? try without suffix
421-
entry = value_set.find_entry(identifier);
418+
index =
419+
id2string(identifier) + "." + id2string(first_component_name) + suffix;
420+
entry = find_entry(index);
421+
if(entry)
422+
return std::move(index);
422423
}
423424

424-
return entry;
425-
}
426-
427-
// Explicitly instantiate the two possible versions of the method above:
428-
429-
value_sett::entryt *value_sett::get_entry_for_symbol(
430-
irep_idt identifier,
431-
const typet &type,
432-
const std::string &suffix,
433-
const namespacet &ns)
434-
{
435-
return get_entry_for_symbol(*this, identifier, type, suffix, ns);
436-
}
425+
// not found? try without suffix
426+
entry = find_entry(identifier);
427+
if(entry)
428+
return std::move(identifier);
437429

438-
const value_sett::entryt *value_sett::get_entry_for_symbol(
439-
irep_idt identifier,
440-
const typet &type,
441-
const std::string &suffix,
442-
const namespacet &ns) const
443-
{
444-
return get_entry_for_symbol(*this, identifier, type, suffix, ns);
430+
return {};
445431
}
446432

447433
void value_sett::get_value_set_rec(
@@ -491,11 +477,11 @@ void value_sett::get_value_set_rec(
491477
}
492478
else if(expr.id()==ID_symbol)
493479
{
494-
const entryt *entry = get_entry_for_symbol(
480+
auto entry_index = get_index_of_symbol(
495481
to_symbol_expr(expr).get_identifier(), expr_type, suffix, ns);
496482

497-
if(entry)
498-
make_union(dest, entry->object_map);
483+
if(entry_index.has_value())
484+
make_union(dest, find_entry(*entry_index)->object_map);
499485
else
500486
insert(dest, exprt(ID_unknown, original_type));
501487
}
@@ -1314,12 +1300,8 @@ void value_sett::assign_rec(
13141300
{
13151301
const irep_idt &identifier=to_symbol_expr(lhs).get_identifier();
13161302

1317-
entryt &e = get_entry(entryt(identifier, suffix), lhs.type());
1318-
1319-
if(add_to_sets)
1320-
make_union(e.object_map, values_rhs);
1321-
else
1322-
e.object_map=values_rhs;
1303+
update_entry(
1304+
entryt{identifier, suffix}, lhs.type(), values_rhs, add_to_sets);
13231305
}
13241306
else if(lhs.id()==ID_dynamic_object)
13251307
{
@@ -1330,9 +1312,7 @@ void value_sett::assign_rec(
13301312
"value_set::dynamic_object"+
13311313
std::to_string(dynamic_object.get_instance());
13321314

1333-
entryt &e = get_entry(entryt(name, suffix), lhs.type());
1334-
1335-
make_union(e.object_map, values_rhs);
1315+
update_entry(entryt{name, suffix}, lhs.type(), values_rhs, true);
13361316
}
13371317
else if(lhs.id()==ID_dereference)
13381318
{
@@ -1640,12 +1620,19 @@ void value_sett::guard(
16401620
}
16411621

16421622
void value_sett::erase_values_from_entry(
1643-
entryt &entry,
1623+
const irep_idt &index,
16441624
const std::unordered_set<exprt, irep_hash> &values_to_erase)
16451625
{
1626+
if(values_to_erase.empty())
1627+
return;
1628+
1629+
auto entry = find_entry(index);
1630+
if(!entry)
1631+
return;
1632+
16461633
std::vector<object_map_dt::key_type> keys_to_erase;
16471634

1648-
for(auto &key_value : entry.object_map.read())
1635+
for(auto &key_value : entry->object_map.read())
16491636
{
16501637
const auto &rhs_object = to_expr(key_value);
16511638
if(values_to_erase.count(rhs_object))
@@ -1659,8 +1646,10 @@ void value_sett::erase_values_from_entry(
16591646
"value_sett::erase_value_from_entry() should erase exactly one value for "
16601647
"each element in the set it is given");
16611648

1649+
entryt replacement = *entry;
16621650
for(const auto &key_to_erase : keys_to_erase)
16631651
{
1664-
entry.object_map.write().erase(key_to_erase);
1652+
replacement.object_map.write().erase(key_to_erase);
16651653
}
1654+
values.replace(index, std::move(replacement));
16661655
}

0 commit comments

Comments
 (0)