CBMC
variable_sensitivity_dependence_graph.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3  Module: analyses variable-sensitivity variable-sensitivity-dependence-graph
4 
5  Author: Diffblue Ltd.
6 
7 \*******************************************************************/
8 
11 
12 #include <langapi/language_util.h>
13 
14 #include <util/container_utils.h>
15 #include <util/json.h>
16 #include <util/json_irep.h>
17 #include <util/std_code.h>
18 
28  const exprt &expr,
29  const namespacet &ns,
30  data_depst &deps) const
31 {
32  const auto res =
33  std::dynamic_pointer_cast<const data_dependency_contextt>(eval(expr, ns));
34 
35  if(res->get_data_dependencies().size() > 0)
36  {
37  // If the expression was able to be eval'ed to something with data
38  // dependencies, then that's all we need to gather.
39  for(const auto &dep : res->get_data_dependencies())
40  deps[dep].insert(expr);
41  }
42  else
43  {
44  // If the expression could not be eval'ed to something with data
45  // dependencies, then it may have been some sort of compound expression,
46  // so attempt to eval the data dependencies for all the operands, taking
47  // the union of them all.
48  for(const exprt &op : expr.operands())
49  {
50  eval_data_deps(op, ns, deps);
51  }
52  }
53 }
54 
69  const irep_idt &function_from,
70  trace_ptrt trace_from,
71  const irep_idt &function_to,
72  trace_ptrt trace_to,
73  ai_baset &ai,
74  const namespacet &ns)
75 {
76  locationt from{trace_from->current_location()};
77  locationt to{trace_to->current_location()};
78 
80  function_from, trace_from, function_to, trace_to, ai, ns);
81 
83  dynamic_cast<variable_sensitivity_dependence_grapht *>(&ai);
85  dep_graph != nullptr, "Domains should all be of the same type");
86 
87  // propagate control dependencies across function calls
88  if(from->is_function_call())
89  {
90  if(function_from == function_to)
91  {
92  control_dependencies(function_from, from, function_to, to, *dep_graph);
93  }
94  else
95  {
96  // edge to function entry point
97  const goto_programt::const_targett next = std::next(from);
98 
101  &(dep_graph->get_state(next)));
102  DATA_INVARIANT(s != nullptr, "Domains should all be of the same type");
103 
104  if(s->has_values.is_false())
105  {
106  s->has_values = tvt::unknown();
107  s->has_changed = true;
108  }
109 
110  // modify abstract state of return location
112  control_deps,
116  s->has_changed = true;
117 
118  control_deps.clear();
119  control_dep_candidates.clear();
120 
121  control_dep_calls.clear();
122  control_dep_calls.insert(from);
123 
125  control_dep_call_candidates.insert(from);
126  }
127  }
128  else
129  control_dependencies(function_from, from, function_to, to, *dep_graph);
130 
131  // Find all the data dependencies in the the 'to' expression
132  data_dependencies(from, to, *dep_graph, ns);
133 }
134 
139  const namespacet &ns)
140 {
141  // Find all the data dependencies in the the 'to' expression
142  domain_data_deps.clear();
143  if(to->is_assign())
144  {
145  const exprt &rhs = to->assign_rhs();
146 
147  // Handle return value of a 'no body' function
148  if(rhs.id() == ID_side_effect)
149  {
150  const side_effect_exprt &see = to_side_effect_expr(rhs);
151  if(see.get_statement() == ID_nondet)
152  {
153  if(from->is_function_call())
154  {
155  const exprt &call = from->call_function();
156 
157  if(call.id() == ID_symbol)
158  {
159  const irep_idt id = to_symbol_expr(call).id();
160  const goto_functionst &goto_functions = dep_graph.goto_functions;
161 
162  goto_functionst::function_mapt::const_iterator it =
163  goto_functions.function_map.find(id);
164 
165  if(it != goto_functions.function_map.end())
166  {
167  if(!it->second.body_available()) // body not available
168  {
169  domain_data_deps[from].insert(call);
170  }
171  }
172  else // function not in map
173  {
174  domain_data_deps[from].insert(call);
175  }
176  }
177  else // complex call expression
178  {
179  domain_data_deps[from].insert(call);
180  }
181  }
182  }
183  }
184  else
185  {
186  // Just an ordinary assignement
188  }
189  }
190  else if(to->is_function_call())
191  {
192  const code_function_callt::argumentst &args = to->call_arguments();
193  for(const auto &arg : args)
194  {
196  }
197  }
198  else if(to->is_goto())
199  {
200  eval_data_deps(to->condition(), ns, domain_data_deps);
201  }
202 }
203 
205  const irep_idt &from_function,
207  const irep_idt &to_function,
210 {
211  // Better Slicing of Programs with Jumps and Switches
212  // Kumar and Horwitz, FASE'02:
213  // "Node N is control dependent on node M iff N postdominates, in
214  // the CFG, one but not all of M's CFG successors."
215  //
216  // The "successor" above refers to an immediate successor of M.
217 
218  // Candidates for M for "to" are "from" and all existing control
219  // dependencies on nodes. "from" is added if it is a goto or assume
220  // instruction
221 
222  // Add new candidates
223 
224  if(from->is_goto() || from->is_assume())
225  control_dep_candidates.insert(from);
226  else if(from->is_end_function())
227  {
228  control_deps.clear();
229  control_dep_candidates.clear();
230  control_dep_calls.clear();
232  return;
233  }
234 
235  // Compute postdominators if needed
236 
237  const goto_functionst &goto_functions = dep_graph.goto_functions;
238 
239  const irep_idt id = from_function;
240  cfg_post_dominatorst &pd_tmp = dep_graph.cfg_post_dominators()[id];
241 
242  goto_functionst::function_mapt::const_iterator f_it =
243  goto_functions.function_map.find(id);
244 
245  if(f_it == goto_functions.function_map.end())
246  return;
247 
248  const goto_programt &goto_program = f_it->second.body;
249 
250  if(pd_tmp.cfg.size() == 0) // have we computed the dominators already?
251  {
252  pd_tmp(goto_program);
253  }
254 
255  const cfg_post_dominatorst &pd = pd_tmp;
256 
257  // Check all candidates
258 
259  for(const auto &cd : control_dep_candidates)
260  {
261  // check all CFG successors of M
262  // special case: assumptions also introduce a control dependency
263  bool post_dom_all = !cd->is_assume();
264  bool post_dom_one = false;
265 
266  // we could hard-code assume and goto handling here to improve
267  // performance
269 
270  // successors of M
271  for(const auto &edge : m.out)
272  {
273  const cfg_post_dominatorst::cfgt::nodet &m_s = pd.cfg[edge.first];
274 
275  if(m_s.dominators.find(to) != m_s.dominators.end())
276  post_dom_one = true;
277  else
278  post_dom_all = false;
279  }
280 
281  if(post_dom_all || !post_dom_one)
282  {
283  control_deps.erase(cd);
284  }
285  else
286  {
287  tvt branch = tvt::unknown();
288 
289  if(cd->is_goto() && !cd->is_backwards_goto())
290  {
291  goto_programt::const_targett t = cd->get_target();
292  branch =
293  to->location_number >= t->location_number ? tvt(false) : tvt(true);
294  }
295 
296  control_deps.insert(std::make_pair(cd, branch));
297  }
298  }
299 
300  if(control_deps.empty())
301  {
303  }
304  else
305  {
306  control_dep_calls.clear();
307  }
308 
309  // add edges to the graph
310  for(const auto &c_dep : control_deps)
311  dep_graph.add_dep(vs_dep_edget::kindt::CTRL, c_dep.first, to);
312 }
313 
315  const control_depst &other_control_deps,
316  const control_dep_candidatest &other_control_dep_candidates,
317  const control_dep_callst &other_control_dep_calls,
318  const control_dep_callst &other_control_dep_call_candidates)
319 {
320  bool changed = false;
321 
322  // Merge control dependencies
323 
324  control_depst::iterator it = control_deps.begin();
325 
326  for(const auto &c_dep : other_control_deps)
327  {
328  // find position to insert
329  while(it != control_deps.end() && it->first < c_dep.first)
330  ++it;
331 
332  if(it == control_deps.end() || c_dep.first < it->first)
333  {
334  // hint points at position that will follow the new element
335  control_deps.insert(it, c_dep);
336  changed = true;
337  }
338  else
339  {
340  INVARIANT(
341  it != control_deps.end(), "Property of branch needed for safety");
342  INVARIANT(
343  !(it->first < c_dep.first), "Property of loop needed for safety");
344  INVARIANT(
345  !(c_dep.first < it->first), "Property of loop needed for safety");
346 
347  tvt &branch1 = it->second;
348  const tvt &branch2 = c_dep.second;
349 
350  if(branch1 != branch2 && !branch1.is_unknown())
351  {
352  branch1 = tvt::unknown();
353  changed = true;
354  }
355 
356  ++it;
357  }
358  }
359 
360  // Merge control dependency candidates
361 
362  size_t n = control_dep_candidates.size();
363 
364  control_dep_candidates.insert(
365  other_control_dep_candidates.begin(), other_control_dep_candidates.end());
366 
367  changed |= n != control_dep_candidates.size();
368 
369  // Merge call control dependencies
370 
371  n = control_dep_calls.size();
372 
373  control_dep_calls.insert(
374  other_control_dep_calls.begin(), other_control_dep_calls.end());
375 
376  changed |= n != control_dep_calls.size();
377 
378  // Merge call control dependency candidates
379 
380  n = control_dep_call_candidates.size();
381 
383  other_control_dep_call_candidates.begin(),
384  other_control_dep_call_candidates.end());
385 
386  changed |= n != control_dep_call_candidates.size();
387 
388  return changed;
389 }
390 
401  trace_ptrt from,
402  trace_ptrt to)
403 {
404  bool changed = false;
405 
406  changed = variable_sensitivity_domaint::merge(b, from, to);
407  changed |= has_values.is_false() || has_changed;
408 
409  // Handle data dependencies
410  const auto &cast_b =
411  dynamic_cast<const variable_sensitivity_dependence_domaint &>(b);
412 
413  // Merge data dependencies
414  for(auto bdep : cast_b.domain_data_deps)
415  {
416  for(exprt bexpr : bdep.second)
417  {
418  auto result = domain_data_deps[bdep.first].insert(bexpr);
419  changed |= result.second;
420  }
421  }
422 
423  changed |= merge_control_dependencies(
424  cast_b.control_deps,
425  cast_b.control_dep_candidates,
426  cast_b.control_dep_calls,
427  cast_b.control_dep_call_candidates);
428 
429  has_changed = false;
431 
432  return changed;
433 }
434 
446 
449  const ai_domain_baset &function_call,
450  const ai_domain_baset &function_start,
451  const ai_domain_baset &function_end,
452  const namespacet &ns)
453 {
454  // The gathering of the data dependencies for the domain is handled by the
455  // 'transform' and simply relies on the underlying domains with their
456  // data_dependency_context to be correct. Therefore all we need to ensure at
457  // the three way merge is that the underlying variable sensitivity domain
458  // does its three way merge.
460  function_call, function_start, function_end, ns);
461 }
462 
471  std::ostream &out,
472  const ai_baset &ai,
473  const namespacet &ns) const
474 {
475  if(!control_deps.empty() || !control_dep_calls.empty())
476  {
477  out << "Control dependencies: ";
478  for(control_depst::const_iterator it = control_deps.begin();
479  it != control_deps.end();
480  ++it)
481  {
482  if(it != control_deps.begin())
483  out << ",";
484 
485  const goto_programt::const_targett cd = it->first;
486  const tvt branch = it->second;
487 
488  out << cd->location_number << " [" << branch << "]";
489  }
490 
491  for(control_dep_callst::const_iterator it = control_dep_calls.begin();
492  it != control_dep_calls.end();
493  ++it)
494  {
495  if(!control_deps.empty() || it != control_dep_calls.begin())
496  out << ",";
497 
498  out << (*it)->location_number << " [UNCONDITIONAL]";
499  }
500 
501  out << "\n";
502  }
503 
504  if(!domain_data_deps.empty())
505  {
506  out << "Data dependencies: ";
507  bool first = true;
508  for(auto &dep : domain_data_deps)
509  {
510  if(!first)
511  out << ", ";
512 
513  out << dep.first->location_number;
514  out << " [";
515  bool first_expr = true;
516  for(auto &expr : dep.second)
517  {
518  if(!first_expr)
519  out << ", ";
520 
521  out << from_expr(ns, "", expr);
522  first_expr = false;
523  }
524  out << "]";
525 
526  first = false;
527  }
528  out << std::endl;
529  }
530 }
531 
541  const ai_baset &ai,
542  const namespacet &ns) const
543 {
544  json_arrayt graph;
545 
546  for(const auto &cd : control_deps)
547  {
548  const goto_programt::const_targett target = cd.first;
549  const tvt branch = cd.second;
550 
551  json_objectt &link = graph.push_back().make_object();
552 
553  link["locationNumber"] =
554  json_numbert(std::to_string(target->location_number));
555  link["sourceLocation"] = json(target->source_location());
556  link["type"] = json_stringt("control");
557  link["branch"] = json_stringt(branch.to_string());
558  }
559 
560  for(const auto &target : control_dep_calls)
561  {
562  json_objectt &link = graph.push_back().make_object();
563  link["locationNumber"] =
564  json_numbert(std::to_string(target->location_number));
565  link["sourceLocation"] = json(target->source_location());
566  link["type"] = json_stringt("control");
567  link["branch"] = json_stringt("UNCONDITIONAL");
568  }
569 
570  for(const auto &dep : domain_data_deps)
571  {
572  json_objectt &link = graph.push_back().make_object();
573  link["locationNumber"] =
574  json_numbert(std::to_string(dep.first->location_number));
575  link["sourceLocation"] = json(dep.first->source_location());
576  json_stringt(dep.first->source_location().as_string());
577  link["type"] = json_stringt("data");
578 
579  const std::set<exprt> &expr_set = dep.second;
580  json_arrayt &expressions = link["expressions"].make_array();
581 
582  for(const exprt &e : expr_set)
583  {
584  json_objectt &object = expressions.push_back().make_object();
585  object["expression"] = json_stringt(from_expr(ns, "", e));
586  object["certainty"] = json_stringt("maybe");
587  }
588  }
589 
590  return std::move(graph);
591 }
592 
595  goto_programt::const_targett this_loc) const
596 {
597  for(const auto &c_dep : control_deps)
598  dep_graph.add_dep(vs_dep_edget::kindt::CTRL, c_dep.first, this_loc);
599 
600  for(const auto &c_dep : control_dep_calls)
601  dep_graph.add_dep(vs_dep_edget::kindt::CTRL, c_dep, this_loc);
602 
603  for(const auto &d_dep : domain_data_deps)
604  dep_graph.add_dep(vs_dep_edget::kindt::DATA, d_dep.first, this_loc);
605 }
606 
611  : public ai_domain_factoryt<variable_sensitivity_dependence_domaint>
612 {
613 public:
617  const vsd_configt &_configuration)
618  : dg(_dg), object_factory(_object_factory), configuration(_configuration)
619  {
620  }
621 
622  std::unique_ptr<statet> make(locationt l) const override
623  {
624  auto node_id = dg.add_node();
625  dg.nodes[node_id].PC = l;
626  auto p = util_make_unique<variable_sensitivity_dependence_domaint>(
627  node_id, object_factory, configuration);
628  CHECK_RETURN(p->is_bottom());
629 
630  return std::unique_ptr<statet>(p.release());
631  }
632 
633 private:
637 };
638 
640  const goto_functionst &goto_functions,
641  const namespacet &_ns,
643  const vsd_configt &configuration,
644  message_handlert &message_handler)
648  *this,
650  configuration),
652  message_handler),
653  goto_functions(goto_functions),
654  ns(_ns)
655 {
656 }
657 
659  vs_dep_edget::kindt kind,
662 {
663  const node_indext n_from = (*this)[from].get_node_id();
664  DATA_INVARIANT(n_from < size(), "Node ids must be within the graph");
665  const node_indext n_to = (*this)[to].get_node_id();
666  DATA_INVARIANT(n_to < size(), "Node ids must be within the graph");
667 
668  // add_edge is redundant as the subsequent operations also insert
669  // entries into the edge maps (implicitly)
670 
671  // add_edge(n_from, n_to);
672 
673  nodes[n_from].out[n_to].add(kind);
674  nodes[n_to].in[n_from].add(kind);
675 }
variable_sensitivity_dependence_domain_factoryt::object_factory
variable_sensitivity_object_factory_ptrt object_factory
Definition: variable_sensitivity_dependence_graph.cpp:635
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
json_numbert
Definition: json.h:290
variable_sensitivity_dependence_domaint::merge
bool merge(const variable_sensitivity_domaint &b, trace_ptrt from, trace_ptrt to) override
Computes the join between "this" and "b".
Definition: variable_sensitivity_dependence_graph.cpp:399
variable_sensitivity_dependence_domaint::control_deps
control_depst control_deps
Definition: variable_sensitivity_dependence_graph.h:183
grapht::size
std::size_t size() const
Definition: graph.h:212
variable_sensitivity_dependence_grapht::add_dep
void add_dep(vs_dep_edget::kindt kind, goto_programt::const_targett from, goto_programt::const_targett to)
Definition: variable_sensitivity_dependence_graph.cpp:658
variable_sensitivity_dependence_domaint::data_dependencies
void data_dependencies(goto_programt::const_targett from, goto_programt::const_targett to, variable_sensitivity_dependence_grapht &dep_graph, const namespacet &ns)
Definition: variable_sensitivity_dependence_graph.cpp:135
CHECK_RETURN
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495
ahistoricalt
The common case of history is to only care about where you are now, not how you got there!...
Definition: ai_history.h:154
ai_three_way_merget
Definition: three_way_merge_abstract_interpreter.h:27
variable_sensitivity_dependence_domaint::output
void output(std::ostream &out, const ai_baset &ai, const namespacet &ns) const override
Basic text output of the abstract domain.
Definition: variable_sensitivity_dependence_graph.cpp:470
variable_sensitivity_dependence_domaint::control_dep_callst
std::set< goto_programt::const_targett > control_dep_callst
Definition: variable_sensitivity_dependence_graph.h:188
variable_sensitivity_dependence_domaint::data_depst
std::map< goto_programt::const_targett, std::set< exprt >, dependency_ordert > data_depst
Definition: variable_sensitivity_dependence_graph.h:179
variable_sensitivity_domaint::eval
virtual abstract_object_pointert eval(const exprt &expr, const namespacet &ns) const
Definition: variable_sensitivity_domain.h:216
grapht::add_node
node_indext add_node(arguments &&... values)
Definition: graph.h:180
variable_sensitivity_dependence_domaint::domain_data_deps
data_depst domain_data_deps
Definition: variable_sensitivity_dependence_graph.h:180
exprt
Base class for all expressions.
Definition: expr.h:55
variable_sensitivity_dependence_domain_factoryt::configuration
const vsd_configt configuration
Definition: variable_sensitivity_dependence_graph.cpp:636
variable_sensitivity_dependence_domain_factoryt::make
std::unique_ptr< statet > make(locationt l) const override
Definition: variable_sensitivity_dependence_graph.cpp:622
variable_sensitivity_dependence_domain_factoryt::dg
variable_sensitivity_dependence_grapht & dg
Definition: variable_sensitivity_dependence_graph.cpp:634
variable_sensitivity_dependence_domain_factoryt::variable_sensitivity_dependence_domain_factoryt
variable_sensitivity_dependence_domain_factoryt(variable_sensitivity_dependence_grapht &_dg, variable_sensitivity_object_factory_ptrt _object_factory, const vsd_configt &_configuration)
Definition: variable_sensitivity_dependence_graph.cpp:614
tvt::is_unknown
bool is_unknown() const
Definition: threeval.h:27
to_string
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Definition: string_constraint.cpp:58
to_side_effect_expr
side_effect_exprt & to_side_effect_expr(exprt &expr)
Definition: std_code.h:1506
vs_dep_edget::kindt::DATA
@ DATA
goto_functionst::function_map
function_mapt function_map
Definition: goto_functions.h:29
jsont::make_object
json_objectt & make_object()
Definition: json.h:438
jsont
Definition: json.h:26
variable_sensitivity_dependence_graph.h
vsd_configt
Definition: variable_sensitivity_configuration.h:44
json_irep.h
ai_domain_baset::trace_ptrt
ai_history_baset::trace_ptrt trace_ptrt
Definition: ai_domain.h:74
variable_sensitivity_dependence_grapht::goto_functions
const goto_functionst & goto_functions
Definition: variable_sensitivity_dependence_graph.h:280
json_arrayt
Definition: json.h:164
grapht< vs_dep_nodet >::node_indext
nodet::node_indext node_indext
Definition: graph.h:173
json_objectt
Definition: json.h:299
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
vs_dep_edget::kindt
kindt
Definition: variable_sensitivity_dependence_graph.h:28
util_make_unique
std::unique_ptr< T > util_make_unique(Ts &&... ts)
Definition: make_unique.h:19
DATA_INVARIANT
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:510
ai_history_factory_default_constructort
An easy factory implementation for histories that don't need parameters.
Definition: ai_history.h:254
branch
void branch(goto_modelt &goto_model, const irep_idt &id)
Definition: branch.cpp:22
variable_sensitivity_dependence_grapht::variable_sensitivity_dependence_grapht
variable_sensitivity_dependence_grapht(const goto_functionst &goto_functions, const namespacet &_ns, variable_sensitivity_object_factory_ptrt object_factory, const vsd_configt &_configuration, message_handlert &message_handler)
Definition: variable_sensitivity_dependence_graph.cpp:639
language_util.h
util_inplace_set_union
bool util_inplace_set_union(std::set< T, Compare, Alloc > &target, const std::set< T, Compare, Alloc > &source)
Compute union of two sets.
Definition: container_utils.h:28
variable_sensitivity_object_factory_ptrt
std::shared_ptr< variable_sensitivity_object_factoryt > variable_sensitivity_object_factory_ptrt
Definition: abstract_environment.h:30
json
static void json(json_objectT &result, const irep_idt &property_id, const property_infot &property_info)
Definition: properties.cpp:120
vs_dep_edget::kindt::CTRL
@ CTRL
variable_sensitivity_dependence_domaint::control_dep_candidatest
std::set< goto_programt::const_targett > control_dep_candidatest
Definition: variable_sensitivity_dependence_graph.h:185
variable_sensitivity_domaint::merge_three_way_function_return
virtual void merge_three_way_function_return(const ai_domain_baset &function_call, const ai_domain_baset &function_start, const ai_domain_baset &function_end, const namespacet &ns)
Perform a context aware merge of the changes that have been applied between function_start and the cu...
Definition: variable_sensitivity_domain.cpp:430
object_factory
exprt object_factory(const typet &type, const irep_idt base_name, code_blockt &init_code, symbol_table_baset &symbol_table, java_object_factory_parameterst parameters, lifetimet lifetime, const source_locationt &loc, const select_pointer_typet &pointer_type_selector, message_handlert &log)
Similar to gen_nondet_init below, but instead of allocating and non-deterministically initializing th...
Definition: java_object_factory.cpp:1547
variable_sensitivity_dependence_domaint::control_dependencies
void control_dependencies(const irep_idt &from_function, goto_programt::const_targett from, const irep_idt &to_function, goto_programt::const_targett to, variable_sensitivity_dependence_grapht &dep_graph)
Definition: variable_sensitivity_dependence_graph.cpp:204
cfg_dominators_templatet::nodet::dominators
target_sett dominators
Definition: cfg_dominators.h:43
variable_sensitivity_dependence_domaint::eval_data_deps
void eval_data_deps(const exprt &expr, const namespacet &ns, data_depst &deps) const
Evaluate an expression and accumulate all the data dependencies involved in the evaluation.
Definition: variable_sensitivity_dependence_graph.cpp:27
cfg_dominators_templatet::get_node
const cfgt::nodet & get_node(const T &program_point) const
Get the graph node (which gives dominators, predecessors and successors) for program_point.
Definition: cfg_dominators.h:53
variable_sensitivity_dependence_domaint::has_changed
bool has_changed
Definition: variable_sensitivity_dependence_graph.h:165
variable_sensitivity_domaint::transform
void transform(const irep_idt &function_from, trace_ptrt trace_from, const irep_idt &function_to, trace_ptrt trace_to, ai_baset &ai, const namespacet &ns) override
Compute the abstract transformer for a single instruction.
Definition: variable_sensitivity_domain.cpp:23
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:222
irept::id
const irep_idt & id() const
Definition: irep.h:396
message_handlert
Definition: message.h:27
grapht::nodes
nodest nodes
Definition: graph.h:176
tvt::unknown
static tvt unknown()
Definition: threeval.h:33
code_function_callt::argumentst
exprt::operandst argumentst
Definition: goto_instruction_code.h:281
jsont::make_array
json_arrayt & make_array()
Definition: json.h:420
variable_sensitivity_dependence_grapht
Definition: variable_sensitivity_dependence_graph.h:217
data_dependency_context.h
tvt::is_false
bool is_false() const
Definition: threeval.h:26
std_code.h
location_sensitive_storaget
The most conventional storage; one domain per location.
Definition: ai_storage.h:152
variable_sensitivity_dependence_grapht::cfg_post_dominators
post_dominators_mapt & cfg_post_dominators()
Definition: variable_sensitivity_dependence_graph.h:272
tvt
Definition: threeval.h:19
variable_sensitivity_dependence_domaint::control_depst
std::map< goto_programt::const_targett, tvt > control_depst
Definition: variable_sensitivity_dependence_graph.h:182
side_effect_exprt::get_statement
const irep_idt & get_statement() const
Definition: std_code.h:1472
variable_sensitivity_dependence_domaint::merge_control_dependencies
bool merge_control_dependencies(const control_depst &other_control_deps, const control_dep_candidatest &other_control_dep_candidates, const control_dep_callst &other_control_dep_calls, const control_dep_callst &other_control_dep_call_candidates)
Definition: variable_sensitivity_dependence_graph.cpp:314
variable_sensitivity_dependence_domaint::populate_dep_graph
void populate_dep_graph(variable_sensitivity_dependence_grapht &, goto_programt::const_targett) const
Definition: variable_sensitivity_dependence_graph.cpp:593
goto_functionst
A collection of goto functions.
Definition: goto_functions.h:24
ai_domain_baset::locationt
goto_programt::const_targett locationt
Definition: ai_domain.h:73
ai_domain_factoryt
Definition: ai_domain.h:196
variable_sensitivity_dependence_domaint::output_json
jsont output_json(const ai_baset &ai, const namespacet &ns) const override
Outputs the current value of the domain.
Definition: variable_sensitivity_dependence_graph.cpp:540
container_utils.h
variable_sensitivity_dependence_domaint::has_values
tvt has_values
Definition: variable_sensitivity_dependence_graph.h:164
variable_sensitivity_dependence_domain_factoryt
This ensures that all domains are constructed with the node ID that links them to the graph part of t...
Definition: variable_sensitivity_dependence_graph.cpp:610
ai_baset
This is the basic interface of the abstract interpreter with default implementations of the core func...
Definition: ai.h:118
variable_sensitivity_domaint
Definition: variable_sensitivity_domain.h:116
json.h
goto_programt
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:72
variable_sensitivity_dependence_domaint
Definition: variable_sensitivity_dependence_graph.h:70
ai_domain_factory_baset::locationt
ai_domain_baset::locationt locationt
Definition: ai_domain.h:171
goto_programt::const_targett
instructionst::const_iterator const_targett
Definition: goto_program.h:587
variable_sensitivity_domaint::merge
virtual bool merge(const variable_sensitivity_domaint &b, trace_ptrt from, trace_ptrt to)
Computes the join between "this" and "b".
Definition: variable_sensitivity_domain.cpp:225
exprt::operands
operandst & operands()
Definition: expr.h:94
cfg_dominators_templatet::nodet
Definition: cfg_dominators.h:41
ai_domain_baset
The interface offered by a domain, allows code to manipulate domains without knowing their exact type...
Definition: ai_domain.h:54
variable_sensitivity_dependence_domaint::merge_three_way_function_return
void merge_three_way_function_return(const ai_domain_baset &function_call, const ai_domain_baset &function_start, const ai_domain_baset &function_end, const namespacet &ns) override
Perform a context aware merge of the changes that have been applied between function_start and the cu...
Definition: variable_sensitivity_dependence_graph.cpp:448
cfg_dominators_templatet::cfg
cfgt cfg
Definition: cfg_dominators.h:47
from_expr
std::string from_expr(const namespacet &ns, const irep_idt &identifier, const exprt &expr)
Definition: language_util.cpp:38
variable_sensitivity_dependence_domaint::transform
void transform(const irep_idt &function_from, trace_ptrt trace_from, const irep_idt &function_to, trace_ptrt trace_to, ai_baset &ai, const namespacet &ns) override
Compute the abstract transformer for a single instruction.
Definition: variable_sensitivity_dependence_graph.cpp:68
json_arrayt::push_back
jsont & push_back(const jsont &json)
Definition: json.h:212
variable_sensitivity_dependence_domaint::control_dep_calls
control_dep_callst control_dep_calls
Definition: variable_sensitivity_dependence_graph.h:189
side_effect_exprt
An expression containing a side effect.
Definition: std_code.h:1449
validation_modet::INVARIANT
@ INVARIANT
variable_sensitivity_dependence_grapht::get_state
virtual statet & get_state(locationt l)
Definition: variable_sensitivity_dependence_graph.h:224
variable_sensitivity_dependence_domaint::control_dep_candidates
control_dep_candidatest control_dep_candidates
Definition: variable_sensitivity_dependence_graph.h:186
variable_sensitivity_dependence_domaint::control_dep_call_candidates
control_dep_callst control_dep_call_candidates
Definition: variable_sensitivity_dependence_graph.h:190
cfg_dominators_templatet
Dominator graph.
Definition: cfg_dominators.h:36
json_stringt
Definition: json.h:269