@@ -110,27 +110,49 @@ bool symex_bmct::get_unwind(
110
110
{
111
111
const irep_idt id=goto_programt::loop_id (*source.pc );
112
112
113
- // We use the most specific limit we have,
114
- // and 'infinity' when we have none.
115
-
113
+ tvt abort_unwind_decision;
116
114
unsigned this_loop_limit=std::numeric_limits<unsigned >::max ();
117
115
118
- loop_limitst &this_thread_limits=
119
- thread_loop_limits[source.thread_nr ];
116
+ for (auto handler : loop_unwind_handlers)
117
+ {
118
+ abort_unwind_decision =
119
+ handler (
120
+ source.pc ->function ,
121
+ source.pc ->loop_number ,
122
+ unwind,
123
+ this_loop_limit);
124
+ if (abort_unwind_decision.is_known ())
125
+ break ;
126
+ }
120
127
121
- loop_limitst::const_iterator l_it=this_thread_limits.find (id);
122
- if (l_it!=this_thread_limits.end ())
123
- this_loop_limit=l_it->second ;
124
- else
128
+ // If no handler gave an opinion, use standard command-line --unwindset
129
+ // / --unwind options to decide:
130
+ if (abort_unwind_decision.is_unknown ())
125
131
{
126
- l_it=loop_limits.find (id);
127
- if (l_it!=loop_limits.end ())
132
+ // We use the most specific limit we have,
133
+ // and 'infinity' when we have none.
134
+
135
+ loop_limitst &this_thread_limits=
136
+ thread_loop_limits[source.thread_nr ];
137
+
138
+ loop_limitst::const_iterator l_it=this_thread_limits.find (id);
139
+ if (l_it!=this_thread_limits.end ())
128
140
this_loop_limit=l_it->second ;
129
- else if (max_unwind_is_set)
130
- this_loop_limit=max_unwind;
141
+ else
142
+ {
143
+ l_it=loop_limits.find (id);
144
+ if (l_it!=loop_limits.end ())
145
+ this_loop_limit=l_it->second ;
146
+ else if (max_unwind_is_set)
147
+ this_loop_limit=max_unwind;
148
+ }
149
+
150
+ abort_unwind_decision = tvt (unwind >= this_loop_limit);
131
151
}
132
152
133
- bool abort =unwind>=this_loop_limit;
153
+ INVARIANT (
154
+ abort_unwind_decision.is_known (), " unwind decision should be taken by now" );
155
+ bool abort = abort_unwind_decision.is_true ();
134
156
135
157
log .statistics () << (abort ? " Not unwinding" : " Unwinding" ) << " loop " << id
136
158
<< " iteration " << unwind;
@@ -149,27 +171,44 @@ bool symex_bmct::get_unwind_recursion(
149
171
const unsigned thread_nr,
150
172
unsigned unwind)
151
173
{
152
- // We use the most specific limit we have,
153
- // and 'infinity' when we have none.
154
-
174
+ tvt abort_unwind_decision;
155
175
unsigned this_loop_limit=std::numeric_limits<unsigned >::max ();
156
176
157
- loop_limitst &this_thread_limits=
158
- thread_loop_limits[thread_nr];
177
+ for (auto handler : recursion_unwind_handlers)
178
+ {
179
+ abort_unwind_decision = handler (id, unwind, this_loop_limit);
180
+ if (abort_unwind_decision.is_known ())
181
+ break ;
182
+ }
159
183
160
- loop_limitst::const_iterator l_it=this_thread_limits.find (id);
161
- if (l_it!=this_thread_limits.end ())
162
- this_loop_limit=l_it->second ;
163
- else
184
+ // If no handler gave an opinion, use standard command-line --unwindset
185
+ // / --unwind options to decide:
186
+ if (abort_unwind_decision.is_unknown ())
164
187
{
165
- l_it=loop_limits.find (id);
166
- if (l_it!=loop_limits.end ())
188
+ // We use the most specific limit we have,
189
+ // and 'infinity' when we have none.
190
+
191
+ loop_limitst &this_thread_limits=
192
+ thread_loop_limits[thread_nr];
193
+
194
+ loop_limitst::const_iterator l_it=this_thread_limits.find (id);
195
+ if (l_it!=this_thread_limits.end ())
167
196
this_loop_limit=l_it->second ;
168
- else if (max_unwind_is_set)
169
- this_loop_limit=max_unwind;
197
+ else
198
+ {
199
+ l_it=loop_limits.find (id);
200
+ if (l_it!=loop_limits.end ())
201
+ this_loop_limit=l_it->second ;
202
+ else if (max_unwind_is_set)
203
+ this_loop_limit=max_unwind;
204
+ }
205
+
206
+ abort_unwind_decision = tvt (unwind>this_loop_limit);
170
207
}
171
208
172
- bool abort =unwind>this_loop_limit;
209
+ INVARIANT (
210
+ abort_unwind_decision.is_known (), " unwind decision should be taken by now" );
211
+ bool abort = abort_unwind_decision.is_true ();
173
212
174
213
if (unwind>0 || abort )
175
214
{
0 commit comments