Skip to content

Commit 8784834

Browse files
Make rename_level2 return a level2t
1 parent f8a712f commit 8784834

13 files changed

+148
-109
lines changed

src/goto-instrument/accelerate/scratch_program.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,7 @@ bool scratch_programt::check_sat(bool do_slice)
6262

6363
exprt scratch_programt::eval(const exprt &e)
6464
{
65-
exprt ssa=e;
66-
67-
symex_state.rename_level2(ssa, ns);
68-
69-
return checker->get(ssa);
65+
return checker->get(symex_state.rename_level2(e, ns).expr);
7066
}
7167

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

src/goto-symex/goto_symex_state.cpp

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,37 @@ goto_symex_statet::rename_level1(exprt expr, const namespacet &ns)
408408
}
409409
}
410410

411-
void goto_symex_statet::rename_level2(exprt &expr, const namespacet &ns)
411+
level2t<ssa_exprt>
412+
goto_symex_statet::rename_level2(ssa_exprt ssa, const namespacet &ns)
413+
{
414+
set_l1_indices(level0, level1, ssa, source.thread_nr, ns);
415+
rename(ssa.type(), ssa.get_identifier(), ns);
416+
ssa.update_type();
417+
418+
if(l2_thread_read_encoding(ssa, ns))
419+
{
420+
// renaming taken care of by l2_thread_encoding
421+
}
422+
else if(!ssa.get_level_2().empty())
423+
{
424+
// already at L2
425+
}
426+
else
427+
{
428+
// We also consider propagation if we go up to L2.
429+
// L1 identifiers are used for propagation!
430+
auto p_it = propagation.find(ssa.get_identifier());
431+
432+
if(p_it != propagation.end())
433+
ssa = to_ssa_expr(p_it->second); // already L2
434+
else
435+
set_l2_indices(level0, level1, level2, ssa, source.thread_nr, ns);
436+
}
437+
return level2t<ssa_exprt>{ssa};
438+
}
439+
440+
level2t<exprt>
441+
goto_symex_statet::rename_level2(exprt expr, const namespacet &ns)
412442
{
413443
// rename all the symbols with their last known value
414444
if(expr.id()==ID_symbol &&
@@ -445,12 +475,12 @@ void goto_symex_statet::rename_level2(exprt &expr, const namespacet &ns)
445475
if(expr.type().id() == ID_code)
446476
{
447477
rename(expr.type(), to_symbol_expr(expr).get_identifier(), ns, L2);
448-
449-
return;
450478
}
451-
452-
expr=ssa_exprt(expr);
453-
rename_level2(expr, ns);
479+
else
480+
{
481+
expr = ssa_exprt(expr);
482+
return rename_level2(expr, ns);
483+
}
454484
}
455485
else if(expr.id()==ID_address_of)
456486
{
@@ -465,10 +495,11 @@ void goto_symex_statet::rename_level2(exprt &expr, const namespacet &ns)
465495

466496
// do this recursively
467497
Forall_operands(it, expr)
468-
rename_level2(*it, ns);
498+
*it = rename_level2(std::move(*it), ns).expr;
469499

470500
fix_type(expr);
471501
}
502+
return level2t<exprt>{expr};
472503
}
473504

474505
/// thread encoding
@@ -759,7 +790,7 @@ void goto_symex_statet::rename(
759790
if(level == L1)
760791
e = rename_level1(e, ns).expr;
761792
else
762-
rename_level2(e, ns);
793+
e = rename_level2(e, ns).expr;
763794
};
764795

765796
// rename all the symbols with their last known value

src/goto-symex/goto_symex_state.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ class goto_symex_statet final
7878
level1t<exprt> rename_level1(exprt expr, const namespacet &ns);
7979
level1t<ssa_exprt>
8080
rename_level1(level0t<ssa_exprt> l0_expr, const namespacet &ns);
81-
void rename_level2(exprt &expr, const namespacet &ns);
81+
level2t<exprt> rename_level2(exprt expr, const namespacet &ns);
82+
level2t<ssa_exprt> rename_level2(ssa_exprt ssa, const namespacet &ns);
8283
void rename(
8384
typet &type,
8485
const irep_idt &l1_identifier,

src/goto-symex/renaming_level.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ struct level1t
7171
underlyingt expr;
7272
};
7373

74+
/// Wrapper for expressions that have been renamed at level2
75+
template <typename underlyingt>
76+
struct level2t
77+
{
78+
static_assert(
79+
std::is_base_of<exprt, underlyingt>::value,
80+
"underlyingt should inherit from exprt");
81+
underlyingt expr;
82+
};
83+
7484
inline level1t<ssa_exprt> remove_level2(ssa_exprt ssa)
7585
{
7686
ssa.remove_level_2();

src/goto-symex/symex_assign.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -212,13 +212,13 @@ void goto_symext::symex_assign_symbol(
212212
tmp_ssa_rhs.swap(ssa_rhs);
213213
}
214214

215-
state.rename_level2(ssa_rhs, ns);
216-
do_simplify(ssa_rhs);
215+
level2t<exprt> l2_rhs = state.rename_level2(ssa_rhs, ns);
216+
do_simplify(l2_rhs.expr);
217217

218218
ssa_exprt ssa_lhs=lhs;
219219
state.assignment(
220220
ssa_lhs,
221-
ssa_rhs,
221+
l2_rhs.expr,
222222
ns,
223223
symex_config.simplify_opt,
224224
symex_config.constant_propagation,
@@ -228,7 +228,7 @@ void goto_symext::symex_assign_symbol(
228228
ssa_full_lhs=add_to_lhs(ssa_full_lhs, ssa_lhs);
229229
const bool record_events=state.record_events;
230230
state.record_events=false;
231-
state.rename_level2(ssa_full_lhs, ns);
231+
level2t<exprt> l2_full_lhs = state.rename_level2(ssa_full_lhs, ns);
232232
state.record_events=record_events;
233233

234234
guardt tmp_guard(state.guard);
@@ -254,8 +254,9 @@ void goto_symext::symex_assign_symbol(
254254
target.assignment(
255255
tmp_guard.as_expr(),
256256
ssa_lhs,
257-
ssa_full_lhs, add_to_lhs(full_lhs, ssa_lhs.get_original_expr()),
258-
ssa_rhs,
257+
l2_full_lhs.expr,
258+
add_to_lhs(full_lhs, ssa_lhs.get_original_expr()),
259+
l2_rhs.expr,
259260
state.source,
260261
assignment_type);
261262
}
@@ -407,21 +408,20 @@ void goto_symext::symex_assign_if(
407408

408409
guardt old_guard=guard;
409410

410-
exprt renamed_guard=lhs.cond();
411-
state.rename_level2(renamed_guard, ns);
412-
do_simplify(renamed_guard);
411+
level2t<exprt> renamed_guard = state.rename_level2(lhs.cond(), ns);
412+
do_simplify(renamed_guard.expr);
413413

414-
if(!renamed_guard.is_false())
414+
if(!renamed_guard.expr.is_false())
415415
{
416-
guard.add(renamed_guard);
416+
guard.add(renamed_guard.expr);
417417
symex_assign_rec(
418418
state, lhs.true_case(), full_lhs, rhs, guard, assignment_type);
419419
guard = std::move(old_guard);
420420
}
421421

422-
if(!renamed_guard.is_true())
422+
if(!renamed_guard.expr.is_true())
423423
{
424-
guard.add(not_exprt(renamed_guard));
424+
guard.add(not_exprt(renamed_guard.expr));
425425
symex_assign_rec(
426426
state, lhs.false_case(), full_lhs, rhs, guard, assignment_type);
427427
guard = std::move(old_guard);

src/goto-symex/symex_builtin_functions.cpp

Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -69,36 +69,37 @@ void goto_symext::symex_allocate(
6969
}
7070
else
7171
{
72-
exprt tmp_size=size;
73-
state.rename_level2(tmp_size, ns); // to allow constant propagation
74-
simplify(tmp_size, ns);
72+
// to allow constant propagation
73+
level2t<exprt> tmp_size = state.rename_level2(size, ns);
74+
simplify(tmp_size.expr, ns);
7575

7676
// special treatment for sizeof(T)*x
7777
{
78-
const auto tmp_type = c_sizeof_type_rec(tmp_size);
78+
const auto tmp_type = c_sizeof_type_rec(tmp_size.expr);
7979

8080
if(tmp_type.has_value())
8181
{
8282
// Did the size get multiplied?
8383
auto elem_size = pointer_offset_size(*tmp_type, ns);
84-
const auto alloc_size = numeric_cast<mp_integer>(tmp_size);
84+
const auto alloc_size = numeric_cast<mp_integer>(tmp_size.expr);
8585

8686
if(!elem_size.has_value() || *elem_size==0)
8787
{
8888
}
8989
else if(
90-
!alloc_size.has_value() && tmp_size.id() == ID_mult &&
91-
tmp_size.operands().size() == 2 &&
92-
(tmp_size.op0().is_constant() || tmp_size.op1().is_constant()))
90+
!alloc_size.has_value() && tmp_size.expr.id() == ID_mult &&
91+
tmp_size.expr.operands().size() == 2 &&
92+
(tmp_size.expr.op0().is_constant() ||
93+
tmp_size.expr.op1().is_constant()))
9394
{
94-
exprt s=tmp_size.op0();
95+
exprt s = tmp_size.expr.op0();
9596
if(s.is_constant())
9697
{
97-
s=tmp_size.op1();
98-
PRECONDITION(*c_sizeof_type_rec(tmp_size.op0()) == *tmp_type);
98+
s = tmp_size.expr.op1();
99+
PRECONDITION(*c_sizeof_type_rec(tmp_size.expr.op0()) == *tmp_type);
99100
}
100101
else
101-
PRECONDITION(*c_sizeof_type_rec(tmp_size.op1()) == *tmp_type);
102+
PRECONDITION(*c_sizeof_type_rec(tmp_size.expr.op1()) == *tmp_type);
102103

103104
object_type = array_typet(*tmp_type, s);
104105
}
@@ -111,15 +112,15 @@ void goto_symext::symex_allocate(
111112
mp_integer elements = *alloc_size / (*elem_size);
112113

113114
if(elements * (*elem_size) == *alloc_size)
114-
object_type =
115-
array_typet(*tmp_type, from_integer(elements, tmp_size.type()));
115+
object_type = array_typet(
116+
*tmp_type, from_integer(elements, tmp_size.expr.type()));
116117
}
117118
}
118119
}
119120
}
120121

121122
if(!object_type.has_value())
122-
object_type=array_typet(unsigned_char_type(), tmp_size);
123+
object_type = array_typet(unsigned_char_type(), tmp_size.expr);
123124

124125
// we introduce a fresh symbol for the size
125126
// to prevent any issues of the size getting ever changed
@@ -135,7 +136,7 @@ void goto_symext::symex_allocate(
135136
size_symbol.base_name=
136137
"dynamic_object_size"+std::to_string(dynamic_counter);
137138
size_symbol.name="symex_dynamic::"+id2string(size_symbol.base_name);
138-
size_symbol.type=tmp_size.type();
139+
size_symbol.type = tmp_size.expr.type();
139140
size_symbol.mode = mode;
140141
size_symbol.type.set(ID_C_constant, true);
141142
size_symbol.value = array_size;
@@ -161,14 +162,15 @@ void goto_symext::symex_allocate(
161162

162163
state.symbol_table.add(value_symbol);
163164

164-
exprt zero_init=code.op1();
165-
state.rename_level2(zero_init, ns); // to allow constant propagation
166-
simplify(zero_init, ns);
165+
// to allow constant propagation
166+
level2t<exprt> zero_init = state.rename_level2(code.op1(), ns);
167+
simplify(zero_init.expr, ns);
167168

168169
INVARIANT(
169-
zero_init.is_constant(), "allocate expects constant as second argument");
170+
zero_init.expr.is_constant(),
171+
"allocate expects constant as second argument");
170172

171-
if(!zero_init.is_zero() && !zero_init.is_false())
173+
if(!zero_init.expr.is_zero() && !zero_init.expr.is_false())
172174
{
173175
const auto zero_value =
174176
zero_initializer(*object_type, code.source_location(), ns);
@@ -231,10 +233,10 @@ void goto_symext::symex_gcc_builtin_va_arg_next(
231233
if(lhs.is_nil())
232234
return; // ignore
233235

234-
exprt tmp=code.op0();
235-
state.rename_level2(tmp, ns); // to allow constant propagation
236-
do_simplify(tmp);
237-
irep_idt id=get_symbol(tmp);
236+
// to allow constant propagation
237+
level2t<exprt> tmp = state.rename_level2(code.op0(), ns);
238+
do_simplify(tmp.expr);
239+
irep_idt id = get_symbol(tmp.expr);
238240

239241
const auto zero = zero_initializer(lhs.type(), code.source_location(), ns);
240242
CHECK_RETURN(zero.has_value());
@@ -309,11 +311,10 @@ void goto_symext::symex_printf(
309311
{
310312
PRECONDITION(!rhs.operands().empty());
311313

312-
exprt tmp_rhs=rhs;
313-
state.rename_level2(tmp_rhs, ns);
314-
do_simplify(tmp_rhs);
314+
level2t<exprt> tmp_rhs = state.rename_level2(rhs, ns);
315+
do_simplify(tmp_rhs.expr);
315316

316-
const exprt::operandst &operands=tmp_rhs.operands();
317+
const exprt::operandst &operands = tmp_rhs.expr.operands();
317318
std::list<exprt> args;
318319

319320
for(std::size_t i=1; i<operands.size(); i++)
@@ -334,20 +335,19 @@ void goto_symext::symex_input(
334335
{
335336
PRECONDITION(code.operands().size() >= 2);
336337

337-
exprt id_arg=code.op0();
338-
339-
state.rename_level2(id_arg, ns);
338+
level2t<exprt> id_arg = state.rename_level2(code.op0(), ns);
340339

341340
std::list<exprt> args;
342341

343342
for(std::size_t i=1; i<code.operands().size(); i++)
344343
{
345344
args.push_back(code.operands()[i]);
346-
state.rename_level2(args.back(), ns);
347-
do_simplify(args.back());
345+
level2t<exprt> l2_arg = state.rename_level2(args.back(), ns);
346+
do_simplify(l2_arg.expr);
347+
args.back() = std::move(l2_arg.expr);
348348
}
349349

350-
const irep_idt input_id=get_string_argument(id_arg, ns);
350+
const irep_idt input_id = get_string_argument(id_arg.expr, ns);
351351

352352
target.input(state.guard.as_expr(), state.source, input_id, args);
353353
}
@@ -357,21 +357,19 @@ void goto_symext::symex_output(
357357
const codet &code)
358358
{
359359
PRECONDITION(code.operands().size() >= 2);
360-
361-
exprt id_arg=code.op0();
362-
363-
state.rename_level2(id_arg, ns);
360+
level2t<exprt> id_arg = state.rename_level2(code.op0(), ns);
364361

365362
std::list<exprt> args;
366363

367364
for(std::size_t i=1; i<code.operands().size(); i++)
368365
{
369366
args.push_back(code.operands()[i]);
370-
state.rename_level2(args.back(), ns);
371-
do_simplify(args.back());
367+
level2t<exprt> l2_arg = state.rename_level2(args.back(), ns);
368+
do_simplify(l2_arg.expr);
369+
args.back() = std::move(l2_arg.expr);
372370
}
373371

374-
const irep_idt output_id=get_string_argument(id_arg, ns);
372+
const irep_idt output_id = get_string_argument(id_arg.expr, ns);
375373

376374
target.output(state.guard.as_expr(), state.source, output_id, args);
377375
}
@@ -480,9 +478,8 @@ void goto_symext::symex_trace(
480478

481479
for(std::size_t j=2; j<code.arguments().size(); j++)
482480
{
483-
exprt var(code.arguments()[j]);
484-
state.rename_level2(var, ns);
485-
vars.push_back(var);
481+
level2t<exprt> var = state.rename_level2(code.arguments()[j], ns);
482+
vars.push_back(var.expr);
486483
}
487484

488485
target.output(state.guard.as_expr(), state.source, event, vars);

0 commit comments

Comments
 (0)