@@ -11,7 +11,6 @@ Author: Daniel Kroening, kroening@kroening.com
1111
1212#include " goto_symex.h"
1313
14- #include < util/find_symbols.h>
1514#include < util/std_expr.h>
1615
1716void goto_symext::symex_dead (statet &state)
@@ -20,23 +19,27 @@ void goto_symext::symex_dead(statet &state)
2019 symex_dead (state, instruction.dead_symbol ());
2120}
2221
23- void goto_symext::symex_dead (statet &state, const symbol_exprt &symbol_expr)
22+ static void remove_l1_object_rec (
23+ goto_symext::statet &state,
24+ const exprt &l1_expr,
25+ const namespacet &ns)
2426{
25- ssa_exprt to_rename = is_ssa_expr (symbol_expr) ? to_ssa_expr (symbol_expr)
26- : ssa_exprt{symbol_expr};
27- ssa_exprt ssa = state.rename_ssa <L1>(to_rename, ns).get ();
28-
29- const exprt fields = state.field_sensitivity .get_fields (ns, state, ssa);
30- find_symbols_sett fields_set;
31- find_symbols_or_nexts (fields, fields_set);
32-
33- for (const irep_idt &l1_identifier : fields_set)
27+ if (is_ssa_expr (l1_expr))
3428 {
29+ const ssa_exprt &l1_ssa = to_ssa_expr (l1_expr);
30+ const irep_idt &l1_identifier = l1_ssa.get_identifier ();
31+
3532 // We cannot remove the object from the L1 renaming map, because L1 renaming
3633 // information is not local to a path, but removing it from the propagation
3734 // map and value-set is safe as 1) it is local to a path and 2) this
38- // instance can no longer appear.
39- state.value_set .values .erase_if_exists (l1_identifier);
35+ // instance can no longer appear (unless shared across threads).
36+ if (
37+ state.threads .size () <= 1 ||
38+ state.write_is_shared (l1_ssa, ns) ==
39+ goto_symex_statet::write_is_shared_resultt::NOT_SHARED)
40+ {
41+ state.value_set .values .erase_if_exists (l1_identifier);
42+ }
4043 state.propagation .erase_if_exists (l1_identifier);
4144 // Remove from the local L2 renaming map; this means any reads from the dead
4245 // identifier will use generation 0 (e.g. x!N@M#0, where N and M are
@@ -45,4 +48,21 @@ void goto_symext::symex_dead(statet &state, const symbol_exprt &symbol_expr)
4548 // identifier is still live.
4649 state.drop_l1_name (l1_identifier);
4750 }
51+ else if (l1_expr.id () == ID_array || l1_expr.id () == ID_struct)
52+ {
53+ for (const auto &op : l1_expr.operands ())
54+ remove_l1_object_rec (state, op, ns);
55+ }
56+ else
57+ UNREACHABLE;
58+ }
59+
60+ void goto_symext::symex_dead (statet &state, const symbol_exprt &symbol_expr)
61+ {
62+ ssa_exprt to_rename = is_ssa_expr (symbol_expr) ? to_ssa_expr (symbol_expr)
63+ : ssa_exprt{symbol_expr};
64+ ssa_exprt ssa = state.rename_ssa <L1>(to_rename, ns).get ();
65+
66+ const exprt fields = state.field_sensitivity .get_fields (ns, state, ssa);
67+ remove_l1_object_rec (state, fields, ns);
4868}
0 commit comments