CBMC
Loading...
Searching...
No Matches
all_paths_enumerator.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Loop Acceleration
4
5Author: Matt Lewis
6
7\*******************************************************************/
8
11
13
15{
16 if(last_path.empty())
17 {
18 // This is the first time we've been called -- build an initial
19 // path.
21
22 // This shouldn't be able to fail.
24
26 {
27 // If this was a loop path, we're good. If it wasn't,
28 // we'll keep enumerating paths until we hit a looping one.
29 // This case is exactly the same as if someone just called
30 // next() on us.
31 path.clear();
32 path.insert(path.begin(), last_path.begin(), last_path.end());
33 return true;
34 }
35 }
36
37 do
38 {
39#ifdef DEBUG
40 std::cout << "Enumerating next path...\n";
41#endif
42
45
47 {
48 path.clear();
49 path.insert(path.begin(), last_path.begin(), last_path.end());
50 return true;
51 }
52 }
53 while(!last_path.empty());
54
55 // We've enumerated all the paths.
56 return false;
57}
58
60{
61 // If we have a path of length 1 or 0, we can't backtrack any further.
62 // That means we're done enumerating paths!
63 if(path.size()<2)
64 {
65 path.clear();
66 return 0;
67 }
68
69 goto_programt::targett node_loc=path.back().loc;
70 path.pop_back();
71
72 goto_programt::targett parent_loc=path.back().loc;
74
75 unsigned int ret=0;
76
77 for(const auto &succ : succs)
78 {
79 if(succ==node_loc)
80 break;
81
82 ret++;
83 }
84
85 if((ret+1)<succs.size())
86 {
87 // We can take the next branch here...
88
89#ifdef DEBUG
90 std::cout << "Backtracked to a path of size " << path.size() << '\n';
91#endif
92
93 return ret+1;
94 }
95
96 // Recurse.
97 return backtrack(path);
98}
99
101{
102 if(path.empty())
103 return;
104
105 goto_programt::targett node_loc=path.back().loc;
106 extend_path(path, node_loc, succ);
107
108 goto_programt::targett end=path.back().loc;
109
110 if(end == loop_header || !loop.contains(end))
111 return;
112
113 complete_path(path, 0);
114}
115
117 patht &path,
119 int succ)
120{
123
124 for(const auto &s : goto_program.get_successors(t))
125 {
126 if(succ==0)
127 {
128 next=s;
129 break;
130 }
131
132 succ--;
133 }
134
135 if(t->is_goto())
136 {
137 guard = not_exprt(t->condition());
138
139 for(goto_programt::targetst::iterator it=t->targets.begin();
140 it != t->targets.end();
141 ++it)
142 {
143 if(next == *it)
144 {
145 guard = t->condition();
146 break;
147 }
148 }
149 }
150
151 path.push_back(path_nodet(next, guard));
152}
153
155{
156 return path.size()>1 && path.back().loc==loop_header;
157}
Loop Acceleration.
static exprt guard(const exprt::operandst &guards, exprt cond)
virtual void clear()
Reset the abstract state.
Definition ai.h:265
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
natural_loops_mutablet::natural_loopt & loop
virtual bool next(patht &path)
void complete_path(patht &path, int succ)
goto_programt::targett loop_header
void extend_path(patht &path, goto_programt::targett t, int succ)
Base class for all expressions.
Definition expr.h:56
instructionst::iterator targett
std::list< Target > get_successors(Target target) const
Get control-flow successors of a given instruction.
Boolean negation.
Definition std_expr.h:2454
The Boolean constant true.
Definition std_expr.h:3190
std::list< path_nodet > patht
Definition path.h:44