Skip to content

Commit 72870e4

Browse files
committed
Use sharing_mapt to store propagation map
goto-symex copies a state, which contains a propagation map, at each branching point. The paths originating at that branch point typically share most of the constants being propagated. Thus the copy is unnecessarily expensive, and so is the merge at the next join point, which will also result in one of the propagation maps to be destroyed. With sharing_mapt, the copy has constant cost, and the cost of destruction only depends on the size of the delta.
1 parent 5b9df9b commit 72870e4

File tree

4 files changed

+26
-11
lines changed

4 files changed

+26
-11
lines changed

src/goto-symex/goto_state.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ Author: Romain Brenguier, [email protected]
1717
/// because there aren't any current callers.
1818
void goto_statet::output_propagation_map(std::ostream &out)
1919
{
20-
for(const auto &name_value : propagation)
20+
sharing_mapt<irep_idt, exprt>::viewt view;
21+
propagation.get_view(view);
22+
23+
for(const auto &name_value : view)
2124
{
2225
out << name_value.first << " <- " << format(name_value.second) << "\n";
2326
}
@@ -86,7 +89,11 @@ void goto_statet::apply_condition(
8689
increase_generation(
8790
l1_identifier, l1_lhs, previous_state.get_l2_name_provider());
8891

89-
propagation[l1_identifier] = rhs;
92+
const auto propagation_entry = propagation.find(l1_identifier);
93+
if(!propagation_entry.has_value())
94+
propagation.insert(l1_identifier, rhs);
95+
else if(propagation_entry->get() != rhs)
96+
propagation.replace(l1_identifier, rhs);
9097

9198
value_set.assign(l1_lhs, rhs, ns, true, false);
9299
}

src/goto-symex/goto_state.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Author: Romain Brenguier, [email protected]
1212
#ifndef CPROVER_GOTO_SYMEX_GOTO_STATE_H
1313
#define CPROVER_GOTO_SYMEX_GOTO_STATE_H
1414

15+
#include <util/sharing_map.h>
16+
1517
#include <analyses/guard.h>
1618
#include <analyses/local_safe_pointers.h>
1719
#include <pointer-analysis/value_set.h>
@@ -54,7 +56,7 @@ class goto_statet
5456
// "constants" can include symbols, but only in the context of an address-of
5557
// op (i.e. &x can be propagated), and an address-taken thing should only be
5658
// L1.
57-
std::map<irep_idt, exprt> propagation;
59+
sharing_mapt<irep_idt, exprt> propagation;
5860

5961
void output_propagation_map(std::ostream &);
6062

src/goto-symex/goto_symex_state.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,14 @@ void goto_symex_statet::assignment(
200200
// for value propagation -- the RHS is L2
201201

202202
if(!is_shared && record_value && goto_symex_is_constantt()(rhs))
203-
propagation[l1_identifier] = rhs;
204-
else
203+
{
204+
const auto propagation_entry = propagation.find(l1_identifier);
205+
if(!propagation_entry.has_value())
206+
propagation.insert(l1_identifier, rhs);
207+
else if(propagation_entry->get() != rhs)
208+
propagation.replace(l1_identifier, rhs);
209+
}
210+
else if(propagation.has_key(l1_identifier))
205211
propagation.erase(l1_identifier);
206212

207213
{
@@ -288,8 +294,8 @@ goto_symex_statet::rename(exprt expr, const namespacet &ns)
288294
// L1 identifiers are used for propagation!
289295
auto p_it = propagation.find(ssa.get_identifier());
290296

291-
if(p_it != propagation.end())
292-
expr=p_it->second; // already L2
297+
if(p_it.has_value())
298+
expr = *p_it; // already L2
293299
else
294300
ssa = set_indices<L2>(std::move(ssa), ns).get();
295301
}

src/goto-symex/symex_goto.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -518,17 +518,17 @@ static void merge_names(
518518
{
519519
const auto p_it = goto_state.propagation.find(l1_identifier);
520520

521-
if(p_it != goto_state.propagation.end())
522-
goto_state_rhs = p_it->second;
521+
if(p_it.has_value())
522+
goto_state_rhs = *p_it;
523523
else
524524
to_ssa_expr(goto_state_rhs).set_level_2(goto_count);
525525
}
526526

527527
{
528528
const auto p_it = dest_state.propagation.find(l1_identifier);
529529

530-
if(p_it != dest_state.propagation.end())
531-
dest_state_rhs = p_it->second;
530+
if(p_it.has_value())
531+
dest_state_rhs = *p_it;
532532
else
533533
to_ssa_expr(dest_state_rhs).set_level_2(dest_count);
534534
}

0 commit comments

Comments
 (0)