@@ -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-
5751const 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,22 @@ 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+ make_union (replacement.object_map , new_values);
76+ else
77+ replacement.object_map = new_values;
78+ values.replace (index, std::move (replacement));
79+ }
80+ else
81+ {
82+ entryt new_entry = e;
83+ new_entry.object_map = new_values;
84+ values.insert (index, std::move (new_entry));
85+ }
7686}
7787
7888bool value_sett::insert (
@@ -103,7 +113,10 @@ void value_sett::output(
103113 const namespacet &ns,
104114 std::ostream &out) const
105115{
106- for (const auto &values_entry : values)
116+ valuest::viewt view;
117+ values.get_view (view);
118+
119+ for (const auto &values_entry : view)
107120 {
108121 irep_idt identifier, display_name;
109122
@@ -210,36 +223,26 @@ bool value_sett::make_union(const value_sett::valuest &new_values)
210223{
211224 bool result=false ;
212225
213- valuest::iterator v_it=values. begin () ;
226+ value_sett:: valuest::delta_viewt delta_view ;
214227
215- for (valuest::const_iterator
216- it=new_values.begin ();
217- it!=new_values.end ();
218- ) // no it++
228+ new_values.get_delta_view (values, delta_view, false );
229+
230+ for (const auto &delta_entry : delta_view)
219231 {
220- if (v_it==values. end () || it-> first <v_it-> first )
232+ if (delta_entry. in_both )
221233 {
222- values.insert (v_it, *it);
223- result=true ;
224- it++;
225- continue ;
234+ entryt merged_entry = *values.find (delta_entry.k );
235+ if (make_union (merged_entry.object_map , delta_entry.m .object_map ))
236+ {
237+ values.replace (delta_entry.k , std::move (merged_entry));
238+ result = true ;
239+ }
226240 }
227- else if (v_it-> first <it-> first )
241+ else
228242 {
229- v_it++ ;
230- continue ;
243+ values. insert (delta_entry. k , delta_entry. m ) ;
244+ result = true ;
231245 }
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++;
243246 }
244247
245248 return result;
@@ -371,77 +374,55 @@ static std::string strip_first_field_from_suffix(
371374 return suffix.substr (field.length () + 1 );
372375}
373376
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,
377+ optionalt<irep_idt> value_sett::get_index_of_symbol (
378+ irep_idt identifier,
378379 const typet &type,
379380 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
381+ const namespacet &ns) const
384382{
385383 if (
386384 type.id () != ID_pointer && type.id () != ID_signedbv &&
387385 type.id () != ID_unsignedbv && type.id () != ID_array &&
388386 type.id () != ID_struct && type.id () != ID_struct_tag &&
389387 type.id () != ID_union && type.id () != ID_union_tag)
390388 {
391- return nullptr ;
389+ return {} ;
392390 }
393391
392+ // look it up
393+ irep_idt index = id2string (identifier) + suffix;
394+ auto *entry = find_entry (index);
395+ if (entry)
396+ return std::move (index);
397+
394398 const typet &followed_type = type.id () == ID_struct_tag
395399 ? ns.follow_tag (to_struct_tag_type (type))
396400 : type.id () == ID_union_tag
397401 ? ns.follow_tag (to_union_tag_type (type))
398402 : type;
399403
400- // look it up
401- auto *entry = value_set.find_entry (id2string (identifier) + suffix);
402-
403404 // 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))
405+ if (followed_type.id () == ID_struct || followed_type.id () == ID_union)
407406 {
408407 const struct_union_typet &struct_union_type =
409408 to_struct_union_type (followed_type);
410409
411410 const irep_idt &first_component_name =
412411 struct_union_type.components ().front ().get_name ();
413412
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);
413+ index =
414+ id2string (identifier) + " ." + id2string (first_component_name) + suffix;
415+ entry = find_entry (index);
416+ if (entry)
417+ return std::move (index);
422418 }
423419
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- }
420+ // not found? try without suffix
421+ entry = find_entry (identifier);
422+ if (entry)
423+ return std::move (identifier);
437424
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);
425+ return {};
445426}
446427
447428void value_sett::get_value_set_rec (
@@ -491,11 +472,11 @@ void value_sett::get_value_set_rec(
491472 }
492473 else if (expr.id ()==ID_symbol)
493474 {
494- const entryt * entry = get_entry_for_symbol (
475+ auto entry = get_index_of_symbol (
495476 to_symbol_expr (expr).get_identifier (), expr_type, suffix, ns);
496477
497- if (entry)
498- make_union (dest, entry->object_map );
478+ if (entry. has_value () )
479+ make_union (dest, find_entry (* entry) ->object_map );
499480 else
500481 insert (dest, exprt (ID_unknown, original_type));
501482 }
@@ -1314,12 +1295,8 @@ void value_sett::assign_rec(
13141295 {
13151296 const irep_idt &identifier=to_symbol_expr (lhs).get_identifier ();
13161297
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;
1298+ update_entry (
1299+ entryt{identifier, suffix}, lhs.type (), values_rhs, add_to_sets);
13231300 }
13241301 else if (lhs.id ()==ID_dynamic_object)
13251302 {
@@ -1330,9 +1307,7 @@ void value_sett::assign_rec(
13301307 " value_set::dynamic_object" +
13311308 std::to_string (dynamic_object.get_instance ());
13321309
1333- entryt &e = get_entry (entryt (name, suffix), lhs.type ());
1334-
1335- make_union (e.object_map , values_rhs);
1310+ update_entry (entryt{name, suffix}, lhs.type (), values_rhs, true );
13361311 }
13371312 else if (lhs.id ()==ID_dereference)
13381313 {
@@ -1640,12 +1615,19 @@ void value_sett::guard(
16401615}
16411616
16421617void value_sett::erase_values_from_entry (
1643- entryt &entry ,
1618+ const irep_idt &index ,
16441619 const std::unordered_set<exprt, irep_hash> &values_to_erase)
16451620{
1621+ if (values_to_erase.empty ())
1622+ return ;
1623+
1624+ auto entry = find_entry (index);
1625+ if (!entry)
1626+ return ;
1627+
16461628 std::vector<object_map_dt::key_type> keys_to_erase;
16471629
1648- for (auto &key_value : entry. object_map .read ())
1630+ for (auto &key_value : entry-> object_map .read ())
16491631 {
16501632 const auto &rhs_object = to_expr (key_value);
16511633 if (values_to_erase.count (rhs_object))
@@ -1659,8 +1641,10 @@ void value_sett::erase_values_from_entry(
16591641 " value_sett::erase_value_from_entry() should erase exactly one value for "
16601642 " each element in the set it is given" );
16611643
1644+ entryt replacement = *entry;
16621645 for (const auto &key_to_erase : keys_to_erase)
16631646 {
1664- entry .object_map .write ().erase (key_to_erase);
1647+ replacement .object_map .write ().erase (key_to_erase);
16651648 }
1649+ values.replace (index, std::move (replacement));
16661650}
0 commit comments