11
11
12
12
#include " goto_symex.h"
13
13
14
- #include < util/find_symbols.h>
15
14
#include < util/std_expr.h>
16
15
17
16
void goto_symext::symex_dead (statet &state)
@@ -20,23 +19,27 @@ void goto_symext::symex_dead(statet &state)
20
19
symex_dead (state, instruction.dead_symbol ());
21
20
}
22
21
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)
24
26
{
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))
34
28
{
29
+ const ssa_exprt &l1_ssa = to_ssa_expr (l1_expr);
30
+ const irep_idt &l1_identifier = l1_ssa.get_identifier ();
31
+
35
32
// We cannot remove the object from the L1 renaming map, because L1 renaming
36
33
// information is not local to a path, but removing it from the propagation
37
34
// 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
+ }
40
43
state.propagation .erase_if_exists (l1_identifier);
41
44
// Remove from the local L2 renaming map; this means any reads from the dead
42
45
// 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)
45
48
// identifier is still live.
46
49
state.drop_l1_name (l1_identifier);
47
50
}
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);
48
68
}
0 commit comments