@@ -48,19 +48,17 @@ bool value_sett::field_sensitive(const irep_idt &id, const typet &type)
48
48
return type.id () == ID_struct || type.id () == ID_struct_tag;
49
49
}
50
50
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
-
57
51
const value_sett::entryt *value_sett::find_entry (const irep_idt &id) const
58
52
{
59
53
auto found = values.find (id);
60
- return found == values. end () ? nullptr : &found->second ;
54
+ return ! found. has_value () ? nullptr : &( found->get ()) ;
61
55
}
62
56
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)
64
62
{
65
63
irep_idt index ;
66
64
@@ -69,10 +67,27 @@ value_sett::entryt &value_sett::get_entry(const entryt &e, const typet &type)
69
67
else
70
68
index =e.identifier ;
71
69
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
+ }
76
91
}
77
92
78
93
bool value_sett::insert (
@@ -103,7 +118,10 @@ void value_sett::output(
103
118
const namespacet &ns,
104
119
std::ostream &out) const
105
120
{
106
- for (const auto &values_entry : values)
121
+ valuest::viewt view;
122
+ values.get_view (view);
123
+
124
+ for (const auto &values_entry : view)
107
125
{
108
126
irep_idt identifier, display_name;
109
127
@@ -210,36 +228,26 @@ bool value_sett::make_union(const value_sett::valuest &new_values)
210
228
{
211
229
bool result=false ;
212
230
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 );
214
234
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)
219
236
{
220
- if (v_it==values. end () || it-> first <v_it-> first )
237
+ if (delta_entry. in_both )
221
238
{
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
+ }
226
245
}
227
- else if (v_it-> first <it-> first )
246
+ else
228
247
{
229
- v_it++ ;
230
- continue ;
248
+ values. insert (delta_entry. k , delta_entry. m ) ;
249
+ result = true ;
231
250
}
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++;
243
251
}
244
252
245
253
return result;
@@ -371,77 +379,55 @@ static std::string strip_first_field_from_suffix(
371
379
return suffix.substr (field.length () + 1 );
372
380
}
373
381
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,
378
384
const typet &type,
379
385
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
384
387
{
385
388
if (
386
389
type.id () != ID_pointer && type.id () != ID_signedbv &&
387
390
type.id () != ID_unsignedbv && type.id () != ID_array &&
388
391
type.id () != ID_struct && type.id () != ID_struct_tag &&
389
392
type.id () != ID_union && type.id () != ID_union_tag)
390
393
{
391
- return nullptr ;
394
+ return {} ;
392
395
}
393
396
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
+
394
403
const typet &followed_type = type.id () == ID_struct_tag
395
404
? ns.follow_tag (to_struct_tag_type (type))
396
405
: type.id () == ID_union_tag
397
406
? ns.follow_tag (to_union_tag_type (type))
398
407
: type;
399
408
400
- // look it up
401
- auto *entry = value_set.find_entry (id2string (identifier) + suffix);
402
-
403
409
// 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)
407
411
{
408
412
const struct_union_typet &struct_union_type =
409
413
to_struct_union_type (followed_type);
410
414
411
415
const irep_idt &first_component_name =
412
416
struct_union_type.components ().front ().get_name ();
413
417
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 );
422
423
}
423
424
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);
437
429
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 {};
445
431
}
446
432
447
433
void value_sett::get_value_set_rec (
@@ -491,11 +477,11 @@ void value_sett::get_value_set_rec(
491
477
}
492
478
else if (expr.id ()==ID_symbol)
493
479
{
494
- const entryt *entry = get_entry_for_symbol (
480
+ auto entry_index = get_index_of_symbol (
495
481
to_symbol_expr (expr).get_identifier (), expr_type, suffix, ns);
496
482
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 );
499
485
else
500
486
insert (dest, exprt (ID_unknown, original_type));
501
487
}
@@ -1314,12 +1300,8 @@ void value_sett::assign_rec(
1314
1300
{
1315
1301
const irep_idt &identifier=to_symbol_expr (lhs).get_identifier ();
1316
1302
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);
1323
1305
}
1324
1306
else if (lhs.id ()==ID_dynamic_object)
1325
1307
{
@@ -1330,9 +1312,7 @@ void value_sett::assign_rec(
1330
1312
" value_set::dynamic_object" +
1331
1313
std::to_string (dynamic_object.get_instance ());
1332
1314
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 );
1336
1316
}
1337
1317
else if (lhs.id ()==ID_dereference)
1338
1318
{
@@ -1640,12 +1620,19 @@ void value_sett::guard(
1640
1620
}
1641
1621
1642
1622
void value_sett::erase_values_from_entry (
1643
- entryt &entry ,
1623
+ const irep_idt &index ,
1644
1624
const std::unordered_set<exprt, irep_hash> &values_to_erase)
1645
1625
{
1626
+ if (values_to_erase.empty ())
1627
+ return ;
1628
+
1629
+ auto entry = find_entry (index );
1630
+ if (!entry)
1631
+ return ;
1632
+
1646
1633
std::vector<object_map_dt::key_type> keys_to_erase;
1647
1634
1648
- for (auto &key_value : entry. object_map .read ())
1635
+ for (auto &key_value : entry-> object_map .read ())
1649
1636
{
1650
1637
const auto &rhs_object = to_expr (key_value);
1651
1638
if (values_to_erase.count (rhs_object))
@@ -1659,8 +1646,10 @@ void value_sett::erase_values_from_entry(
1659
1646
" value_sett::erase_value_from_entry() should erase exactly one value for "
1660
1647
" each element in the set it is given" );
1661
1648
1649
+ entryt replacement = *entry;
1662
1650
for (const auto &key_to_erase : keys_to_erase)
1663
1651
{
1664
- entry .object_map .write ().erase (key_to_erase);
1652
+ replacement .object_map .write ().erase (key_to_erase);
1665
1653
}
1654
+ values.replace (index , std::move (replacement));
1666
1655
}
0 commit comments