@@ -13,29 +13,26 @@ Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk
13
13
14
14
#include < util/std_expr.h>
15
15
16
- memory_model_baset::memory_model_baset (const namespacet &_ns):
17
- partial_order_concurrencyt(_ns),
18
- var_cnt(0 )
16
+ memory_model_baset::memory_model_baset (const namespacet &_ns)
17
+ : partial_order_concurrencyt(_ns), var_cnt(0 )
19
18
{
20
19
}
21
20
22
21
memory_model_baset::~memory_model_baset ()
23
22
{
24
23
}
25
24
26
- symbol_exprt memory_model_baset::nondet_bool_symbol (
27
- const std::string &prefix)
25
+ symbol_exprt memory_model_baset::nondet_bool_symbol (const std::string &prefix)
28
26
{
29
27
return symbol_exprt (
30
- " memory_model::choice_" +prefix+std::to_string (var_cnt++),
31
- bool_typet ());
28
+ " memory_model::choice_" + prefix + std::to_string (var_cnt++), bool_typet ());
32
29
}
33
30
34
31
bool memory_model_baset::po (event_it e1 , event_it e2 )
35
32
{
36
33
// within same thread
37
- if (e1 ->source .thread_nr == e2 ->source .thread_nr )
38
- return numbering[e1 ]< numbering[e2 ];
34
+ if (e1 ->source .thread_nr == e2 ->source .thread_nr )
35
+ return numbering[e1 ] < numbering[e2 ];
39
36
else
40
37
{
41
38
// in general un-ordered, with exception of thread-spawning
@@ -49,83 +46,67 @@ void memory_model_baset::read_from(symex_target_equationt &equation)
49
46
// make them match at least one
50
47
// (internal or external) write.
51
48
52
- for (address_mapt::const_iterator
53
- a_it=address_map.begin ();
54
- a_it!=address_map.end ();
55
- a_it++)
49
+ for (const auto &address : address_map)
56
50
{
57
- const a_rect &a_rec=a_it->second ;
58
-
59
- for (event_listt::const_iterator
60
- r_it=a_rec.reads .begin ();
61
- r_it!=a_rec.reads .end ();
62
- r_it++)
51
+ for (const auto &read_event : address.second .reads )
63
52
{
64
- const event_it r=*r_it;
65
-
66
- exprt::operandst rf_some_operands;
67
- rf_some_operands.reserve (a_rec.writes .size ());
53
+ exprt::operandst rf_choice_symbols;
54
+ rf_choice_symbols.reserve (address.second .writes .size ());
68
55
69
56
// this is quadratic in #events per address
70
- for (event_listt::const_iterator
71
- w_it=a_rec.writes .begin ();
72
- w_it!=a_rec.writes .end ();
73
- ++w_it)
57
+ for (const auto &write_event : address.second .writes )
74
58
{
75
- const event_it w=*w_it;
76
-
77
59
// rf cannot contradict program order
78
- if (po (r, w))
79
- continue ; // contradicts po
80
-
81
- bool is_rfi=
82
- w->source .thread_nr ==r->source .thread_nr ;
83
-
84
- symbol_exprt s=nondet_bool_symbol (" rf" );
85
-
86
- // record the symbol
87
- choice_symbols.emplace (std::make_pair (r, w), s);
88
-
89
- // We rely on the fact that there is at least
90
- // one write event that has guard 'true'.
91
- implies_exprt read_from (s,
92
- and_exprt (w->guard ,
93
- equal_exprt (r->ssa_lhs , w->ssa_lhs )));
94
-
95
- // Uses only the write's guard as precondition, read's guard
96
- // follows from rf_some
97
- add_constraint (equation,
98
- read_from, is_rfi?" rfi" :" rf" , r->source );
99
-
100
- if (!is_rfi)
60
+ if (!po (read_event, write_event))
101
61
{
102
- // if r reads from w, then w must have happened before r
103
- const implies_exprt cond (s, before (w, r));
104
- add_constraint (equation,
105
- cond, " rf-order" , r->source );
62
+ rf_choice_symbols.push_back (register_read_from_choice_symbol (
63
+ read_event, write_event, equation));
106
64
}
107
-
108
- rf_some_operands.push_back (s);
109
65
}
110
66
111
- // value equals the one of some write
112
- exprt rf_some;
113
-
114
67
// uninitialised global symbol like symex_dynamic::dynamic_object*
115
68
// or *$object
116
- if (rf_some_operands.empty ())
117
- continue ;
118
- else if (rf_some_operands.size ()==1 )
119
- rf_some=rf_some_operands.front ();
120
- else
69
+ if (!rf_choice_symbols.empty ())
121
70
{
122
- rf_some = or_exprt (std::move (rf_some_operands));
71
+ // Add the read's guard, each of the writes' guards is implied
72
+ // by each entry in rf_some
73
+ add_constraint (
74
+ equation,
75
+ implies_exprt{read_event->guard , disjunction (rf_choice_symbols)},
76
+ " rf-some" ,
77
+ read_event->source );
123
78
}
124
-
125
- // Add the read's guard, each of the writes' guards is implied
126
- // by each entry in rf_some
127
- add_constraint (equation,
128
- implies_exprt (r->guard , rf_some), " rf-some" , r->source );
129
79
}
130
80
}
131
81
}
82
+
83
+ symbol_exprt memory_model_baset::register_read_from_choice_symbol (
84
+ const event_it &r,
85
+ const event_it &w,
86
+ symex_target_equationt &equation)
87
+ {
88
+ symbol_exprt s = nondet_bool_symbol (" rf" );
89
+
90
+ // record the symbol
91
+ choice_symbols.emplace (std::make_pair (r, w), s);
92
+
93
+ bool is_rfi = w->source .thread_nr == r->source .thread_nr ;
94
+ // Uses only the write's guard as precondition, read's guard
95
+ // follows from rf_some
96
+ add_constraint (
97
+ equation,
98
+ // We rely on the fact that there is at least
99
+ // one write event that has guard 'true'.
100
+ implies_exprt{s, and_exprt{w->guard , equal_exprt{r->ssa_lhs , w->ssa_lhs }}},
101
+ is_rfi ? " rfi" : " rf" ,
102
+ r->source );
103
+
104
+ if (!is_rfi)
105
+ {
106
+ // if r reads from w, then w must have happened before r
107
+ add_constraint (
108
+ equation, implies_exprt{s, before (w, r)}, " rf-order" , r->source );
109
+ }
110
+
111
+ return s;
112
+ }
0 commit comments