Skip to content

Commit a1deabe

Browse files
committed
Symex: shortcut the common case of whole-struct initialisation
Rather than assign a temporary symbol and then expand it, directly extract the fields and assign them. This cuts the time taken on one initialisation-heavy benchmark from 3.6s to 3.2s.
1 parent 626ec18 commit a1deabe

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

jbmc/regression/jbmc-generics/constant_propagation/test.desc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ Test.class
33
--function Test.main --show-vcc
44
^EXIT=0$
55
^SIGNAL=0$
6-
^\{-\d+\} symex_dynamic::dynamic_object1#2 = \{ \{ \{ "java::GenericSub" \}, NULL, 0 \} \}$
76
^\{-\d+\} symex_dynamic::dynamic_object1#2\.\.@Generic\.\[email protected]\.\.@class_identifier = "java::GenericSub"$
87
^\{-\d+\} symex_dynamic::dynamic_object1#2\.\.@Generic\.\.key = NULL$
98
^\{-\d+\} symex_dynamic::dynamic_object1#3\.\.@Generic\.\.x = 5$

src/goto-symex/goto_symex.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,13 @@ class goto_symext
499499
const exprt &rhs,
500500
exprt::operandst &,
501501
assignment_typet);
502+
void symex_assign_from_struct(
503+
statet &,
504+
const ssa_exprt &lhs,
505+
const exprt &full_lhs,
506+
const struct_exprt &rhs,
507+
exprt::operandst &,
508+
assignment_typet);
502509
void symex_assign_symbol(
503510
statet &,
504511
const ssa_exprt &lhs,

src/goto-symex/symex_assign.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,51 @@ static void shift_indexed_access_to_lhs(
364364
}
365365
}
366366

367+
/// Assign a struct expression to a symbol. If \ref symex_assign_symbol was used
368+
/// then we would assign the whole symbol, before extracting its components,
369+
/// with results like `x = {1, 2}; x..field1 = x.field1; x..field2 = x.field2;`
370+
/// This abbreviates the process, directly producing
371+
/// `x..field1 = 1; x..field2 = 2;`
372+
/// \param state: goto-symex state
373+
/// \param lhs: symbol to assign (already renamed to L1)
374+
/// \param full_lhs: expression skeleton corresponding to \p lhs, to be included
375+
/// in the result trace
376+
/// \param rhs: struct expression to assign to \p lhs
377+
/// \param guard: guard conjuncts that must hold for this assignment to be made
378+
/// \param assignment_type: assignment type (see
379+
/// \ref symex_targett::assignment_typet)
380+
void goto_symext::symex_assign_from_struct(
381+
statet &state,
382+
const ssa_exprt &lhs, // L1
383+
const exprt &full_lhs,
384+
const struct_exprt &rhs,
385+
exprt::operandst &guard,
386+
assignment_typet assignment_type)
387+
{
388+
const struct_typet &type = to_struct_type(ns.follow(lhs.type()));
389+
const struct_union_typet::componentst &components = type.components();
390+
PRECONDITION(rhs.operands().size() == components.size());
391+
392+
for(std::size_t i = 0; i < components.size(); ++i)
393+
{
394+
const auto &comp = components[i];
395+
exprt lhs_field = member_exprt(lhs, comp.get_name(), comp.type());
396+
state.field_sensitivity.apply(ns, state, lhs_field, true);
397+
INVARIANT(
398+
lhs_field.id() == ID_symbol,
399+
"member of symbol should be susceptible to field-sensitivity");
400+
401+
const exprt &rhs_field = rhs.operands()[i];
402+
symex_assign_symbol(
403+
state,
404+
to_ssa_expr(lhs_field),
405+
full_lhs,
406+
rhs_field,
407+
guard,
408+
assignment_type);
409+
}
410+
}
411+
367412
void goto_symext::symex_assign_symbol(
368413
statet &state,
369414
const ssa_exprt &lhs, // L1
@@ -372,6 +417,14 @@ void goto_symext::symex_assign_symbol(
372417
exprt::operandst &guard,
373418
assignment_typet assignment_type)
374419
{
420+
// Shortcut the common case of a whole-struct initializer:
421+
if(rhs.id() == ID_struct)
422+
{
423+
symex_assign_from_struct(
424+
state, lhs, full_lhs, to_struct_expr(rhs), guard, assignment_type);
425+
return;
426+
}
427+
375428
exprt ssa_rhs=rhs;
376429

377430
// put assignment guard into the rhs

0 commit comments

Comments
 (0)