@@ -14,6 +14,7 @@ Date: April 2017
1414#include " mm_io.h"
1515
1616#include < util/fresh_symbol.h>
17+ #include < util/message.h>
1718#include < util/pointer_expr.h>
1819#include < util/pointer_offset_size.h>
1920#include < util/pointer_predicates.h>
@@ -23,6 +24,51 @@ Date: April 2017
2324
2425#include < set>
2526
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+
2672static std::set<dereference_exprt> collect_deref_expr (const exprt &src)
2773{
2874 std::set<dereference_exprt> collected;
@@ -33,13 +79,12 @@ static std::set<dereference_exprt> collect_deref_expr(const exprt &src)
3379 return collected;
3480}
3581
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)
4283{
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+
4388 for (auto it = goto_function.body .instructions .begin ();
4489 it != goto_function.body .instructions .end ();
4590 it++)
@@ -76,6 +121,7 @@ void mm_io(
76121 typecast_exprt (size_opt.value (), st)},
77122 source_location);
78123 goto_function.body .insert_before_swap (it, call);
124+ ++reads_replaced;
79125 it++;
80126 }
81127 }
@@ -99,45 +145,33 @@ void mm_io(
99145 typecast_exprt (a_rhs, vt)});
100146 goto_function.body .insert_before_swap (it);
101147 *it = goto_programt::make_function_call (fc, source_location);
148+ ++writes_replaced;
102149 it++;
103150 }
104151 }
105152 }
106153}
107154
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)
109159{
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};
114161
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 ) ;
117164
118- if (const auto mm_io_r_symbol = symbol_table. lookup (id_r) )
165+ if (rewrite. reads_replaced || rewrite. writes_replaced )
119166 {
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;
131171 }
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);
138172}
139173
140- void mm_io (goto_modelt &model)
174+ void mm_io (goto_modelt &model, message_handlert &message_handler )
141175{
142- mm_io (model.symbol_table , model.goto_functions );
176+ mm_io (model.symbol_table , model.goto_functions , message_handler );
143177}
0 commit comments