@@ -14,6 +14,7 @@ Date: April 2017
14
14
#include " mm_io.h"
15
15
16
16
#include < util/fresh_symbol.h>
17
+ #include < util/message.h>
17
18
#include < util/pointer_expr.h>
18
19
#include < util/pointer_offset_size.h>
19
20
#include < util/pointer_predicates.h>
@@ -23,6 +24,51 @@ Date: April 2017
23
24
24
25
#include < set>
25
26
27
+ class mm_iot
28
+ {
29
+ public:
30
+ explicit mm_iot (symbol_table_baset &symbol_table);
31
+
32
+ void mm_io (goto_functionst::goto_functiont &goto_function);
33
+
34
+ std::size_t reads_replaced = 0 ;
35
+ std::size_t writes_replaced = 0 ;
36
+
37
+ protected:
38
+ const irep_idt id_r = CPROVER_PREFIX " mm_io_r" ;
39
+ const irep_idt id_w = CPROVER_PREFIX " mm_io_w" ;
40
+
41
+ const namespacet ns;
42
+ exprt mm_io_r;
43
+ exprt mm_io_r_value;
44
+ exprt mm_io_w;
45
+ };
46
+
47
+ mm_iot::mm_iot (symbol_table_baset &symbol_table)
48
+ : ns(symbol_table),
49
+ mm_io_r(nil_exprt{}),
50
+ mm_io_r_value(nil_exprt{}),
51
+ mm_io_w(nil_exprt{})
52
+ {
53
+ if (const auto mm_io_r_symbol = symbol_table.lookup (id_r))
54
+ {
55
+ mm_io_r = mm_io_r_symbol->symbol_expr ();
56
+
57
+ const auto &value_symbol = get_fresh_aux_symbol (
58
+ to_code_type (mm_io_r.type ()).return_type (),
59
+ id2string (id_r) + " $value" ,
60
+ id2string (id_r) + " $value" ,
61
+ mm_io_r_symbol->location ,
62
+ mm_io_r_symbol->mode ,
63
+ symbol_table);
64
+
65
+ mm_io_r_value = value_symbol.symbol_expr ();
66
+ }
67
+
68
+ if (const auto mm_io_w_symbol = symbol_table.lookup (id_w))
69
+ mm_io_w = mm_io_w_symbol->symbol_expr ();
70
+ }
71
+
26
72
static std::set<dereference_exprt> collect_deref_expr (const exprt &src)
27
73
{
28
74
std::set<dereference_exprt> collected;
@@ -33,13 +79,12 @@ static std::set<dereference_exprt> collect_deref_expr(const exprt &src)
33
79
return collected;
34
80
}
35
81
36
- void mm_io (
37
- const exprt &mm_io_r,
38
- const exprt &mm_io_r_value,
39
- const exprt &mm_io_w,
40
- goto_functionst::goto_functiont &goto_function,
41
- const namespacet &ns)
82
+ void mm_iot::mm_io (goto_functionst::goto_functiont &goto_function)
42
83
{
84
+ // return early when there is nothing to be done
85
+ if (mm_io_r.is_nil () && mm_io_w.is_nil ())
86
+ return ;
87
+
43
88
for (auto it = goto_function.body .instructions .begin ();
44
89
it != goto_function.body .instructions .end ();
45
90
it++)
@@ -76,6 +121,7 @@ void mm_io(
76
121
typecast_exprt (size_opt.value (), st)},
77
122
source_location);
78
123
goto_function.body .insert_before_swap (it, call);
124
+ ++reads_replaced;
79
125
it++;
80
126
}
81
127
}
@@ -99,45 +145,33 @@ void mm_io(
99
145
typecast_exprt (a_rhs, vt)});
100
146
goto_function.body .insert_before_swap (it);
101
147
*it = goto_programt::make_function_call (fc, source_location);
148
+ ++writes_replaced;
102
149
it++;
103
150
}
104
151
}
105
152
}
106
153
}
107
154
108
- void mm_io (symbol_tablet &symbol_table, goto_functionst &goto_functions)
155
+ void mm_io (
156
+ symbol_tablet &symbol_table,
157
+ goto_functionst &goto_functions,
158
+ message_handlert &message_handler)
109
159
{
110
- const namespacet ns (symbol_table);
111
- exprt mm_io_r = nil_exprt ();
112
- exprt mm_io_r_value = nil_exprt ();
113
- exprt mm_io_w = nil_exprt ();
160
+ mm_iot rewrite{symbol_table};
114
161
115
- const irep_idt id_r = CPROVER_PREFIX " mm_io_r " ;
116
- const irep_idt id_w = CPROVER_PREFIX " mm_io_w " ;
162
+ for ( auto &f : goto_functions. function_map )
163
+ rewrite. mm_io (f. second ) ;
117
164
118
- if (const auto mm_io_r_symbol = symbol_table. lookup (id_r) )
165
+ if (rewrite. reads_replaced || rewrite. writes_replaced )
119
166
{
120
- mm_io_r = mm_io_r_symbol->symbol_expr ();
121
-
122
- const auto &value_symbol = get_fresh_aux_symbol (
123
- to_code_type (mm_io_r.type ()).return_type (),
124
- id2string (id_r) + " $value" ,
125
- id2string (id_r) + " $value" ,
126
- mm_io_r_symbol->location ,
127
- mm_io_r_symbol->mode ,
128
- symbol_table);
129
-
130
- mm_io_r_value = value_symbol.symbol_expr ();
167
+ messaget log {message_handler};
168
+ log .status () << " Replaced MMIO operations: " << rewrite.reads_replaced
169
+ << " read(s), " << rewrite.writes_replaced << " write(s)"
170
+ << messaget::eom;
131
171
}
132
-
133
- if (const auto mm_io_w_symbol = symbol_table.lookup (id_w))
134
- mm_io_w = mm_io_w_symbol->symbol_expr ();
135
-
136
- for (auto & f : goto_functions.function_map )
137
- mm_io (mm_io_r, mm_io_r_value, mm_io_w, f.second , ns);
138
172
}
139
173
140
- void mm_io (goto_modelt &model)
174
+ void mm_io (goto_modelt &model, message_handlert &message_handler )
141
175
{
142
- mm_io (model.symbol_table , model.goto_functions );
176
+ mm_io (model.symbol_table , model.goto_functions , message_handler );
143
177
}
0 commit comments