Skip to content

Commit 81bc65f

Browse files
authored
Merge pull request #4305 from romainbrenguier/refactor/renamedt
Introduce a renamedt type for renamed expressions in symex
2 parents 7f3c681 + b5ae64b commit 81bc65f

12 files changed

+100
-49
lines changed

src/goto-instrument/accelerate/scratch_program.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ bool scratch_programt::check_sat(bool do_slice)
6969

7070
exprt scratch_programt::eval(const exprt &e)
7171
{
72-
return checker->get(symex_state->rename<goto_symex_statet::L2>(e, ns));
72+
return checker->get(symex_state->rename<L2>(e, ns));
7373
}
7474

7575
void scratch_programt::append(goto_programt::instructionst &new_instructions)

src/goto-symex/goto_symex_state.cpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,9 @@ void goto_symex_statet::set_l0_indices(
237237
ssa_exprt &ssa_expr,
238238
const namespacet &ns)
239239
{
240-
level0(ssa_expr, ns, source.thread_nr);
240+
renamedt<ssa_exprt, L0> renamed =
241+
level0(std::move(ssa_expr), ns, source.thread_nr);
242+
ssa_expr = renamed.get();
241243
}
242244

243245
void goto_symex_statet::set_l1_indices(
@@ -248,8 +250,9 @@ void goto_symex_statet::set_l1_indices(
248250
return;
249251
if(!ssa_expr.get_level_1().empty())
250252
return;
251-
level0(ssa_expr, ns, source.thread_nr);
252-
level1(ssa_expr);
253+
renamedt<ssa_exprt, L1> l1 =
254+
level1(level0(std::move(ssa_expr), ns, source.thread_nr));
255+
ssa_expr = l1.get();
253256
}
254257

255258
void goto_symex_statet::set_l2_indices(
@@ -258,12 +261,12 @@ void goto_symex_statet::set_l2_indices(
258261
{
259262
if(!ssa_expr.get_level_2().empty())
260263
return;
261-
level0(ssa_expr, ns, source.thread_nr);
262-
level1(ssa_expr);
263-
ssa_expr.set_level_2(level2.current_count(ssa_expr.get_identifier()));
264+
renamedt<ssa_exprt, L2> l2 =
265+
level2(level1(level0(std::move(ssa_expr), ns, source.thread_nr)));
266+
ssa_expr = l2.get();
264267
}
265268

266-
template <goto_symex_statet::levelt level>
269+
template <levelt level>
267270
ssa_exprt goto_symex_statet::rename_ssa(ssa_exprt ssa, const namespacet &ns)
268271
{
269272
static_assert(
@@ -282,11 +285,12 @@ ssa_exprt goto_symex_statet::rename_ssa(ssa_exprt ssa, const namespacet &ns)
282285
}
283286

284287
/// Ensure `rename_ssa` gets compiled for L0
285-
template ssa_exprt goto_symex_statet::rename_ssa<goto_symex_statet::L0>(
286-
ssa_exprt ssa,
287-
const namespacet &ns);
288+
template ssa_exprt
289+
goto_symex_statet::rename_ssa<L0>(ssa_exprt ssa, const namespacet &ns);
290+
template ssa_exprt
291+
goto_symex_statet::rename_ssa<L1>(ssa_exprt ssa, const namespacet &ns);
288292

289-
template <goto_symex_statet::levelt level>
293+
template <levelt level>
290294
exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
291295
{
292296
// rename all the symbols with their last known value
@@ -367,6 +371,8 @@ exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
367371
return expr;
368372
}
369373

374+
template exprt goto_symex_statet::rename<L1>(exprt expr, const namespacet &ns);
375+
370376
/// thread encoding
371377
bool goto_symex_statet::l2_thread_read_encoding(
372378
ssa_exprt &expr,
@@ -544,7 +550,7 @@ bool goto_symex_statet::l2_thread_write_encoding(
544550
return threads.size()>1;
545551
}
546552

547-
template <goto_symex_statet::levelt level>
553+
template <levelt level>
548554
void goto_symex_statet::rename_address(exprt &expr, const namespacet &ns)
549555
{
550556
if(expr.id()==ID_symbol &&
@@ -669,7 +675,7 @@ static bool requires_renaming(const typet &type, const namespacet &ns)
669675
return false;
670676
}
671677

672-
template <goto_symex_statet::levelt level>
678+
template <levelt level>
673679
void goto_symex_statet::rename(
674680
typet &type,
675681
const irep_idt &l1_identifier,

src/goto-symex/goto_symex_state.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,6 @@ class goto_symex_statet final : public goto_statet
150150
symex_level0t level0;
151151
symex_level1t level1;
152152

153-
// Symex renaming levels.
154-
enum levelt { L0=0, L1=1, L2=2 };
155-
156153
/// Rewrites symbol expressions in \ref exprt, applying a suffix to each
157154
/// symbol reflecting its most recent version, which differs depending on
158155
/// which level you requested. Each level also updates its predecessors, so

src/goto-symex/renaming_level.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,54 @@ Author: Romain Brenguier, [email protected]
1717

1818
#include "goto_symex_state.h"
1919

20-
void symex_level0t::
21-
operator()(ssa_exprt &ssa_expr, const namespacet &ns, unsigned thread_nr) const
20+
renamedt<ssa_exprt, L0> symex_level0t::
21+
operator()(ssa_exprt ssa_expr, const namespacet &ns, unsigned thread_nr) const
2222
{
2323
// already renamed?
2424
if(!ssa_expr.get_level_0().empty())
25-
return;
25+
return renamedt<ssa_exprt, L0>{std::move(ssa_expr)};
2626

2727
const irep_idt &obj_identifier = ssa_expr.get_object_name();
2828

2929
// guards are not L0-renamed
3030
if(obj_identifier == goto_symex_statet::guard_identifier())
31-
return;
31+
return renamedt<ssa_exprt, L0>{std::move(ssa_expr)};
3232

3333
const symbolt *s;
3434
const bool found_l0 = !ns.lookup(obj_identifier, s);
3535
INVARIANT(found_l0, "level0: failed to find " + id2string(obj_identifier));
3636

3737
// don't rename shared variables or functions
3838
if(s->type.id() == ID_code || s->is_shared())
39-
return;
39+
return renamedt<ssa_exprt, L0>{std::move(ssa_expr)};
4040

4141
// rename!
4242
ssa_expr.set_level_0(thread_nr);
43+
return renamedt<ssa_exprt, L0>{ssa_expr};
4344
}
4445

45-
void symex_level1t::operator()(ssa_exprt &ssa_expr) const
46+
renamedt<ssa_exprt, L1> symex_level1t::
47+
operator()(renamedt<ssa_exprt, L0> l0_expr) const
4648
{
47-
// already renamed?
48-
if(!ssa_expr.get_level_1().empty())
49-
return;
49+
if(!l0_expr.get().get_level_1().empty())
50+
return renamedt<ssa_exprt, L1>{std::move(l0_expr.value)};
5051

51-
const irep_idt l0_name = ssa_expr.get_l1_object_identifier();
52+
const irep_idt l0_name = l0_expr.get().get_l1_object_identifier();
5253

5354
const auto it = current_names.find(l0_name);
5455
if(it == current_names.end())
55-
return;
56+
return renamedt<ssa_exprt, L1>{std::move(l0_expr.value)};
5657

5758
// rename!
58-
ssa_expr.set_level_1(it->second.second);
59+
l0_expr.value.set_level_1(it->second.second);
60+
return renamedt<ssa_exprt, L1>{std::move(l0_expr.value)};
61+
}
62+
63+
renamedt<ssa_exprt, L2> symex_level2t::
64+
operator()(renamedt<ssa_exprt, L1> l1_expr) const
65+
{
66+
l1_expr.value.set_level_2(current_count(l1_expr.get().get_identifier()));
67+
return renamedt<ssa_exprt, L2>{std::move(l1_expr.value)};
5968
}
6069

6170
void symex_level1t::restore_from(

src/goto-symex/renaming_level.h

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ Author: Romain Brenguier, [email protected]
1818
#include <util/irep.h>
1919
#include <util/ssa_expr.h>
2020

21+
/// Symex renaming level names.
22+
enum levelt
23+
{
24+
L0 = 0,
25+
L1 = 1,
26+
L2 = 2
27+
};
28+
2129
/// Wrapper for a \c current_names map, which maps each identifier to an SSA
2230
/// expression and a counter.
2331
/// This is extended by the different symex_level structures which are used
@@ -51,13 +59,44 @@ struct symex_renaming_levelt
5159
}
5260
};
5361

62+
/// Wrapper for expressions or types which have been renamed up to a given
63+
/// \p level
64+
template <typename underlyingt, levelt level>
65+
class renamedt
66+
{
67+
public:
68+
static_assert(
69+
std::is_base_of<exprt, underlyingt>::value ||
70+
std::is_base_of<typet, underlyingt>::value,
71+
"underlyingt should inherit from exprt or typet");
72+
73+
const underlyingt &get() const
74+
{
75+
return value;
76+
}
77+
78+
private:
79+
underlyingt value;
80+
81+
friend struct symex_level0t;
82+
friend struct symex_level1t;
83+
friend struct symex_level2t;
84+
85+
/// Only symex_levelXt classes can create renamedt objects
86+
explicit renamedt(underlyingt value) : value(std::move(value))
87+
{
88+
}
89+
};
90+
5491
/// Functor to set the level 0 renaming of SSA expressions.
5592
/// Level 0 corresponds to threads.
5693
/// The renaming is built for one particular interleaving.
5794
struct symex_level0t : public symex_renaming_levelt
5895
{
59-
void operator()(ssa_exprt &ssa_expr, const namespacet &ns, unsigned thread_nr)
60-
const;
96+
renamedt<ssa_exprt, L0> operator()(
97+
ssa_exprt ssa_expr,
98+
const namespacet &ns,
99+
unsigned thread_nr) const;
61100

62101
symex_level0t() = default;
63102
~symex_level0t() override = default;
@@ -68,7 +107,7 @@ struct symex_level0t : public symex_renaming_levelt
68107
/// This is to preserve locality in case of recursion
69108
struct symex_level1t : public symex_renaming_levelt
70109
{
71-
void operator()(ssa_exprt &ssa_expr) const;
110+
renamedt<ssa_exprt, L1> operator()(renamedt<ssa_exprt, L0> l0_expr) const;
72111

73112
/// Insert the content of \p other into this renaming
74113
void restore_from(const current_namest &other);
@@ -82,6 +121,8 @@ struct symex_level1t : public symex_renaming_levelt
82121
/// This is to ensure each variable is only assigned once.
83122
struct symex_level2t : public symex_renaming_levelt
84123
{
124+
renamedt<ssa_exprt, L2> operator()(renamedt<ssa_exprt, L1> l1_expr) const;
125+
85126
symex_level2t() = default;
86127
~symex_level2t() override = default;
87128
};

src/goto-symex/symex_dead.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ void goto_symext::symex_dead(statet &state)
2626
// We increase the L2 renaming to make these non-deterministic.
2727
// We also prevent propagation of old values.
2828

29-
ssa_exprt ssa = state.rename_ssa<statet::L1>(ssa_exprt{code.symbol()}, ns);
29+
ssa_exprt ssa = state.rename_ssa<L1>(ssa_exprt{code.symbol()}, ns);
3030

3131
// in case of pointers, put something into the value set
3232
if(code.symbol().type().id() == ID_pointer)
@@ -37,8 +37,7 @@ void goto_symext::symex_dead(statet &state)
3737
else
3838
rhs=exprt(ID_invalid);
3939

40-
const exprt l1_rhs =
41-
state.rename<goto_symex_statet::L1>(std::move(rhs), ns);
40+
const exprt l1_rhs = state.rename<L1>(std::move(rhs), ns);
4241
state.value_set.assign(ssa, l1_rhs, ns, true, false);
4342
}
4443

src/goto-symex/symex_decl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ void goto_symext::symex_decl(statet &state, const symbol_exprt &expr)
3737
// We increase the L2 renaming to make these non-deterministic.
3838
// We also prevent propagation of old values.
3939

40-
ssa_exprt ssa = state.rename_ssa<statet::L1>(ssa_exprt{expr}, ns);
40+
ssa_exprt ssa = state.rename_ssa<L1>(ssa_exprt{expr}, ns);
4141
const irep_idt &l1_identifier = ssa.get_identifier();
4242

4343
// rename type to L2
@@ -53,7 +53,7 @@ void goto_symext::symex_decl(statet &state, const symbol_exprt &expr)
5353
else
5454
rhs=exprt(ID_invalid);
5555

56-
exprt l1_rhs = state.rename<goto_symex_statet::L1>(std::move(rhs), ns);
56+
exprt l1_rhs = state.rename<L1>(std::move(rhs), ns);
5757
state.value_set.assign(ssa, l1_rhs, ns, true, false);
5858
}
5959

src/goto-symex/symex_dereference.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,11 +356,11 @@ void goto_symext::dereference(exprt &expr, statet &state)
356356
// from different frames. Would be enough to rename
357357
// symbols whose address is taken.
358358
PRECONDITION(!state.call_stack().empty());
359-
exprt l1_expr = state.rename<goto_symex_statet::L1>(expr, ns);
359+
exprt l1_expr = state.rename<L1>(expr, ns);
360360

361361
// start the recursion!
362362
dereference_rec(l1_expr, state);
363363
// dereferencing may introduce new symbol_exprt
364364
// (like __CPROVER_memory)
365-
expr = state.rename<goto_symex_statet::L1>(std::move(l1_expr), ns);
365+
expr = state.rename<L1>(std::move(l1_expr), ns);
366366
}

src/goto-symex/symex_dereference_state.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ symex_dereference_statet::get_or_create_failed_symbol(const exprt &expr)
4848
{
4949
symbolt sym=*symbol;
5050
symbolt *sym_ptr=nullptr;
51-
const ssa_exprt sym_expr = state.rename_ssa<goto_symex_statet::L1>(
52-
ssa_exprt{sym.symbol_expr()}, ns);
51+
const ssa_exprt sym_expr =
52+
state.rename_ssa<L1>(ssa_exprt{sym.symbol_expr()}, ns);
5353
sym.name = sym_expr.get_identifier();
5454
state.symbol_table.move(sym, sym_ptr);
5555
return sym_ptr;
@@ -68,8 +68,8 @@ symex_dereference_statet::get_or_create_failed_symbol(const exprt &expr)
6868
{
6969
symbolt sym=*symbol;
7070
symbolt *sym_ptr=nullptr;
71-
const ssa_exprt sym_expr = state.rename_ssa<goto_symex_statet::L1>(
72-
ssa_exprt{sym.symbol_expr()}, ns);
71+
const ssa_exprt sym_expr =
72+
state.rename_ssa<L1>(ssa_exprt{sym.symbol_expr()}, ns);
7373
sym.name = sym_expr.get_identifier();
7474
state.symbol_table.move(sym, sym_ptr);
7575
return sym_ptr;

src/goto-symex/symex_function_call.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,8 @@ static void locality(
405405
it++)
406406
{
407407
// get L0 name
408-
ssa_exprt ssa = state.rename_ssa<goto_symex_statet::L0>(
409-
ssa_exprt{ns.lookup(*it).symbol_expr()}, ns);
408+
ssa_exprt ssa =
409+
state.rename_ssa<L0>(ssa_exprt{ns.lookup(*it).symbol_expr()}, ns);
410410
const irep_idt l0_name=ssa.get_identifier();
411411

412412
// save old L1 name for popping the frame
@@ -428,8 +428,7 @@ static void locality(
428428
// identifiers may be shared among functions
429429
// (e.g., due to inlining or other code restructuring)
430430

431-
ssa_exprt ssa_l1 =
432-
state.rename_ssa<goto_symex_statet::L1>(std::move(ssa), ns);
431+
ssa_exprt ssa_l1 = state.rename_ssa<L1>(std::move(ssa), ns);
433432

434433
irep_idt l1_name = ssa_l1.get_identifier();
435434
unsigned offset=0;

src/goto-symex/symex_goto.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ void goto_symext::symex_goto(statet &state)
239239
exprt new_rhs = boolean_negate(new_guard);
240240

241241
ssa_exprt new_lhs =
242-
state.rename_ssa<statet::L1>(ssa_exprt{guard_symbol_expr}, ns);
242+
state.rename_ssa<L1>(ssa_exprt{guard_symbol_expr}, ns);
243243
state.assignment(new_lhs, new_rhs, ns, true, false);
244244

245245
guardt guard{true_exprt{}};

src/goto-symex/symex_start_thread.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void goto_symext::symex_start_thread(statet &state)
7373
std::forward_as_tuple(lhs.get_l1_object_identifier()),
7474
std::forward_as_tuple(lhs, 0));
7575
CHECK_RETURN(emplace_result.second);
76-
const ssa_exprt lhs_l1 = state.rename_ssa<statet::L1>(std::move(lhs), ns);
76+
const ssa_exprt lhs_l1 = state.rename_ssa<L1>(std::move(lhs), ns);
7777
const irep_idt l1_name = lhs_l1.get_l1_object_identifier();
7878
// store it
7979
state.l1_history.insert(l1_name);

0 commit comments

Comments
 (0)