CBMC
synthesizer_utils.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Utility functions for loop invariant synthesizer.
4 
5 Author: Qinheping Hu
6 
7 \*******************************************************************/
8 
9 #include "synthesizer_utils.h"
10 
12  const goto_programt::const_targett &loop_head,
14 {
15  goto_programt::const_targett loop_end = loop_head;
16  for(const auto &t : loop)
17  {
18  // an instruction is the loop end if it is a goto instruction
19  // and it jumps backward to the loop head
20  if(
21  t->is_goto() && t->get_target() == loop_head &&
22  t->location_number > loop_end->location_number)
23  loop_end = t;
24  }
25  INVARIANT(
26  loop_head != loop_end,
27  "Could not find end of the loop starting at: " +
28  loop_head->source_location().as_string());
29 
30  return loop_end;
31 }
32 
34  const goto_programt::targett &loop_head,
36 {
37  goto_programt::targett loop_end = loop_head;
38  for(const auto &t : loop)
39  {
40  // an instruction is the loop end if it is a goto instruction
41  // and it jumps backward to the loop head
42  if(
43  t->is_goto() && t->get_target() == loop_head &&
44  t->location_number > loop_end->location_number)
45  loop_end = t;
46  }
47  INVARIANT(
48  loop_head != loop_end,
49  "Could not find end of the loop starting at: " +
50  loop_head->source_location().as_string());
51 
52  return loop_end;
53 }
54 
56  const unsigned int target_loop_number,
57  goto_functiont &function,
58  bool finding_head)
59 {
60  natural_loops_mutablet natural_loops(function.body);
61 
62  // iterate over all natural loops to find the loop with `target_loop_number`
63  for(const auto &loop_p : natural_loops.loop_map)
64  {
65  const goto_programt::targett loop_head = loop_p.first;
66  goto_programt::targett loop_end =
67  get_loop_end_from_loop_head_and_content_mutable(loop_head, loop_p.second);
68  // check if the current loop is the target loop by comparing loop number
69  if(loop_end->loop_number == target_loop_number)
70  {
71  if(finding_head)
72  return loop_head;
73  else
74  return loop_end;
75  }
76  }
77 
79 }
80 
82 get_loop_end(const unsigned int target_loop_number, goto_functiont &function)
83 {
84  return get_loop_head_or_end(target_loop_number, function, false);
85 }
86 
88 get_loop_head(const unsigned int target_loop_number, goto_functiont &function)
89 {
90  return get_loop_head_or_end(target_loop_number, function, true);
91 }
92 
94  const invariant_mapt &invariant_map,
95  goto_modelt &goto_model,
96  messaget &log)
97 {
98  for(const auto &invariant_map_entry : invariant_map)
99  {
100  loop_idt loop_id = invariant_map_entry.first;
101  irep_idt function_id = loop_id.function_id;
102  unsigned int loop_number = loop_id.loop_number;
103 
104  // get the last instruction of the target loop
105  auto &function = goto_model.goto_functions.function_map[function_id];
106  goto_programt::targett loop_end = get_loop_end(loop_number, function);
107 
108  // annotate the invariant to the condition of `loop_end`
109  exprt condition = loop_end->condition();
110  loop_end->condition_nonconst().add(ID_C_spec_loop_invariant) =
111  invariant_map_entry.second;
112  }
113 }
messaget
Class that provides messages with a built-in verbosity 'level'.
Definition: message.h:154
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
get_loop_head_or_end
goto_programt::targett get_loop_head_or_end(const unsigned int target_loop_number, goto_functiont &function, bool finding_head)
Return loop head if finding_head is true, Otherwise return loop end.
Definition: synthesizer_utils.cpp:55
exprt
Base class for all expressions.
Definition: expr.h:55
goto_modelt
Definition: goto_model.h:25
get_loop_end_from_loop_head_and_content
goto_programt::const_targett get_loop_end_from_loop_head_and_content(const goto_programt::const_targett &loop_head, const loop_templatet< goto_programt::const_targett > &loop)
Definition: synthesizer_utils.cpp:11
get_loop_head
goto_programt::targett get_loop_head(const unsigned int target_loop_number, goto_functiont &function)
Find and return the first instruction of the natural loop with loop_number in function.
Definition: synthesizer_utils.cpp:88
goto_functionst::function_map
function_mapt function_map
Definition: goto_functions.h:29
synthesizer_utils.h
loop_templatet
A loop, specified as a set of instructions.
Definition: loop_analysis.h:23
goto_functiont
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
Definition: goto_function.h:23
natural_loops_templatet< goto_programt, goto_programt::targett >
invariant_mapt
std::map< loop_idt, exprt > invariant_mapt
Definition: synthesizer_utils.h:19
irept::add
irept & add(const irep_idt &name)
Definition: irep.cpp:116
annotate_invariants
void annotate_invariants(const invariant_mapt &invariant_map, goto_modelt &goto_model, messaget &log)
Annotate the invariants in invariant_map to their corresponding loops.
Definition: synthesizer_utils.cpp:93
goto_modelt::goto_functions
goto_functionst goto_functions
GOTO functions.
Definition: goto_model.h:33
loop_idt::loop_number
unsigned int loop_number
Definition: loop_ids.h:35
get_loop_end
goto_programt::targett get_loop_end(const unsigned int target_loop_number, goto_functiont &function)
Find and return the last instruction of the natural loop with loop_number in function.
Definition: synthesizer_utils.cpp:82
get_loop_end_from_loop_head_and_content_mutable
goto_programt::targett get_loop_end_from_loop_head_and_content_mutable(const goto_programt::targett &loop_head, const loop_templatet< goto_programt::targett > &loop)
Find the goto instruction of loop that jumps to loop_head
Definition: synthesizer_utils.cpp:33
goto_programt::const_targett
instructionst::const_iterator const_targett
Definition: goto_program.h:587
loop_idt::function_id
irep_idt function_id
Definition: loop_ids.h:34
INVARIANT
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition: invariant.h:423
goto_programt::targett
instructionst::iterator targett
Definition: goto_program.h:586
loop_idt
Loop id used to identify loops.
Definition: loop_ids.h:27
loop_analysist::loop_map
loop_mapt loop_map
Definition: loop_analysis.h:88