Skip to content

Commit 09254a9

Browse files
committed
Centralize generational increases of level2 names
Refactor all local name operations to within the level2 object itself to allow for shadowing global state with the local dictionary.
1 parent 2bf0a3a commit 09254a9

File tree

8 files changed

+106
-42
lines changed

8 files changed

+106
-42
lines changed

src/goto-symex/auto_objects.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ void goto_symext::trigger_auto_object(
9595
if(has_prefix(id2string(symbol.base_name), "auto_object"))
9696
{
9797
// done already?
98-
if(state.level2.current_names.find(ssa_expr.get_identifier())==
99-
state.level2.current_names.end())
98+
if(state.level2.current_names->find(ssa_expr.get_identifier())==
99+
state.level2.current_names->end())
100100
{
101101
initialize_auto_object(expr, state);
102102
}

src/goto-symex/goto_symex_state.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,7 @@ void goto_symex_statet::assignment(
181181
#endif
182182

183183
// do the l2 renaming
184-
const auto level2_it =
185-
level2.current_names.emplace(l1_identifier, std::make_pair(lhs, 0)).first;
186-
symex_renaming_levelt::increase_counter(level2_it);
184+
level2.increase_generation(l1_identifier, lhs);
187185
set_l2_indices(lhs, ns);
188186

189187
// in case we happen to be multi-threaded, record the memory access
@@ -429,10 +427,7 @@ bool goto_symex_statet::l2_thread_read_encoding(
429427

430428
if(a_s_read.second.empty())
431429
{
432-
auto level2_it =
433-
level2.current_names.emplace(l1_identifier, std::make_pair(ssa_l1, 0))
434-
.first;
435-
symex_renaming_levelt::increase_counter(level2_it);
430+
level2.increase_generation(l1_identifier, ssa_l1);
436431
a_s_read.first=level2.current_count(l1_identifier);
437432
}
438433

@@ -468,10 +463,6 @@ bool goto_symex_statet::l2_thread_read_encoding(
468463
return true;
469464
}
470465

471-
const auto level2_it =
472-
level2.current_names.emplace(l1_identifier, std::make_pair(ssa_l1, 0))
473-
.first;
474-
475466
// No event and no fresh index, but avoid constant propagation
476467
if(!record_events)
477468
{
@@ -481,7 +472,8 @@ bool goto_symex_statet::l2_thread_read_encoding(
481472
}
482473

483474
// produce a fresh L2 name
484-
symex_renaming_levelt::increase_counter(level2_it);
475+
level2.increase_generation(l1_identifier, ssa_l1);
476+
485477
set_l2_indices(ssa_l1, ns);
486478
expr=ssa_l1;
487479

src/goto-symex/renaming_level.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ void symex_level1t::operator()(ssa_exprt &ssa_expr)
5050

5151
const irep_idt l0_name = ssa_expr.get_l1_object_identifier();
5252

53-
const auto it = current_names.find(l0_name);
54-
if(it == current_names.end())
53+
const auto it = current_names->find(l0_name);
54+
if(it == current_names->end())
5555
return;
5656

5757
// rename!
@@ -61,14 +61,14 @@ void symex_level1t::operator()(ssa_exprt &ssa_expr)
6161
void symex_level1t::restore_from(
6262
const symex_renaming_levelt::current_namest &other)
6363
{
64-
auto it = current_names.begin();
64+
auto it = current_names->begin();
6565
for(const auto &pair : other)
6666
{
67-
while(it != current_names.end() && it->first < pair.first)
67+
while(it != current_names->end() && it->first < pair.first)
6868
++it;
69-
if(it == current_names.end() || pair.first < it->first)
70-
current_names.insert(it, pair);
71-
else if(it != current_names.end())
69+
if(it == current_names->end() || pair.first < it->first)
70+
current_names->insert(it, pair);
71+
else if(it != current_names->end())
7272
{
7373
PRECONDITION(it->first == pair.first);
7474
it->second = pair.second;

src/goto-symex/renaming_level.h

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ Author: Romain Brenguier, [email protected]
1414

1515
#include <map>
1616
#include <unordered_set>
17+
#include <memory>
1718

1819
#include <util/irep.h>
1920
#include <util/ssa_expr.h>
21+
#include <iostream>
2022

2123
/// Wrapper for a \c current_names map, which maps each identifier to an SSA
2224
/// expression and a counter.
@@ -28,13 +30,13 @@ struct symex_renaming_levelt
2830

2931
/// Map identifier to ssa_exprt and counter
3032
typedef std::map<irep_idt, std::pair<ssa_exprt, unsigned>> current_namest;
31-
current_namest current_names;
33+
current_namest *current_names = new current_namest;
3234

3335
/// Counter corresponding to an identifier
34-
unsigned current_count(const irep_idt &identifier) const
36+
virtual unsigned current_count(const irep_idt &identifier) const
3537
{
36-
const auto it = current_names.find(identifier);
37-
return it == current_names.end() ? 0 : it->second.second;
38+
const auto it = current_names->find(identifier);
39+
return it == current_names->end() ? 0 : it->second.second;
3840
}
3941

4042
/// Increase the counter corresponding to an identifier
@@ -46,7 +48,7 @@ struct symex_renaming_levelt
4648
/// Add the \c ssa_exprt of current_names to vars
4749
void get_variables(std::unordered_set<ssa_exprt, irep_hash> &vars) const
4850
{
49-
for(const auto &pair : current_names)
51+
for(const auto &pair : *current_names)
5052
vars.insert(pair.second.first);
5153
}
5254
};
@@ -84,6 +86,80 @@ struct symex_level2t : public symex_renaming_levelt
8486
{
8587
symex_level2t() = default;
8688
~symex_level2t() override = default;
89+
90+
/// In the case of a state split, we want to keep track of the overall
91+
/// name generation across all states for identifier creation.
92+
optionalt<current_namest> local_generations;
93+
94+
void erase(const irep_idt &identifier)
95+
{
96+
current_names->erase(identifier);
97+
if (local_generations)
98+
local_generations->erase(identifier);
99+
}
100+
101+
/// If we have a local counter, use that instead of our global.
102+
unsigned current_count(const irep_idt &identifier) const override
103+
{
104+
if(local_generations)
105+
{
106+
const auto it = local_generations->find(identifier);
107+
return it == local_generations->end() ? 0 : it->second.second;
108+
}
109+
else
110+
{
111+
return symex_renaming_levelt::current_count(identifier);
112+
}
113+
}
114+
115+
/// Ages the generation of an ssa expression by one.
116+
void increase_generation(
117+
const irep_idt l1_identifier,
118+
const ssa_exprt &lhs)
119+
{
120+
current_names->emplace(l1_identifier, std::make_pair(lhs, 0));
121+
if (local_generations)
122+
local_generations->emplace(l1_identifier, std::make_pair(lhs, 0));
123+
124+
increase_generation(l1_identifier);
125+
}
126+
127+
/// Ages the generation of an ssa expression by one. Does nothing
128+
/// if there isn't an expression keyed by the l1 identifier.
129+
void increase_generation(
130+
const irep_idt l1_identifier)
131+
{
132+
auto current_names_iter = current_names->find(l1_identifier);
133+
if (current_names_iter == current_names->end())
134+
return;
135+
136+
current_names_iter->second.second++;
137+
if(local_generations)
138+
{
139+
auto local_iter = local_generations->find(l1_identifier);
140+
if (local_iter != local_generations->end())
141+
local_iter->second.second = current_names_iter->second.second;
142+
}
143+
}
144+
145+
current_namest get_current_names()
146+
{
147+
return local_generations ? *local_generations : *current_names;
148+
}
149+
150+
void print_differences(const std::string &differences)
151+
{
152+
if (!local_generations)
153+
return;
154+
155+
for(const auto &local_gen : *local_generations)
156+
{
157+
auto local = local_gen.second.second;
158+
auto global = current_names->find(local_gen.first)->second.second;
159+
if (local != global)
160+
std::cout << differences << "ID: " << id2string(local_gen.first) << ", local: " << local << " global: " << global << '\n';
161+
}
162+
}
87163
};
88164

89165
/// Undo all levels of renaming

src/goto-symex/symex_dead.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,5 @@ void goto_symext::symex_dead(statet &state)
5252
state.propagation.erase(l1_identifier);
5353

5454
// L2 renaming
55-
auto level2_it = state.level2.current_names.find(l1_identifier);
56-
if(level2_it != state.level2.current_names.end())
57-
symex_renaming_levelt::increase_counter(level2_it);
55+
state.level2.increase_generation(l1_identifier);
5856
}

src/goto-symex/symex_decl.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,8 @@ void goto_symext::symex_decl(statet &state, const symbol_exprt &expr)
6868
// L2 renaming
6969
// inlining may yield multiple declarations of the same identifier
7070
// within the same L1 context
71-
const auto level2_it =
72-
state.level2.current_names.emplace(l1_identifier, std::make_pair(ssa, 0))
73-
.first;
74-
symex_renaming_levelt::increase_counter(level2_it);
71+
state.level2.increase_generation(l1_identifier, ssa);
72+
7573
const bool record_events=state.record_events;
7674
state.record_events=false;
7775
state.rename(ssa, ns);

src/goto-symex/symex_function_call.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,8 @@ static void pop_frame(goto_symext::statet &state)
346346
state.level1.restore_from(frame.old_level1);
347347

348348
// clear function-locals from L2 renaming
349-
for(auto c_it = state.level2.current_names.begin();
350-
c_it != state.level2.current_names.end();) // no ++c_it
349+
for(auto c_it = state.level2.current_names->begin();
350+
c_it != state.level2.current_names->end();) // no ++c_it
351351
{
352352
const irep_idt l1_o_id=c_it->second.first.get_l1_object_identifier();
353353
// could use iteration over local_objects as l1_o_id is prefix
@@ -361,7 +361,7 @@ static void pop_frame(goto_symext::statet &state)
361361
}
362362
auto cur = c_it;
363363
++c_it;
364-
state.level2.current_names.erase(cur);
364+
state.level2.erase(cur->first);
365365
}
366366
}
367367

@@ -409,17 +409,17 @@ static void locality(
409409
const irep_idt l0_name=ssa.get_identifier();
410410

411411
// save old L1 name for popping the frame
412-
auto c_it = state.level1.current_names.find(l0_name);
412+
auto c_it = state.level1.current_names->find(l0_name);
413413

414-
if(c_it != state.level1.current_names.end())
414+
if(c_it != state.level1.current_names->end())
415415
{
416416
frame.old_level1.emplace(l0_name, c_it->second);
417417
c_it->second = std::make_pair(ssa, frame_nr);
418418
}
419419
else
420420
{
421421
c_it = state.level1.current_names
422-
.emplace(l0_name, std::make_pair(ssa, frame_nr))
422+
->emplace(l0_name, std::make_pair(ssa, frame_nr))
423423
.first;
424424
}
425425

src/goto-symex/symex_start_thread.cpp

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

55-
for(auto c_it = state.level2.current_names.begin();
56-
c_it != state.level2.current_names.end();
55+
for(auto c_it = state.level2.current_names->begin();
56+
c_it != state.level2.current_names->end();
5757
++c_it)
5858
{
5959
const irep_idt l1_o_id=c_it->second.first.get_l1_object_identifier();
@@ -68,7 +68,7 @@ void goto_symext::symex_start_thread(statet &state)
6868
lhs.set_level_0(t);
6969

7070
// set up L1 name
71-
if(!state.level1.current_names.insert(
71+
if(!state.level1.current_names->insert(
7272
std::make_pair(lhs.get_l1_object_identifier(),
7373
std::make_pair(lhs, 0))).second)
7474
UNREACHABLE;

0 commit comments

Comments
 (0)