Skip to content

Commit 9edc38c

Browse files
committed
Use the sharing map for the renaming level maps
1 parent a139e2a commit 9edc38c

10 files changed

+136
-112
lines changed

src/goto-symex/auto_objects.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,7 @@ void goto_symext::trigger_auto_object(const exprt &expr, statet &state)
9191
if(has_prefix(id2string(symbol.base_name), "auto_object"))
9292
{
9393
// done already?
94-
if(
95-
state.get_level2().current_names.find(ssa_expr.get_identifier()) ==
96-
state.get_level2().current_names.end())
94+
if(!state.get_level2().current_names.has_key(ssa_expr.get_identifier()))
9795
{
9896
initialize_auto_object(expr, state);
9997
}

src/goto-symex/goto_state.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,22 @@ std::size_t goto_statet::increase_generation(
2828
const ssa_exprt &lhs,
2929
std::function<std::size_t(const irep_idt &)> fresh_l2_name_provider)
3030
{
31-
auto current_emplace_res =
32-
level2.current_names.emplace(l1_identifier, std::make_pair(lhs, 0));
31+
std::size_t n = fresh_l2_name_provider(l1_identifier);
3332

34-
current_emplace_res.first->second.second =
35-
fresh_l2_name_provider(l1_identifier);
33+
const auto r_opt = level2.current_names.find(l1_identifier);
3634

37-
return current_emplace_res.first->second.second;
35+
if(!r_opt)
36+
{
37+
level2.current_names.insert(l1_identifier, std::make_pair(lhs, n));
38+
}
39+
else
40+
{
41+
std::pair<ssa_exprt, unsigned> copy = r_opt->get();
42+
copy.second = n;
43+
level2.current_names.replace(l1_identifier, copy);
44+
}
45+
46+
return n;
3847
}
3948

4049
/// Given a condition that must hold on this path, propagate as much knowledge

src/goto-symex/goto_symex_state.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -776,16 +776,20 @@ ssa_exprt goto_symex_statet::add_object(
776776
const irep_idt l0_name = ssa.get_identifier();
777777
const std::size_t l1_index = index_generator(l0_name);
778778

779-
// save old L1 name, if any
780-
auto existing_or_new_entry = level1.current_names.emplace(
781-
std::piecewise_construct,
782-
std::forward_as_tuple(l0_name),
783-
std::forward_as_tuple(ssa, l1_index));
779+
const auto r_opt = level1.current_names.find(l0_name);
784780

785-
if(!existing_or_new_entry.second)
781+
if(!r_opt)
786782
{
787-
frame.old_level1.emplace(l0_name, existing_or_new_entry.first->second);
788-
existing_or_new_entry.first->second = std::make_pair(ssa, l1_index);
783+
level1.current_names.insert(l0_name, std::make_pair(ssa, l1_index));
784+
}
785+
else
786+
{
787+
if(!frame.old_level1.has_key(l0_name))
788+
{
789+
frame.old_level1.insert(l0_name, r_opt->get());
790+
}
791+
792+
level1.current_names.replace(l0_name, std::make_pair(ssa, l1_index));
789793
}
790794

791795
ssa = rename_ssa<L1>(std::move(ssa), ns).get();

src/goto-symex/goto_symex_state.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,15 +223,16 @@ class goto_symex_statet final : public goto_statet
223223
}
224224

225225
/// Drops an L1 name from the local L2 map
226-
void drop_l1_name(symex_renaming_levelt::current_namest::const_iterator it)
226+
void drop_existing_l1_name(const irep_idt &l1_identifier)
227227
{
228-
level2.current_names.erase(it);
228+
level2.current_names.erase(l1_identifier);
229229
}
230230

231231
/// Drops an L1 name from the local L2 map
232232
void drop_l1_name(const irep_idt &l1_identifier)
233233
{
234-
level2.current_names.erase(l1_identifier);
234+
if(level2.current_names.has_key(l1_identifier))
235+
level2.current_names.erase(l1_identifier);
235236
}
236237

237238
std::function<std::size_t(const irep_idt &)> get_l2_name_provider() const

src/goto-symex/renaming_level.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,15 @@ operator()(renamedt<ssa_exprt, L0> l0_expr) const
5555

5656
const irep_idt l0_name = l0_expr.get().get_l1_object_identifier();
5757

58-
const auto it = current_names.find(l0_name);
59-
if(it == current_names.end())
58+
const auto r_opt = current_names.find(l0_name);
59+
60+
if(!r_opt)
61+
{
6062
return renamedt<ssa_exprt, L1>{std::move(l0_expr.value())};
63+
}
6164

6265
// rename!
63-
l0_expr.value().set_level_1(it->second.second);
66+
l0_expr.value().set_level_1(r_opt->get().second);
6467
return renamedt<ssa_exprt, L1>{std::move(l0_expr.value())};
6568
}
6669

@@ -75,18 +78,18 @@ operator()(renamedt<ssa_exprt, L1> l1_expr) const
7578

7679
void symex_level1t::restore_from(const current_namest &other)
7780
{
78-
auto it = current_names.begin();
79-
for(const auto &pair : other)
81+
current_namest::delta_viewt delta_view;
82+
other.get_delta_view(current_names, delta_view, false);
83+
84+
for(const auto &delta_item : delta_view)
8085
{
81-
while(it != current_names.end() && it->first < pair.first)
82-
++it;
83-
if(it == current_names.end() || pair.first < it->first)
84-
current_names.insert(it, pair);
85-
else if(it != current_names.end())
86+
if(!delta_item.in_both)
87+
{
88+
current_names.insert(delta_item.k, delta_item.m);
89+
}
90+
else
8691
{
87-
PRECONDITION(it->first == pair.first);
88-
it->second = pair.second;
89-
++it;
92+
current_names.replace(delta_item.k, delta_item.m);
9093
}
9194
}
9295
}

src/goto-symex/renaming_level.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Author: Romain Brenguier, [email protected]
1616
#include <unordered_set>
1717

1818
#include <util/irep.h>
19+
#include <util/sharing_map.h>
1920
#include <util/simplify_expr.h>
2021
#include <util/ssa_expr.h>
2122

@@ -42,27 +43,26 @@ struct symex_renaming_levelt
4243
symex_renaming_levelt(symex_renaming_levelt &&other) = default;
4344

4445
/// Map identifier to ssa_exprt and counter
45-
typedef std::map<irep_idt, std::pair<ssa_exprt, unsigned>> current_namest;
46+
typedef sharing_mapt<irep_idt, std::pair<ssa_exprt, unsigned>> current_namest;
4647
current_namest current_names;
4748

4849
/// Counter corresponding to an identifier
4950
unsigned current_count(const irep_idt &identifier) const
5051
{
51-
const auto it = current_names.find(identifier);
52-
return it == current_names.end() ? 0 : it->second.second;
53-
}
54-
55-
/// Increase the counter corresponding to an identifier
56-
static void increase_counter(const current_namest::iterator &it)
57-
{
58-
++it->second.second;
52+
const auto r_opt = current_names.find(identifier);
53+
return !r_opt ? 0 : r_opt->get().second;
5954
}
6055

6156
/// Add the \c ssa_exprt of current_names to vars
6257
void get_variables(std::unordered_set<ssa_exprt, irep_hash> &vars) const
6358
{
64-
for(const auto &pair : current_names)
59+
current_namest::viewt view;
60+
current_names.get_view(view);
61+
62+
for(const auto &pair : view)
63+
{
6564
vars.insert(pair.second.first);
65+
}
6666
}
6767
};
6868

src/goto-symex/symex_function_call.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -351,23 +351,30 @@ pop_frame(goto_symext::statet &state, const path_storaget &path_storage)
351351
// restore L1 renaming
352352
state.level1.restore_from(frame.old_level1);
353353

354-
// clear function-locals from L2 renaming
355-
for(auto c_it = state.get_level2().current_names.begin();
356-
c_it != state.get_level2().current_names.end();) // no ++c_it
354+
symex_renaming_levelt::current_namest::viewt view;
355+
state.get_level2().current_names.get_view(view);
356+
357+
std::vector<irep_idt> keys_to_erase;
358+
359+
for(const auto &pair : view)
357360
{
358-
const irep_idt l1_o_id=c_it->second.first.get_l1_object_identifier();
361+
const irep_idt l1_o_id = pair.second.first.get_l1_object_identifier();
362+
359363
// could use iteration over local_objects as l1_o_id is prefix
360364
if(
361365
frame.local_objects.find(l1_o_id) == frame.local_objects.end() ||
362366
(state.threads.size() > 1 &&
363-
path_storage.dirty(c_it->second.first.get_object_name())))
367+
path_storage.dirty(pair.second.first.get_object_name())))
364368
{
365-
++c_it;
366369
continue;
367370
}
368-
auto cur = c_it;
369-
++c_it;
370-
state.drop_l1_name(cur);
371+
372+
keys_to_erase.push_back(pair.first);
373+
}
374+
375+
for(const irep_idt &key : keys_to_erase)
376+
{
377+
state.drop_existing_l1_name(key);
371378
}
372379
}
373380

src/goto-symex/symex_goto.cpp

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -414,39 +414,6 @@ void goto_symext::merge_goto(
414414
}
415415
}
416416

417-
/// Applies f to `(k, ssa, i, j)` if the first map maps k to (ssa, i) and
418-
/// the second to (ssa', j). If the first map has an entry for k but not the
419-
/// second one then j is 0, and when the first map has no entry for k then i = 0
420-
static void for_each2(
421-
const std::map<irep_idt, std::pair<ssa_exprt, unsigned>> &first_map,
422-
const std::map<irep_idt, std::pair<ssa_exprt, unsigned>> &second_map,
423-
const std::function<void(const ssa_exprt &, unsigned, unsigned)> &f)
424-
{
425-
auto second_it = second_map.begin();
426-
for(const auto &first_pair : first_map)
427-
{
428-
while(second_it != second_map.end() && second_it->first < first_pair.first)
429-
{
430-
f(second_it->second.first, 0, second_it->second.second);
431-
++second_it;
432-
}
433-
const ssa_exprt &ssa = first_pair.second.first;
434-
const unsigned count = first_pair.second.second;
435-
if(second_it != second_map.end() && second_it->first == first_pair.first)
436-
{
437-
f(ssa, count, second_it->second.second);
438-
++second_it;
439-
}
440-
else
441-
f(ssa, count, 0);
442-
}
443-
while(second_it != second_map.end())
444-
{
445-
f(second_it->second.first, 0, second_it->second.second);
446-
++second_it;
447-
}
448-
}
449-
450417
/// Helper function for \c phi_function which merges the names of an identifier
451418
/// for two different states.
452419
/// \param goto_state: first state
@@ -592,23 +559,56 @@ void goto_symext::phi_function(
592559
// this gets the diff between the guards
593560
diff_guard -= dest_state.guard;
594561

595-
for_each2(
596-
goto_state.get_level2().current_names,
597-
dest_state.get_level2().current_names,
598-
[&](const ssa_exprt &ssa, unsigned goto_count, unsigned dest_count) {
599-
merge_names(
600-
goto_state,
601-
dest_state,
602-
ns,
603-
diff_guard,
604-
log,
605-
symex_config.simplify_opt,
606-
target,
607-
path_storage.dirty,
608-
ssa,
609-
goto_count,
610-
dest_count);
611-
});
562+
symex_renaming_levelt::current_namest::delta_viewt delta_view;
563+
goto_state.get_level2().current_names.get_delta_view(
564+
dest_state.get_level2().current_names, delta_view, false);
565+
566+
for(const auto &delta_item : delta_view)
567+
{
568+
const ssa_exprt &ssa = delta_item.m.first;
569+
unsigned goto_count = delta_item.m.second;
570+
unsigned dest_count = !delta_item.in_both ? 0 : delta_item.other_m.second;
571+
572+
merge_names(
573+
goto_state,
574+
dest_state,
575+
ns,
576+
diff_guard,
577+
log,
578+
symex_config.simplify_opt,
579+
target,
580+
path_storage.dirty,
581+
ssa,
582+
goto_count,
583+
dest_count);
584+
}
585+
586+
delta_view.clear();
587+
dest_state.get_level2().current_names.get_delta_view(
588+
goto_state.get_level2().current_names, delta_view, false);
589+
590+
for(const auto &delta_item : delta_view)
591+
{
592+
if(delta_item.in_both)
593+
continue;
594+
595+
const ssa_exprt &ssa = delta_item.m.first;
596+
unsigned goto_count = 0;
597+
unsigned dest_count = delta_item.m.second;
598+
599+
merge_names(
600+
goto_state,
601+
dest_state,
602+
ns,
603+
diff_guard,
604+
log,
605+
symex_config.simplify_opt,
606+
target,
607+
path_storage.dirty,
608+
ssa,
609+
goto_count,
610+
dest_count);
611+
}
612612
}
613613

614614
void goto_symext::loop_bound_exceeded(

src/goto-symex/symex_start_thread.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,19 @@ void goto_symext::symex_start_thread(statet &state)
5252
// create a copy of the local variables for the new thread
5353
framet &frame = state.call_stack().top();
5454

55-
for(auto c_it = state.get_level2().current_names.begin();
56-
c_it != state.get_level2().current_names.end();
57-
++c_it)
55+
symex_renaming_levelt::current_namest::viewt view;
56+
state.get_level2().current_names.get_view(view);
57+
58+
for(const auto &pair : view)
5859
{
59-
const irep_idt l1_o_id=c_it->second.first.get_l1_object_identifier();
60+
const irep_idt l1_o_id = pair.second.first.get_l1_object_identifier();
61+
6062
// could use iteration over local_objects as l1_o_id is prefix
6163
if(frame.local_objects.find(l1_o_id)==frame.local_objects.end())
6264
continue;
6365

6466
// get original name
65-
ssa_exprt lhs(c_it->second.first.get_original_expr());
67+
ssa_exprt lhs(pair.second.first.get_original_expr());
6668

6769
// get L0 name for current thread
6870
lhs.set_level_0(t);
@@ -71,18 +73,16 @@ void goto_symext::symex_start_thread(statet &state)
7173
CHECK_RETURN(l1_index == 0);
7274

7375
// set up L1 name
74-
auto emplace_result = state.level1.current_names.emplace(
75-
std::piecewise_construct,
76-
std::forward_as_tuple(lhs.get_l1_object_identifier()),
77-
std::forward_as_tuple(lhs, 0));
78-
CHECK_RETURN(emplace_result.second);
76+
state.level1.current_names.insert(
77+
lhs.get_l1_object_identifier(), std::make_pair(lhs, 0));
78+
7979
const ssa_exprt lhs_l1 = state.rename_ssa<L1>(std::move(lhs), ns).get();
8080
const irep_idt l1_name = lhs_l1.get_l1_object_identifier();
8181
// store it
8282
new_thread.call_stack.back().local_objects.insert(l1_name);
8383

8484
// make copy
85-
ssa_exprt rhs=c_it->second.first;
85+
ssa_exprt rhs = pair.second.first;
8686

8787
exprt::operandst lhs_conditions;
8888
const bool record_events=state.record_events;

src/util/ssa_expr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Author: Daniel Kroening, [email protected]
1616
class ssa_exprt:public symbol_exprt
1717
{
1818
public:
19+
ssa_exprt() : symbol_exprt("", typet()) {}
20+
1921
/// Constructor
2022
/// \param expr: Expression to be converted to SSA symbol
2123
explicit ssa_exprt(const exprt &expr) : symbol_exprt(expr.type())

0 commit comments

Comments
 (0)