Skip to content

Commit dc4611f

Browse files
authored
Merge pull request diffblue#3996 from romainbrenguier/refactor/symex-rename-copy
Split the rename function according to the level and pass expression by copy instead of reference
2 parents d285eb8 + 7da918f commit dc4611f

13 files changed

+141
-140
lines changed

src/goto-instrument/accelerate/scratch_program.cpp

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

7070
exprt scratch_programt::eval(const exprt &e)
7171
{
72-
exprt ssa=e;
73-
74-
symex_state->rename(ssa, ns);
75-
76-
return checker->get(ssa);
72+
return checker->get(symex_state->rename<goto_symex_statet::L2>(e, ns));
7773
}
7874

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

src/goto-symex/goto_symex_state.cpp

Lines changed: 60 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,11 @@ void goto_symex_statet::assignment(
163163
bool allow_pointer_unsoundness)
164164
{
165165
// identifier should be l0 or l1, make sure it's l1
166-
rename(lhs, ns, L1);
166+
lhs = rename_ssa<L1>(std::move(lhs), ns);
167167
irep_idt l1_identifier=lhs.get_identifier();
168168

169169
// the type might need renaming
170-
rename(lhs.type(), l1_identifier, ns);
170+
rename<L2>(lhs.type(), l1_identifier, ns);
171171
lhs.update_type();
172172
if(run_validation_checks)
173173
{
@@ -263,10 +263,31 @@ void goto_symex_statet::set_l2_indices(
263263
ssa_expr.set_level_2(level2.current_count(ssa_expr.get_identifier()));
264264
}
265265

266-
void goto_symex_statet::rename(
267-
exprt &expr,
268-
const namespacet &ns,
269-
levelt level)
266+
template <goto_symex_statet::levelt level>
267+
ssa_exprt goto_symex_statet::rename_ssa(ssa_exprt ssa, const namespacet &ns)
268+
{
269+
static_assert(
270+
level == L0 || level == L1,
271+
"rename_ssa can only be used for levels L0 and L1");
272+
if(level == L0)
273+
set_l0_indices(ssa, ns);
274+
else if(level == L1)
275+
set_l1_indices(ssa, ns);
276+
else
277+
UNREACHABLE;
278+
279+
rename<level>(ssa.type(), ssa.get_identifier(), ns);
280+
ssa.update_type();
281+
return ssa;
282+
}
283+
284+
/// 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+
289+
template <goto_symex_statet::levelt level>
290+
exprt goto_symex_statet::rename(exprt expr, const namespacet &ns)
270291
{
271292
// rename all the symbols with their last known value
272293

@@ -277,20 +298,16 @@ void goto_symex_statet::rename(
277298

278299
if(level == L0)
279300
{
280-
set_l0_indices(ssa, ns);
281-
rename(expr.type(), ssa.get_identifier(), ns, level);
282-
ssa.update_type();
301+
ssa = rename_ssa<L0>(std::move(ssa), ns);
283302
}
284303
else if(level == L1)
285304
{
286-
set_l1_indices(ssa, ns);
287-
rename(expr.type(), ssa.get_identifier(), ns, level);
288-
ssa.update_type();
305+
ssa = rename_ssa<L1>(std::move(ssa), ns);
289306
}
290307
else if(level==L2)
291308
{
292309
set_l1_indices(ssa, ns);
293-
rename(expr.type(), ssa.get_identifier(), ns, level);
310+
rename<level>(expr.type(), ssa.get_identifier(), ns);
294311
ssa.update_type();
295312

296313
if(l2_thread_read_encoding(ssa, ns))
@@ -318,33 +335,24 @@ void goto_symex_statet::rename(
318335
{
319336
// we never rename function symbols
320337
if(as_const(expr).type().id() == ID_code)
321-
{
322-
rename(
323-
expr.type(),
324-
to_symbol_expr(expr).get_identifier(),
325-
ns,
326-
level);
327-
328-
return;
329-
}
330-
331-
expr=ssa_exprt(expr);
332-
rename(expr, ns, level);
338+
rename<level>(expr.type(), to_symbol_expr(expr).get_identifier(), ns);
339+
else
340+
expr = rename<level>(ssa_exprt{expr}, ns);
333341
}
334342
else if(expr.id()==ID_address_of)
335343
{
336344
auto &address_of_expr = to_address_of_expr(expr);
337-
rename_address(address_of_expr.object(), ns, level);
345+
rename_address<level>(address_of_expr.object(), ns);
338346
to_pointer_type(expr.type()).subtype() =
339347
as_const(address_of_expr).object().type();
340348
}
341349
else
342350
{
343-
rename(expr.type(), irep_idt(), ns, level);
351+
rename<level>(expr.type(), irep_idt(), ns);
344352

345353
// do this recursively
346354
Forall_operands(it, expr)
347-
rename(*it, ns, level);
355+
*it = rename<level>(std::move(*it), ns);
348356

349357
const exprt &c_expr = as_const(expr);
350358
INVARIANT(
@@ -356,6 +364,7 @@ void goto_symex_statet::rename(
356364
"Type of renamed expr should be the same as operands for with_exprt and "
357365
"if_exprt");
358366
}
367+
return expr;
359368
}
360369

361370
/// thread encoding
@@ -535,10 +544,8 @@ bool goto_symex_statet::l2_thread_write_encoding(
535544
return threads.size()>1;
536545
}
537546

538-
void goto_symex_statet::rename_address(
539-
exprt &expr,
540-
const namespacet &ns,
541-
levelt level)
547+
template <goto_symex_statet::levelt level>
548+
void goto_symex_statet::rename_address(exprt &expr, const namespacet &ns)
542549
{
543550
if(expr.id()==ID_symbol &&
544551
expr.get_bool(ID_C_SSA_symbol))
@@ -548,42 +555,42 @@ void goto_symex_statet::rename_address(
548555
// only do L1!
549556
set_l1_indices(ssa, ns);
550557

551-
rename(expr.type(), ssa.get_identifier(), ns, level);
558+
rename<level>(expr.type(), ssa.get_identifier(), ns);
552559
ssa.update_type();
553560
}
554561
else if(expr.id()==ID_symbol)
555562
{
556563
expr=ssa_exprt(expr);
557-
rename_address(expr, ns, level);
564+
rename_address<level>(expr, ns);
558565
}
559566
else
560567
{
561568
if(expr.id()==ID_index)
562569
{
563570
index_exprt &index_expr=to_index_expr(expr);
564571

565-
rename_address(index_expr.array(), ns, level);
572+
rename_address<level>(index_expr.array(), ns);
566573
PRECONDITION(index_expr.array().type().id() == ID_array);
567574
expr.type() = to_array_type(index_expr.array().type()).subtype();
568575

569576
// the index is not an address
570-
rename(index_expr.index(), ns, level);
577+
index_expr.index() = rename<level>(std::move(index_expr.index()), ns);
571578
}
572579
else if(expr.id()==ID_if)
573580
{
574581
// the condition is not an address
575582
if_exprt &if_expr=to_if_expr(expr);
576-
rename(if_expr.cond(), ns, level);
577-
rename_address(if_expr.true_case(), ns, level);
578-
rename_address(if_expr.false_case(), ns, level);
583+
if_expr.cond() = rename<level>(std::move(if_expr.cond()), ns);
584+
rename_address<level>(if_expr.true_case(), ns);
585+
rename_address<level>(if_expr.false_case(), ns);
579586

580587
if_expr.type()=if_expr.true_case().type();
581588
}
582589
else if(expr.id()==ID_member)
583590
{
584591
member_exprt &member_expr=to_member_expr(expr);
585592

586-
rename_address(member_expr.struct_op(), ns, level);
593+
rename_address<level>(member_expr.struct_op(), ns);
587594

588595
// type might not have been renamed in case of nesting of
589596
// structs and pointers/arrays
@@ -600,17 +607,17 @@ void goto_symex_statet::rename_address(
600607
expr.type()=comp.type();
601608
}
602609
else
603-
rename(expr.type(), irep_idt(), ns, level);
610+
rename<level>(expr.type(), irep_idt(), ns);
604611
}
605612
else
606613
{
607614
// this could go wrong, but we would have to re-typecheck ...
608-
rename(expr.type(), irep_idt(), ns, level);
615+
rename<level>(expr.type(), irep_idt(), ns);
609616

610617
// do this recursively; we assume here
611618
// that all the operands are addresses
612619
Forall_operands(it, expr)
613-
rename_address(*it, ns, level);
620+
rename_address<level>(*it, ns);
614621
}
615622
}
616623
}
@@ -668,11 +675,11 @@ static bool requires_renaming(const typet &type, const namespacet &ns)
668675
return false;
669676
}
670677

678+
template <goto_symex_statet::levelt level>
671679
void goto_symex_statet::rename(
672680
typet &type,
673681
const irep_idt &l1_identifier,
674-
const namespacet &ns,
675-
levelt level)
682+
const namespacet &ns)
676683
{
677684
// check whether there are symbol expressions in the type; if not, there
678685
// is no need to expand the struct/union tags in the type
@@ -711,8 +718,8 @@ void goto_symex_statet::rename(
711718
if(type.id()==ID_array)
712719
{
713720
auto &array_type = to_array_type(type);
714-
rename(array_type.subtype(), irep_idt(), ns, level);
715-
rename(array_type.size(), ns, level);
721+
rename<level>(array_type.subtype(), irep_idt(), ns);
722+
array_type.size() = rename<level>(std::move(array_type.size()), ns);
716723
}
717724
else if(type.id() == ID_struct || type.id() == ID_union)
718725
{
@@ -723,14 +730,17 @@ void goto_symex_statet::rename(
723730
{
724731
// be careful, or it might get cyclic
725732
if(component.type().id() == ID_array)
726-
rename(to_array_type(component.type()).size(), ns, level);
733+
{
734+
auto &array_type = to_array_type(component.type());
735+
array_type.size() = rename<level>(std::move(array_type.size()), ns);
736+
}
727737
else if(component.type().id() != ID_pointer)
728-
rename(component.type(), irep_idt(), ns, level);
738+
rename<level>(component.type(), irep_idt(), ns);
729739
}
730740
}
731741
else if(type.id()==ID_pointer)
732742
{
733-
rename(to_pointer_type(type).subtype(), irep_idt(), ns, level);
743+
rename<level>(to_pointer_type(type).subtype(), irep_idt(), ns);
734744
}
735745

736746
if(level==L2 &&

src/goto-symex/goto_symex_state.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,16 @@ class goto_symex_statet final : public goto_statet
179179
///
180180
/// A full explanation of SSA (which is why we do this renaming) is in
181181
/// the SSA section of background-concepts.md.
182-
void rename(exprt &expr, const namespacet &ns, levelt level=L2);
183-
void rename(
184-
typet &type,
185-
const irep_idt &l1_identifier,
186-
const namespacet &ns,
187-
levelt level=L2);
182+
template <levelt level = L2>
183+
exprt rename(exprt expr, const namespacet &ns);
184+
185+
/// Version of rename which is specialized for SSA exprt.
186+
/// Implementation only exists for level L0 and L1.
187+
template <levelt level>
188+
ssa_exprt rename_ssa(ssa_exprt ssa, const namespacet &ns);
189+
190+
template <levelt level = L2>
191+
void rename(typet &type, const irep_idt &l1_identifier, const namespacet &ns);
188192

189193
void assignment(
190194
ssa_exprt &lhs, // L0/L1
@@ -195,7 +199,8 @@ class goto_symex_statet final : public goto_statet
195199
bool allow_pointer_unsoundness=false);
196200

197201
protected:
198-
void rename_address(exprt &expr, const namespacet &ns, levelt level);
202+
template <levelt>
203+
void rename_address(exprt &expr, const namespacet &ns);
199204

200205
/// Update level 0 values.
201206
void set_l0_indices(ssa_exprt &expr, const namespacet &ns);

src/goto-symex/symex_assign.cpp

Lines changed: 8 additions & 8 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(ssa_rhs, ns);
216-
do_simplify(ssa_rhs);
215+
exprt l2_rhs = state.rename(std::move(ssa_rhs), ns);
216+
do_simplify(l2_rhs);
217217

218218
ssa_exprt ssa_lhs=lhs;
219219
state.assignment(
220220
ssa_lhs,
221-
ssa_rhs,
221+
l2_rhs,
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(ssa_full_lhs, ns);
231+
exprt l2_full_lhs = state.rename(std::move(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,
258+
add_to_lhs(full_lhs, ssa_lhs.get_original_expr()),
259+
l2_rhs,
259260
state.source,
260261
assignment_type);
261262
}
@@ -406,8 +407,7 @@ void goto_symext::symex_assign_if(
406407

407408
guardt old_guard=guard;
408409

409-
exprt renamed_guard=lhs.cond();
410-
state.rename(renamed_guard, ns);
410+
exprt renamed_guard = state.rename(lhs.cond(), ns);
411411
do_simplify(renamed_guard);
412412

413413
if(!renamed_guard.is_false())

0 commit comments

Comments
 (0)