CBMC
dfcc_cfg_info.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Dynamic frame condition checking for function and loop contracts.
4 
5 Author: Qinheping Hu, qinhh@amazon.com
6 Author: Remi Delmas delmasrd@amazon.com
7 
8 Date: March 2023
9 
10 \*******************************************************************/
11 
16 
17 #ifndef CPROVER_GOTO_INSTRUMENT_CONTRACTS_DYNAMIC_FRAMES_DFCC_CFG_INFO_H
18 #define CPROVER_GOTO_INSTRUMENT_CONTRACTS_DYNAMIC_FRAMES_DFCC_CFG_INFO_H
19 
20 #include <util/namespace.h>
21 #include <util/std_expr.h>
22 #include <util/symbol_table.h>
23 
26 
28 
29 #include <map>
30 #include <set>
31 #include <unordered_set>
32 
33 class dfcc_libraryt;
34 class goto_functiont;
35 class message_handlert;
36 
40 {
41 public:
43  std::size_t loop_id,
44  std::size_t cbmc_loop_id,
45  const std::set<exprt> &assigns,
48  const std::unordered_set<irep_idt> &local,
49  const std::unordered_set<irep_idt> &tracked,
50  std::set<std::size_t> inner_loops,
51  std::set<std::size_t> outer_loops,
54  : loop_id(loop_id),
59  local(local),
65  {
66  }
67 
69  void output(std::ostream &out) const;
70 
96  std::optional<goto_programt::targett>
97  find_head(goto_programt &goto_program) const;
98 
99  // Finds the last instruction tagged as loop latch and having the same loop
100  // identifier as this struct in the given program. The goto program passed as
101  // argument to this method must be the program from which that dfcc_loop_infot
102  // instance was initially generated. Technically it will not be the exact same
103  // program because the whole point of contract instrumentation is to
104  // instrument the program into a different program by adding new instructions
105  // in the program and turning loops into non-loops. For an explanation of why
106  // this would work please read the documentation of find head, and mentally
107  // replace `head` by `latch` and `start` by `end` in the explanation.
108  std::optional<goto_programt::targett>
109  find_latch(goto_programt &goto_program) const;
110 
112  const std::size_t loop_id;
113 
115  const std::size_t cbmc_loop_id;
116 
118  const std::set<exprt> assigns;
119 
122 
125 
128  const std::unordered_set<irep_idt> local;
129 
133  const std::unordered_set<irep_idt> tracked;
134 
136  const std::set<std::size_t> inner_loops;
137 
139  const std::set<std::size_t> outer_loops;
140 
143 
148 
151  const bool must_skip() const
152  {
153  return invariant.is_nil() && decreases.empty();
154  }
155 };
156 
243 {
244 public:
246  goto_modelt &goto_model,
247  const irep_idt &function_id,
249  const exprt &top_level_write_set,
250  const loop_contract_configt &loop_contract_config,
251  symbol_table_baset &symbol_table,
252  message_handlert &message_handler,
253  dfcc_libraryt &library);
254 
255  void output(std::ostream &out) const;
256 
258  const dfcc_loop_infot &get_loop_info(const std::size_t loop_id) const;
259 
263  const exprt &get_write_set(goto_programt::const_targett target) const;
264 
267  const std::unordered_set<irep_idt> &
269 
272  const std::unordered_set<irep_idt> &
274 
277  const exprt &get_outer_write_set(std::size_t loop_id) const;
278 
279  const std::vector<std::size_t> &get_loops_toposorted() const
280  {
281  return topsorted_loops;
282  }
283 
286  std::size_t
287  get_first_id_not_skipped_or_top_level_id(const std::size_t loop_id) const;
288 
291  const std::optional<std::size_t>
292  get_outer_loop_identifier(const std::size_t loop_id) const;
293 
297 
303  bool must_check_lhs(goto_programt::const_targett target) const;
304 
306  {
307  return top_level_write_set;
308  }
309 
312  const std::unordered_set<irep_idt> &get_top_level_tracked()
313  {
314  return top_level_tracked;
315  }
316 
317 private:
321  const namespacet ns;
322 
325  bool is_valid_loop_or_top_level_id(const std::size_t id) const;
326 
328  bool is_valid_loop_id(const std::size_t id) const;
329 
331  bool is_top_level_id(const std::size_t id) const;
332 
334  size_t top_level_id() const;
335 
337  std::vector<std::size_t> topsorted_loops;
338 
341  std::vector<std::size_t> top_level_loops;
342 
344  std::unordered_set<irep_idt> top_level_local;
345 
347  std::unordered_set<irep_idt> top_level_tracked;
348 
350  std::map<std::size_t, dfcc_loop_infot> loop_info_map;
351 };
352 
353 #endif
Computes natural loops, enforces normal form conditions, computes the nesting graph,...
const std::optional< std::size_t > get_outer_loop_identifier(const std::size_t loop_id) const
Finds the DFCC id of the loop that contains the given loop, returns nullopt when the loop has no oute...
const std::vector< std::size_t > & get_loops_toposorted() const
const std::unordered_set< irep_idt > & get_top_level_tracked()
Returns the set of top level symbols that must be tracked explicitly in the top level write set of th...
std::unordered_set< irep_idt > top_level_local
Set of identifiers DECL at top level.
const exprt & top_level_write_set
std::size_t get_first_id_not_skipped_or_top_level_id(const std::size_t loop_id) const
Returns the id of the first outer loop (including this one) that is not skipped, or the top level id.
const namespacet ns
std::vector< std::size_t > topsorted_loops
Loop identifiers sorted from most deeply nested to less deeply nested.
std::unordered_set< irep_idt > top_level_tracked
Set of identifiers DECL at top level.
bool is_top_level_id(const std::size_t id) const
True iff id is in the valid range for a loop id for this function.
const dfcc_loop_infot & get_loop_info(const std::size_t loop_id) const
Returns the loop info for that loop_id.
void output(std::ostream &out) const
goto_functiont & goto_function
std::vector< std::size_t > top_level_loops
Loop identifiers for top level loops (ie for loops that are not nested in in another loop).
const std::unordered_set< irep_idt > & get_tracked_set(goto_programt::const_targett target) const
Returns the subset of local variable that are explicitly tracked in the write set for the scope where...
dfcc_cfg_infot(goto_modelt &goto_model, const irep_idt &function_id, goto_functiont &goto_function, const exprt &top_level_write_set, const loop_contract_configt &loop_contract_config, symbol_table_baset &symbol_table, message_handlert &message_handler, dfcc_libraryt &library)
bool must_check_lhs(goto_programt::const_targett target) const
True iff the lhs of an assignment must be checked against the ambient write set.
const std::unordered_set< irep_idt > & get_local_set(goto_programt::const_targett target) const
Returns the set of local variable for the scope where that target instruction is found.
const exprt & get_outer_write_set(std::size_t loop_id) const
Returns the write set of the outer loop of that loop or the top level write set if that loop has no o...
const exprt & get_write_set(goto_programt::const_targett target) const
Returns the write set variable to use for the given instruction Returns the write set for the loop,...
const exprt & get_top_level_write_set() const
bool must_track_decl_or_dead(goto_programt::const_targett target) const
True iff a DECL ident must be tracked in the write set of the loop that contains the DECL.
size_t top_level_id() const
Returns the top level ID.
bool is_valid_loop_id(const std::size_t id) const
True iff id is in the valid range for a loop id for this function.
const irep_idt & function_id
std::map< std::size_t, dfcc_loop_infot > loop_info_map
Map from loop identifier to loop info struct.
bool is_valid_loop_or_top_level_id(const std::size_t id) const
True iff id is in the valid range for a loop id or is equal to the top level id for this function.
Class interface to library types and functions defined in cprover_contracts.c.
Definition: dfcc_library.h:154
Describes a single loop for the purpose of DFCC loop contract instrumentation.
Definition: dfcc_cfg_info.h:40
const symbol_exprt addr_of_write_set_var
Symbol representing pointer to the stack allocated write set object for this loop.
void output(std::ostream &out) const
Prints a textual representation of the struct to out.
const exprt::operandst decreases
Decreases clause expression.
const std::unordered_set< irep_idt > local
Set of local identifiers locally DECL in loop instructions, excluding identifiers declared in nested ...
const std::set< exprt > assigns
Set of targets assigned by the loop, either user-provided or inferred.
const std::size_t cbmc_loop_id
Loop identifier assigned to this loop by traditional CBMC loop numbering.
std::optional< goto_programt::targett > find_latch(goto_programt &goto_program) const
const std::unordered_set< irep_idt > tracked
Subset of locals that must be tracked in the loop's write set.
dfcc_loop_infot(std::size_t loop_id, std::size_t cbmc_loop_id, const std::set< exprt > &assigns, exprt invariant, exprt::operandst decreases, const std::unordered_set< irep_idt > &local, const std::unordered_set< irep_idt > &tracked, std::set< std::size_t > inner_loops, std::set< std::size_t > outer_loops, symbol_exprt write_set_var, symbol_exprt addr_of_write_set_var)
Definition: dfcc_cfg_info.h:42
const std::size_t loop_id
Loop identifier assigned by DFCC to this loop.
const exprt invariant
Loop invariant expression.
const bool must_skip() const
Returns true if the loop has no invariant and no decreases clause and its instrumentation must be ski...
const std::set< std::size_t > outer_loops
Integer identifier of the outer loop(s) if they exists.
const std::set< std::size_t > inner_loops
Integer identifiers of inner loops of that loop.
std::optional< goto_programt::targett > find_head(goto_programt &goto_program) const
Finds the first instruction tagged as loop head and having the same loop identifier as this struct in...
const symbol_exprt write_set_var
Symbol representing the stack-allocated write set object for this loop.
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
std::vector< exprt > operandst
Definition: expr.h:58
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
Definition: goto_function.h:24
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
bool is_nil() const
Definition: irep.h:368
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
Expression to hold a symbol (variable)
Definition: std_expr.h:131
The symbol table base class interface.
Symbol Table + CFG.
Concrete Goto Program.
Config for loop contract.
API to expression classes.
Loop contract configurations.
Author: Diffblue Ltd.