CBMC
variable_sensitivity_dependence_graph.h
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 
12 #ifndef CPROVER_ANALYSES_VARIABLE_SENSITIVITY_VARIABLE_SENSITIVITY_DEPENDENCE_GRAPH_H
13 #define CPROVER_ANALYSES_VARIABLE_SENSITIVITY_VARIABLE_SENSITIVITY_DEPENDENCE_GRAPH_H
14 
17 
19 #include <util/graph.h>
20 
21 #include <ostream>
22 
24 
26 {
27 public:
28  enum class kindt
29  {
30  NONE,
31  CTRL,
32  DATA,
33  BOTH
34  };
35 
36  void add(kindt _kind)
37  {
38  switch(kind)
39  {
40  case kindt::NONE:
41  kind = _kind;
42  break;
43  case kindt::DATA:
44  case kindt::CTRL:
45  if(kind != _kind)
46  kind = kindt::BOTH;
47  break;
48  case kindt::BOTH:
49  break;
50  }
51  }
52 
53  kindt get() const
54  {
55  return kind;
56  }
57 
58 protected:
60 };
61 
62 struct vs_dep_nodet : public graph_nodet<vs_dep_edget>
63 {
66 
68 };
69 
72 {
73 public:
75 
77  node_indext id,
79  const vsd_configt &configuration)
81  node_id(id),
82  has_values(false),
83  has_changed(false)
84  {
85  }
86 
87  void transform(
88  const irep_idt &function_from,
89  trace_ptrt trace_from,
90  const irep_idt &function_to,
91  trace_ptrt trace_to,
92  ai_baset &ai,
93  const namespacet &ns) override;
94 
95  void make_bottom() override
96  {
98  has_values = tvt(false);
99  has_changed = false;
100  domain_data_deps.clear();
101  control_deps.clear();
102  control_dep_candidates.clear();
103  control_dep_calls.clear();
105  }
106 
107  void make_top() override
108  {
110  has_values = tvt(true);
111  has_changed = false;
112  domain_data_deps.clear();
113  control_deps.clear();
114  control_dep_candidates.clear();
115  control_dep_calls.clear();
117  }
118 
119  bool is_bottom() const override
120  {
122  }
123 
124  bool is_top() const override
125  {
127  }
128 
129  bool merge(
131  trace_ptrt from,
132  trace_ptrt to) override;
133 
135  const ai_domain_baset &function_start,
136  const ai_domain_baset &function_end,
137  const namespacet &ns) override;
138 
139  void output(std::ostream &out, const ai_baset &ai, const namespacet &ns)
140  const override;
141 
142  jsont output_json(const ai_baset &ai, const namespacet &ns) const override;
143 
144  void populate_dep_graph(
147 
149  {
151  node_id != std::numeric_limits<node_indext>::max(),
152  "Check for the old uninitialised value");
153  return node_id;
154  }
155 
156 private:
160 
162  {
163  public:
166  const goto_programt::const_targett &b) const
167  {
168  return a->location_number < b->location_number;
169  }
170  };
171  typedef std::
172  map<goto_programt::const_targett, std::set<exprt>, dependency_ordert>
175 
176  typedef std::
177  map<goto_programt::const_targett, tvt, goto_programt::target_less_than>
180 
181  typedef std::
182  set<goto_programt::const_targett, goto_programt::target_less_than>
185 
186  typedef std::
187  set<goto_programt::const_targett, goto_programt::target_less_than>
191 
192  void eval_data_deps(const exprt &expr, const namespacet &ns, data_depst &deps)
193  const;
194 
196  const irep_idt &from_function,
198  const irep_idt &to_function,
201 
202  void data_dependencies(
206  const namespacet &ns);
207 
209  const control_depst &other_control_deps,
210  const control_dep_candidatest &other_control_dep_candidates,
211  const control_dep_callst &other_control_dep_calls,
212  const control_dep_callst &other_control_dep_call_candidates);
213 };
214 
216 
218  public grapht<vs_dep_nodet>
219 {
220 protected:
221  using ai_baset::get_state;
222 
223  // Legacy-style mutable access to the storage
225  {
226  auto &s = dynamic_cast<location_sensitive_storaget &>(*storage);
227  return s.get_state(l, *domain_factory);
228  }
229 
231  {
232  return dynamic_cast<variable_sensitivity_dependence_domaint &>(
233  get_state(l));
234  }
235 
236 public:
238 
240 
241  typedef std::map<irep_idt, cfg_post_dominatorst> post_dominators_mapt;
242 
245  const namespacet &_ns,
247  const vsd_configt &_configuration,
249 
250  void
251  initialize(const irep_idt &function_id, const goto_programt &goto_program)
252  {
253  ai_recursive_interproceduralt::initialize(function_id, goto_program);
254  }
255 
256  void finalize()
257  {
258  for(const auto &location_state :
259  static_cast<location_sensitive_storaget &>(*storage).internal())
260  {
261  std::static_pointer_cast<variable_sensitivity_dependence_domaint>(
262  location_state.second)
263  ->populate_dep_graph(*this, location_state.first);
264  }
265  }
266 
267  void add_dep(
268  vs_dep_edget::kindt kind,
271 
273  {
274  return post_dominators;
275  }
276 
277 protected:
281  const namespacet &ns;
282 
284 };
285 
286 // NOLINTNEXTLINE(whitespace/line_length)
287 #endif // CPROVER_ANALYSES_VARIABLE_SENSITIVITY_VARIABLE_SENSITIVITY_DEPENDENCE_GRAPH_H
std::shared_ptr< variable_sensitivity_object_factoryt > variable_sensitivity_object_factory_ptrt
Compute dominators for CFG of goto_function.
This is the basic interface of the abstract interpreter with default implementations of the core func...
Definition: ai.h:117
goto_programt::const_targett locationt
Definition: ai.h:124
message_handlert & message_handler
Definition: ai.h:521
std::unique_ptr< ai_domain_factory_baset > domain_factory
For creating domain objects.
Definition: ai.h:494
virtual void initialize(const irep_idt &function_id, const goto_programt &goto_program)
Initialize all the abstract states for a single function.
Definition: ai.cpp:194
virtual statet & get_state(trace_ptrt p)
Get the state for the given history, creating it with the factory if it doesn't exist.
Definition: ai.h:515
The interface offered by a domain, allows code to manipulate domains without knowing their exact type...
Definition: ai_domain.h:54
ai_history_baset::trace_ptrt trace_ptrt
Definition: ai_domain.h:73
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:38
Base class for all expressions.
Definition: expr.h:56
A collection of goto functions.
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:73
instructionst::const_iterator const_targett
Definition: goto_program.h:615
This class represents a node in a directed graph.
Definition: graph.h:35
A generic directed graph with a parametric node type.
Definition: graph.h:167
Definition: json.h:27
The most conventional storage; one domain per location.
Definition: ai_storage.h:154
statet & get_state(trace_ptrt p, const ai_domain_factory_baset &fac) override
Look up the analysis state for a given history, instantiating a new domain if required.
Definition: ai_storage.h:193
state_mapt & internal(void)
Definition: ai_storage.h:169
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
Definition: threeval.h:20
bool is_false() const
Definition: threeval.h:26
bool is_true() const
Definition: threeval.h:25
This ensures that all domains are constructed with the node ID that links them to the graph part of t...
bool operator()(const goto_programt::const_targett &a, const goto_programt::const_targett &b) const
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)
void populate_dep_graph(variable_sensitivity_dependence_grapht &, goto_programt::const_targett) const
std::map< goto_programt::const_targett, tvt, goto_programt::target_less_than > control_depst
std::map< goto_programt::const_targett, std::set< exprt >, dependency_ordert > data_depst
std::set< goto_programt::const_targett, goto_programt::target_less_than > control_dep_candidatest
std::set< goto_programt::const_targett, goto_programt::target_less_than > control_dep_callst
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.
void make_top() override
all states – the analysis doesn't use this directly (see make_entry) and domains may refuse to implem...
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.
void merge_three_way_function_return(const ai_domain_baset &function_start, const ai_domain_baset &function_end, const namespacet &ns) override
Merges just the things that have changes between "function_start" and "function_end" into "this".
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)
bool merge(const variable_sensitivity_domaint &b, trace_ptrt from, trace_ptrt to) override
Computes the join between "this" and "b".
variable_sensitivity_dependence_domaint(node_indext id, variable_sensitivity_object_factory_ptrt object_factory, const vsd_configt &configuration)
void output(std::ostream &out, const ai_baset &ai, const namespacet &ns) const override
Basic text output of the abstract domain.
void data_dependencies(goto_programt::const_targett from, goto_programt::const_targett to, variable_sensitivity_dependence_grapht &dep_graph, const namespacet &ns)
jsont output_json(const ai_baset &ai, const namespacet &ns) const override
Outputs the current value of the domain.
std::map< irep_idt, cfg_post_dominatorst > post_dominators_mapt
void initialize(const irep_idt &function_id, const goto_programt &goto_program)
Initialize all the abstract states for a single function.
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)
variable_sensitivity_dependence_domaint & operator[](locationt l)
void finalize()
Override this to add a cleanup or post-processing step after fixedpoint has run.
void add_dep(vs_dep_edget::kindt kind, goto_programt::const_targett from, goto_programt::const_targett to)
virtual statet & get_state(trace_ptrt p)
Get the state for the given history, creating it with the factory if it doesn't exist.
Definition: ai.h:515
void make_bottom() override
Sets the domain to bottom (no states / unreachable).
void make_top() override
Sets the domain to top (all states).
bool is_bottom() const override
Find out if the domain is currently unreachable.
bool is_top() const override
Is the domain completely top at this state.
A Template Class for Graphs.
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...
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:534
graph_nodet< vs_dep_edget >::edgest edgest
graph_nodet< vs_dep_edget >::edget edget
goto_programt::const_targett PC
An abstract interpreter, based on the default recursive-interprocedural that uses variable sensitivit...
There are different ways of handling arrays, structures, unions and pointers.