Skip to content

Commit 35088bf

Browse files
author
Owen
committed
Speed up erasing from value sets
1 parent 1639d95 commit 35088bf

File tree

3 files changed

+28
-24
lines changed

3 files changed

+28
-24
lines changed

src/goto-symex/symex_main.cpp

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -606,10 +606,11 @@ void goto_symext::try_filter_value_sets(
606606
value_setst::valuest value_set_elements;
607607
original_value_set.get_value_set(*symbol_expr, value_set_elements, ns);
608608

609-
std::vector<exprt> delete_from_jump_taken_value_set;
610-
std::vector<exprt> delete_from_jump_not_taken_value_set;
611-
delete_from_jump_taken_value_set.reserve(value_set_elements.size());
612-
delete_from_jump_not_taken_value_set.reserve(value_set_elements.size());
609+
610+
std::unordered_set<exprt, irep_hash> erase_from_jump_taken_value_set;
611+
std::unordered_set<exprt, irep_hash> erase_from_jump_not_taken_value_set;
612+
erase_from_jump_taken_value_set.reserve(value_set_elements.size());
613+
erase_from_jump_not_taken_value_set.reserve(value_set_elements.size());
613614

614615
// Try evaluating the condition with the symbol replaced by a pointer to each
615616
// one of its possible values in turn. If that leads to a true for some
@@ -667,29 +668,25 @@ void goto_symext::try_filter_value_sets(
667668

668669
if(jump_taken_value_set && modified_condition.is_false())
669670
{
670-
delete_from_jump_taken_value_set.emplace_back(value_set_element);
671+
erase_from_jump_taken_value_set.insert(value_set_element);
671672
}
672673
else if(jump_not_taken_value_set && modified_condition.is_true())
673674
{
674-
delete_from_jump_not_taken_value_set.emplace_back(value_set_element);
675+
erase_from_jump_not_taken_value_set.insert(value_set_element);
675676
}
676677
}
677-
if(jump_taken_value_set && !delete_from_jump_taken_value_set.empty())
678+
if(jump_taken_value_set && !erase_from_jump_taken_value_set.empty())
678679
{
679680
value_sett::entryt *entry = jump_taken_value_set->get_entry_for_symbol(
680681
symbol_expr->get_identifier(), symbol_type, "", ns);
681-
for(const exprt &value_to_erase : delete_from_jump_taken_value_set)
682-
{
683-
jump_taken_value_set->erase_value_from_entry(*entry, value_to_erase);
684-
}
682+
jump_taken_value_set->erase_values_from_entry(
683+
*entry, erase_from_jump_taken_value_set);
685684
}
686-
if(jump_not_taken_value_set && !delete_from_jump_not_taken_value_set.empty())
685+
if(jump_not_taken_value_set && !erase_from_jump_not_taken_value_set.empty())
687686
{
688687
value_sett::entryt *entry = jump_not_taken_value_set->get_entry_for_symbol(
689688
symbol_expr->get_identifier(), symbol_type, "", ns);
690-
for(const exprt &value_to_erase : delete_from_jump_not_taken_value_set)
691-
{
692-
jump_not_taken_value_set->erase_value_from_entry(*entry, value_to_erase);
693-
}
689+
jump_not_taken_value_set->erase_values_from_entry(
690+
*entry, erase_from_jump_not_taken_value_set);
694691
}
695692
}

src/pointer-analysis/value_set.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,24 +1624,28 @@ void value_sett::guard(
16241624
}
16251625
}
16261626

1627-
void value_sett::erase_value_from_entry(
1627+
void value_sett::erase_values_from_entry(
16281628
entryt &entry,
1629-
const exprt &value_to_erase)
1629+
const std::unordered_set<exprt, irep_hash> &values_to_erase)
16301630
{
16311631
std::vector<object_map_dt::key_type> keys_to_erase;
16321632

1633-
for(const auto &key_value : entry.object_map.read())
1633+
for(auto &key_value : entry.object_map.read())
16341634
{
16351635
const auto &rhs_object = to_expr(key_value);
1636-
if(rhs_object == value_to_erase)
1636+
if(values_to_erase.count(rhs_object))
16371637
{
16381638
keys_to_erase.emplace_back(key_value.first);
16391639
}
16401640
}
16411641

16421642
DATA_INVARIANT(
1643-
keys_to_erase.size() == 1,
1644-
"value_sett::erase_value_from_entry() should erase exactly one value");
1643+
keys_to_erase.size() == values_to_erase.size(),
1644+
"value_sett::erase_value_from_entry() should erase exactly one value for "
1645+
"each element in the set it is given");
16451646

1646-
entry.object_map.write().erase(keys_to_erase[0]);
1647+
for(const auto &key_to_erase : keys_to_erase)
1648+
{
1649+
entry.object_map.write().erase(key_to_erase);
1650+
}
16471651
}

src/pointer-analysis/value_set.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Author: Daniel Kroening, [email protected]
1313
#define CPROVER_POINTER_ANALYSIS_VALUE_SET_H
1414

1515
#include <set>
16+
#include <unordered_set>
1617

1718
#include <util/mp_arith.h>
1819
#include <util/reference_counting.h>
@@ -483,7 +484,9 @@ class value_sett
483484
const std::string &suffix,
484485
const namespacet &ns) const;
485486

486-
void erase_value_from_entry(entryt &entry, const exprt &value_to_erase);
487+
void erase_values_from_entry(
488+
entryt &entry,
489+
const std::unordered_set<exprt, irep_hash> &values_to_erase);
487490

488491
protected:
489492
/// Reads the set of objects pointed to by `expr`, including making

0 commit comments

Comments
 (0)