Skip to content

Commit a1c6c4d

Browse files
Make rename_level2 return a level2t
1 parent ffaf2db commit a1c6c4d

13 files changed

+141
-105
lines changed

src/goto-instrument/accelerate/scratch_program.cpp

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

6363
exprt scratch_programt::eval(const exprt &e)
6464
{
65-
exprt ssa=e;
65+
return checker->get(symex_state.rename_level2(e, ns).expr);
6666

67-
symex_state.rename_level2(ssa, ns);
68-
69-
return checker->get(ssa);
7067
}
7168

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

src/goto-symex/goto_symex_state.cpp

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,38 @@ level1t<exprt> goto_symex_statet::rename_level1(
414414
}
415415
}
416416

417-
void goto_symex_statet::rename_level2(
418-
exprt &expr,
417+
level2t<ssa_exprt> goto_symex_statet::rename_level2(
418+
ssa_exprt ssa,
419+
const namespacet &ns)
420+
{
421+
set_l1_indices(level0, level1, ssa, source.thread_nr, ns);
422+
rename(ssa.type(), ssa.get_identifier(), ns);
423+
ssa.update_type();
424+
425+
if(l2_thread_read_encoding(ssa, ns))
426+
{
427+
// renaming taken care of by l2_thread_encoding
428+
}
429+
else if(!ssa.get_level_2().empty())
430+
{
431+
// already at L2
432+
}
433+
else
434+
{
435+
// We also consider propagation if we go up to L2.
436+
// L1 identifiers are used for propagation!
437+
auto p_it = propagation.find(ssa.get_identifier());
438+
439+
if(p_it != propagation.end())
440+
ssa = to_ssa_expr(p_it->second); // already L2
441+
else
442+
set_l2_indices(level0, level1, level2, ssa, source.thread_nr, ns);
443+
}
444+
return level2t<ssa_exprt>{ssa};
445+
}
446+
447+
level2t<exprt> goto_symex_statet::rename_level2(
448+
exprt expr,
419449
const namespacet &ns)
420450
{
421451
// rename all the symbols with their last known value
@@ -457,12 +487,12 @@ void goto_symex_statet::rename_level2(
457487
to_symbol_expr(expr).get_identifier(),
458488
ns,
459489
L2);
460-
461-
return;
462490
}
463-
464-
expr=ssa_exprt(expr);
465-
rename_level2(expr, ns);
491+
else
492+
{
493+
expr=ssa_exprt(expr);
494+
return rename_level2(expr, ns);
495+
}
466496
}
467497
else if(expr.id()==ID_address_of)
468498
{
@@ -476,10 +506,12 @@ void goto_symex_statet::rename_level2(
476506
rename(expr.type(), irep_idt(), ns, L2);
477507

478508
// do this recursively
479-
Forall_operands(it, expr)rename_level2(*it, ns);
509+
Forall_operands(it, expr)
510+
*it = rename_level2(std::move(*it), ns).expr;
480511

481512
fix_type(expr);
482513
}
514+
return level2t<exprt>{expr};
483515
}
484516

485517
/// thread encoding
@@ -770,7 +802,7 @@ void goto_symex_statet::rename(
770802
if(level == L1)
771803
e = rename_level1(e, ns).expr;
772804
else
773-
rename_level2(e, ns);
805+
e = rename_level2(e, ns).expr;
774806
};
775807

776808
// 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
@@ -76,7 +76,8 @@ class goto_symex_statet final
7676
level1t<ssa_exprt> rename_level1_ssa(ssa_exprt expr, const namespacet &ns);
7777
level1t<exprt> rename_level1(exprt expr, const namespacet &ns);
7878
level1t<ssa_exprt> rename_level1(level0t<ssa_exprt> l0_expr, const namespacet &ns);
79-
void rename_level2(exprt &expr, const namespacet &ns);
79+
level2t<exprt> rename_level2(exprt expr, const namespacet &ns);
80+
level2t<ssa_exprt> rename_level2(ssa_exprt ssa, const namespacet &ns);
8081
void rename(
8182
typet &type,
8283
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: 39 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -69,36 +69,36 @@ 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() || tmp_size.expr.op1().is_constant()))
9393
{
94-
exprt s=tmp_size.op0();
94+
exprt s=tmp_size.expr.op0();
9595
if(s.is_constant())
9696
{
97-
s=tmp_size.op1();
98-
PRECONDITION(*c_sizeof_type_rec(tmp_size.op0()) == *tmp_type);
97+
s=tmp_size.expr.op1();
98+
PRECONDITION(*c_sizeof_type_rec(tmp_size.expr.op0()) == *tmp_type);
9999
}
100100
else
101-
PRECONDITION(*c_sizeof_type_rec(tmp_size.op1()) == *tmp_type);
101+
PRECONDITION(*c_sizeof_type_rec(tmp_size.expr.op1()) == *tmp_type);
102102

103103
object_type = array_typet(*tmp_type, s);
104104
}
@@ -112,14 +112,14 @@ void goto_symext::symex_allocate(
112112

113113
if(elements * (*elem_size) == *alloc_size)
114114
object_type =
115-
array_typet(*tmp_type, from_integer(elements, tmp_size.type()));
115+
array_typet(*tmp_type, from_integer(elements, tmp_size.expr.type()));
116116
}
117117
}
118118
}
119119
}
120120

121121
if(!object_type.has_value())
122-
object_type=array_typet(unsigned_char_type(), tmp_size);
122+
object_type=array_typet(unsigned_char_type(), tmp_size.expr);
123123

124124
// we introduce a fresh symbol for the size
125125
// to prevent any issues of the size getting ever changed
@@ -135,7 +135,7 @@ void goto_symext::symex_allocate(
135135
size_symbol.base_name=
136136
"dynamic_object_size"+std::to_string(dynamic_counter);
137137
size_symbol.name="symex_dynamic::"+id2string(size_symbol.base_name);
138-
size_symbol.type=tmp_size.type();
138+
size_symbol.type=tmp_size.expr.type();
139139
size_symbol.mode = mode;
140140
size_symbol.type.set(ID_C_constant, true);
141141
size_symbol.value = array_size;
@@ -161,14 +161,14 @@ void goto_symext::symex_allocate(
161161

162162
state.symbol_table.add(value_symbol);
163163

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

168168
INVARIANT(
169-
zero_init.is_constant(), "allocate expects constant as second argument");
169+
zero_init.expr.is_constant(), "allocate expects constant as second argument");
170170

171-
if(!zero_init.is_zero() && !zero_init.is_false())
171+
if(!zero_init.expr.is_zero() && !zero_init.expr.is_false())
172172
{
173173
const auto zero_value =
174174
zero_initializer(*object_type, code.source_location(), ns);
@@ -231,10 +231,10 @@ void goto_symext::symex_gcc_builtin_va_arg_next(
231231
if(lhs.is_nil())
232232
return; // ignore
233233

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);
234+
// to allow constant propagation
235+
level2t<exprt> tmp = state.rename_level2(code.op0(), ns);
236+
do_simplify(tmp.expr);
237+
irep_idt id=get_symbol(tmp.expr);
238238

239239
const auto zero = zero_initializer(lhs.type(), code.source_location(), ns);
240240
CHECK_RETURN(zero.has_value());
@@ -309,11 +309,10 @@ void goto_symext::symex_printf(
309309
{
310310
PRECONDITION(!rhs.operands().empty());
311311

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

316-
const exprt::operandst &operands=tmp_rhs.operands();
315+
const exprt::operandst &operands=tmp_rhs.expr.operands();
317316
std::list<exprt> args;
318317

319318
for(std::size_t i=1; i<operands.size(); i++)
@@ -334,20 +333,19 @@ void goto_symext::symex_input(
334333
{
335334
PRECONDITION(code.operands().size() >= 2);
336335

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

341338
std::list<exprt> args;
342339

343340
for(std::size_t i=1; i<code.operands().size(); i++)
344341
{
345342
args.push_back(code.operands()[i]);
346-
state.rename_level2(args.back(), ns);
347-
do_simplify(args.back());
343+
level2t<exprt> l2_arg = state.rename_level2(args.back(), ns);
344+
do_simplify(l2_arg.expr);
345+
args.back() = std::move(l2_arg.expr);
348346
}
349347

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

352350
target.input(state.guard.as_expr(), state.source, input_id, args);
353351
}
@@ -357,21 +355,19 @@ void goto_symext::symex_output(
357355
const codet &code)
358356
{
359357
PRECONDITION(code.operands().size() >= 2);
360-
361-
exprt id_arg=code.op0();
362-
363-
state.rename_level2(id_arg, ns);
358+
level2t<exprt> id_arg = state.rename_level2(code.op0(), ns);
364359

365360
std::list<exprt> args;
366361

367362
for(std::size_t i=1; i<code.operands().size(); i++)
368363
{
369364
args.push_back(code.operands()[i]);
370-
state.rename_level2(args.back(), ns);
371-
do_simplify(args.back());
365+
level2t<exprt> l2_arg = state.rename_level2(args.back(), ns);
366+
do_simplify(l2_arg.expr);
367+
args.back() = std::move(l2_arg.expr);
372368
}
373369

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

376372
target.output(state.guard.as_expr(), state.source, output_id, args);
377373
}
@@ -480,9 +476,8 @@ void goto_symext::symex_trace(
480476

481477
for(std::size_t j=2; j<code.arguments().size(); j++)
482478
{
483-
exprt var(code.arguments()[j]);
484-
state.rename_level2(var, ns);
485-
vars.push_back(var);
479+
level2t<exprt> var = state.rename_level2(code.arguments()[j], ns);
480+
vars.push_back(var.expr);
486481
}
487482

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

0 commit comments

Comments
 (0)