CBMC
Loading...
Searching...
No Matches
weak_memory.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Weak Memory Instrumentation for Threaded Goto Programs
4
5Author: Daniel Kroening, Vincent Nimal
6
7Date: September 2011
8
9\*******************************************************************/
10
13
14/*
15 * Strategy: we first overapproximate all the read/write sequences of
16 * the program executions with a read/write graph. We then detect the
17 * pairs potentially dangerous, and to be delayed in some executions
18 * of the program. We finally insert the corresponding instrumentations
19 * in the program.
20 */
21
22#include "weak_memory.h"
23
24#include <set>
25
26#include <util/fresh_symbol.h>
27
29
31
33
34#include "shared_buffers.h"
35#include "goto2graph.h"
36
39 value_setst &value_sets,
40 symbol_tablet &symbol_table,
41 const irep_idt &function_id,
42 goto_programt &goto_program,
44 const goto_functionst::goto_functiont &goto_function,
45#endif
46 messaget &message)
47{
48 namespacet ns(symbol_table);
49
50#ifdef LOCAL_MAY
51 local_may_aliast local_may(goto_function);
52#endif
53
55 {
57
58 message.debug() << instruction.source_location() << messaget::eom;
59
60 if(instruction.is_goto() ||
61 instruction.is_assert() ||
62 instruction.is_assume())
63 {
65 ns,
66 value_sets,
67 function_id,
68 i_it,
71#endif
72 message.get_message_handler()); // NOLINT(whitespace/parens)
73 if(rw_set.empty())
74 continue;
75
76 symbolt &new_symbol = get_fresh_aux_symbol(
77 bool_typet(),
78 id2string(function_id),
79 "$tmp_guard",
80 instruction.source_location(),
81 ns.lookup(function_id).mode,
82 symbol_table);
83 new_symbol.is_static_lifetime=true;
84 new_symbol.is_thread_local=true;
85 new_symbol.value.make_nil();
86
87 symbol_exprt symbol_expr=new_symbol.symbol_expr();
88
90 code_assignt(symbol_expr, instruction.condition()),
91 instruction.source_location());
92
93 // replace guard
94 instruction.condition_nonconst() = symbol_expr;
95 goto_program.insert_before_swap(i_it, new_i);
96
97 i_it++; // step forward
98 }
99 else if(instruction.is_function_call())
100 {
101 // nothing
102 }
103 }
104}
105
107 memory_modelt model,
108 value_setst &value_sets,
109 goto_modelt &goto_model,
110 bool SCC,
112 bool no_cfg_kill,
113 bool no_dependencies,
115 unsigned input_max_var,
116 unsigned input_max_po_trans,
117 bool render_po,
118 bool render_file,
119 bool render_function,
120 bool cav11_option,
121 bool hide_internals,
122 message_handlert &message_handler,
123 bool ignore_arrays)
124{
125 messaget message(message_handler);
126
127 // no more used -- dereferences performed in rw_set
128 // get rid of pointers
129 // remove_pointers(goto_functions, symbol_table, value_sets);
130 // add_failed_symbols(symbol_table);
131 // message.status() <<"pointers removed"<< messaget::eom;
132
133 message.status() << "--------" << messaget::eom;
134
135 // all access to shared variables is pushed into assignments
136 for(auto &gf_entry : goto_model.goto_functions.function_map)
137 {
138 if(
139 gf_entry.first != INITIALIZE_FUNCTION &&
141 {
143 value_sets,
144 goto_model.symbol_table,
145 gf_entry.first,
146 gf_entry.second.body,
148 gf_entry.second,
149#endif
150 message);
151 }
152 }
153
154 message.status() << "Temp added" << messaget::eom;
155
156 unsigned max_thds = 0;
157 instrumentert instrumenter(goto_model, message);
158 max_thds=instrumenter.goto2graph_cfg(value_sets, model, no_dependencies,
160 message.status()<<"abstraction completed"<<messaget::eom;
161
162 // collects cycles, directly or by SCCs
165 input_max_po_trans, ignore_arrays);
166 else
167 instrumenter.set_parameters_collection(max_thds, 0, ignore_arrays);
168
169 if(SCC)
170 {
171 instrumenter.collect_cycles_by_SCCs(model);
172 message.status()<<"cycles collected: "<<messaget::eom;
173 unsigned interesting_scc = 0;
174 unsigned total_cycles = 0;
175 for(unsigned i=0; i<instrumenter.num_sccs; i++)
176 if(instrumenter.egraph_SCCs[i].size()>=4)
177 {
178 message.status()<<"SCC #"<<i<<": "
179 <<instrumenter.set_of_cycles_per_SCC[interesting_scc++].size()
180 <<" cycles found"<<messaget::eom;
181 total_cycles += instrumenter
183 }
184
185 /* if no cycle, no need to instrument */
186 if(total_cycles == 0)
187 {
188 message.status()<<"program safe -- no need to instrument"<<messaget::eom;
189 return;
190 }
191 }
192 else
193 {
194 instrumenter.collect_cycles(model);
195 message.status()<<"cycles collected: "<<instrumenter.set_of_cycles.size()
196 <<" cycles found"<<messaget::eom;
197
198 /* if no cycle, no need to instrument */
199 if(instrumenter.set_of_cycles.empty())
200 {
201 message.status()<<"program safe -- no need to instrument"<<messaget::eom;
202 return;
203 }
204 }
205
206 if(!no_cfg_kill)
207 instrumenter.cfg_cycles_filter();
208
209 // collects instructions to instrument, depending on the strategy selected
211 {
212 const std::set<event_idt> events_set = instrumentert::extract_my_events();
213 instrumenter.instrument_my_events(events_set);
214 }
215 else
217
218 // prints outputs
220 instrumenter.print_outputs(model, hide_internals);
221
222 // now adds buffers
223 shared_bufferst shared_buffers(
224 goto_model.symbol_table, max_thds, message);
225
226 if(cav11_option)
227 shared_buffers.set_cav11(model);
228
229 // stores the events to instrument
230 shared_buffers.cycles = instrumenter.var_to_instr; // var in the cycles
231 shared_buffers.cycles_loc = instrumenter.id2loc; // instrumented places
232 shared_buffers.cycles_r_loc = instrumenter.id2cycloc; // places in the cycles
233
234 // for reads delays
235 shared_buffers.affected_by_delay(value_sets, goto_model.goto_functions);
236
237 for(std::set<irep_idt>::iterator it=
238 shared_buffers.affected_by_delay_set.begin();
239 it!=shared_buffers.affected_by_delay_set.end();
240 it++)
241 message.debug()<<id2string(*it)<<messaget::eom;
242
243 message.status()<<"I instrument:"<<messaget::eom;
244 for(std::set<irep_idt>::iterator it=shared_buffers.cycles.begin();
245 it!=shared_buffers.cycles.end(); it++)
246 {
247 typedef std::multimap<irep_idt, source_locationt>::iterator m_itt;
248 const std::pair<m_itt, m_itt> ran=
249 shared_buffers.cycles_loc.equal_range(*it);
250 for(m_itt ran_it=ran.first; ran_it!=ran.second; ran_it++)
251 message.result() << (it->empty() ? "fence" : *it) << ", "
252 << ran_it->second << messaget::eom;
253 }
254
256 shared_buffers, goto_model.symbol_table, goto_model.goto_functions);
257 visitor.weak_memory(
258 value_sets, goto_model.goto_functions.entry_point(), model);
259
260 /* removes potential skips */
261 remove_skip(goto_model);
262
263 // initialization code for buffers
264 shared_buffers.add_initialization_code(goto_model.goto_functions);
265
266 // update counters etc.
267 goto_model.goto_functions.update();
268
269 message.status()<< "Goto-program instrumented" << messaget::eom;
270}
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
The Boolean type.
Definition std_types.h:36
A goto_instruction_codet representing an assignment in the program.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
function_mapt function_map
::goto_functiont goto_functiont
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
symbol_tablet symbol_table
Symbol table.
Definition goto_model.h:31
goto_functionst goto_functions
GOTO functions.
Definition goto_model.h:34
This class represents an instruction in the GOTO intermediate representation.
const exprt & condition() const
Get the condition of gotos, assume, assert.
exprt & condition_nonconst()
Get the condition of gotos, assume, assert.
const source_locationt & source_location() const
A generic container class for the GOTO intermediate representation of one function.
void insert_before_swap(targett target)
Insertion that preserves jumps to "target".
static instructiont make_assignment(const code_assignt &_code, const source_locationt &l=source_locationt::nil())
Create an assignment instruction.
std::multimap< irep_idt, source_locationt > id2cycloc
Definition goto2graph.h:355
void print_outputs(memory_modelt model, bool hide_internals)
unsigned num_sccs
Definition goto2graph.h:319
void instrument_my_events(const std::set< event_idt > &events)
void collect_cycles_by_SCCs(memory_modelt model)
Note: can be distributed (#define DISTRIBUTED)
std::set< event_grapht::critical_cyclet > set_of_cycles
Definition goto2graph.h:315
void collect_cycles(memory_modelt model)
Definition goto2graph.h:381
void instrument_with_strategy(instrumentation_strategyt strategy)
std::set< irep_idt > var_to_instr
Definition goto2graph.h:353
std::vector< std::set< event_idt > > egraph_SCCs
Definition goto2graph.h:312
void set_parameters_collection(unsigned _max_var=0, unsigned _max_po_trans=0, bool _ignore_arrays=false)
Definition goto2graph.h:394
std::multimap< irep_idt, source_locationt > id2loc
Definition goto2graph.h:354
std::vector< std::set< event_grapht::critical_cyclet > > set_of_cycles_per_SCC
Definition goto2graph.h:318
unsigned goto2graph_cfg(value_setst &value_sets, memory_modelt model, bool no_dependencies, loop_strategyt duplicate_body)
goes through CFG and build a static abstract event graph overapproximating the read/write relations f...
void cfg_cycles_filter()
void set_rendering_options(bool aligned, bool file, bool function)
Definition goto2graph.h:414
static std::set< event_idt > extract_my_events()
void make_nil()
Definition irep.h:446
Class that provides messages with a built-in verbosity 'level'.
Definition message.h:154
mstreamt & debug() const
Definition message.h:421
mstreamt & result() const
Definition message.h:401
static eomt eom
Definition message.h:289
mstreamt & status() const
Definition message.h:406
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
std::multimap< irep_idt, source_locationt > cycles_loc
void set_cav11(memory_modelt model)
void affected_by_delay(value_setst &value_sets, goto_functionst &goto_functions)
analysis over the goto-program which computes in affected_by_delay_set the variables (non necessarily...
std::set< irep_idt > affected_by_delay_set
std::set< irep_idt > cycles
std::multimap< irep_idt, source_locationt > cycles_r_loc
void add_initialization_code(goto_functionst &goto_functions)
Expression to hold a symbol (variable)
Definition std_expr.h:131
The symbol table.
Symbol table entry.
Definition symbol.h:28
bool is_static_lifetime
Definition symbol.h:70
bool is_thread_local
Definition symbol.h:71
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition symbol.cpp:121
exprt value
Initial value of symbol.
Definition symbol.h:34
symbolt & get_fresh_aux_symbol(const typet &type, const std::string &name_prefix, const std::string &basename_prefix, const source_locationt &source_location, const irep_idt &symbol_mode, const namespacet &ns, symbol_table_baset &symbol_table)
Installs a fresh-named symbol with respect to the given namespace ns with the requested name pattern ...
Fresh auxiliary symbol creation.
Instrumenter.
#define Forall_goto_program_instructions(it, program)
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
void remove_skip(goto_programt &goto_program, goto_programt::targett begin, goto_programt::targett end)
remove unnecessary skip statements
Program Transformation.
Race Detection for Threaded Goto Programs.
#define INITIALIZE_FUNCTION
void weak_memory(memory_modelt model, value_setst &value_sets, goto_modelt &goto_model, bool SCC, instrumentation_strategyt event_strategy, bool no_cfg_kill, bool no_dependencies, loop_strategyt duplicate_body, unsigned input_max_var, unsigned input_max_po_trans, bool render_po, bool render_file, bool render_function, bool cav11_option, bool hide_internals, message_handlert &message_handler, bool ignore_arrays)
void introduce_temporaries(value_setst &value_sets, symbol_tablet &symbol_table, const irep_idt &function_id, goto_programt &goto_program, messaget &message)
all access to shared variables is pushed into assignments
Weak Memory Instrumentation for Threaded Goto Programs.
memory_modelt
Definition wmm.h:18
loop_strategyt
Definition wmm.h:37
instrumentation_strategyt
Definition wmm.h:27
@ my_events
Definition wmm.h:32