20
20
#include < analyses/goto_rw.h>
21
21
22
22
#include < goto-programs/remove_skip.h>
23
+ #include < goto-programs/cfg.h>
23
24
24
25
// debug
25
26
#ifdef DEBUG_ABSTRACT_LOOPS
26
27
#include " iostream"
27
- #include < util/expr_iterator.h>
28
28
#endif
29
29
30
30
class abstract_loopst
@@ -43,6 +43,8 @@ class abstract_loopst
43
43
dependence_grapht dep_graph (_ns);
44
44
// data structures initialization
45
45
dep_graph (goto_model.goto_functions , _ns);
46
+ // build the CFG data structure
47
+ cfg (goto_model.goto_functions );
46
48
// call main function
47
49
abstract_loops (goto_model, dep_graph, target_loop_map);
48
50
}
@@ -53,8 +55,8 @@ class abstract_loopst
53
55
// target abstract loop number for each function
54
56
loop_mapt target_loop_map;
55
57
// set of all leaf dependency nodes for loop variables
56
- nodeset leaf_nodes;
57
- nodeset update_nodes;
58
+ // nodeset leaf_nodes;
59
+ // nodeset update_nodes;
58
60
// current function
59
61
irep_idt fn;
60
62
// map from instruction line # to the set of loops it belongs to
@@ -65,6 +67,18 @@ class abstract_loopst
65
67
typedef dep_graph_domaint::depst depst;
66
68
// name space for program
67
69
const namespacet ns;
70
+ // cfg
71
+ struct cfg_nodet
72
+ {
73
+ cfg_nodet ():node_required(false )
74
+ {
75
+ }
76
+
77
+ bool node_required;
78
+ };
79
+
80
+ typedef cfg_baset<cfg_nodet> cfgt;
81
+ cfgt cfg;
68
82
69
83
// functions in this class
70
84
void abstract_loops (goto_modelt &goto_model,
@@ -75,7 +89,8 @@ class abstract_loopst
75
89
76
90
void update_shrinkability (unsigned loc, irep_idt func);
77
91
78
- void check_assertion (unsigned location, const dependence_grapht &dep_graph);
92
+ void check_assertion (unsigned location, const dependence_grapht &dep_graph,
93
+ const goto_functionst &goto_functions);
79
94
80
95
void abstract_goto_program (unsigned loop_num,
81
96
const dependence_grapht &dep_graph,
@@ -185,6 +200,7 @@ class abstract_loopst
185
200
}; // end of class abstract_loopst
186
201
187
202
203
+ #ifdef DEBUG_ABSTRACT_LOOPS
188
204
// / print out nodes in set
189
205
void print_nodes (abstract_loopst::nodeset &node_set)
190
206
{
@@ -198,6 +214,7 @@ void print_nodes(abstract_loopst::nodeset &node_set)
198
214
}
199
215
std::cout << ' \n ' ;
200
216
}
217
+ #endif
201
218
202
219
// / Do the abstraction on goto program (modify goto program)
203
220
// / \param loop_num: target loop number
@@ -241,16 +258,10 @@ void abstract_loopst::abstract_goto_program(unsigned loop_num,
241
258
f_it = goto_functions.function_map .find (fn);
242
259
i_it = f_it->second .body .instructions .begin ();
243
260
std::advance (i_it, loop_info->init_loc - i_it->location_number );
244
-
245
- // init values can be nondet
246
- const code_assignt &code_assign = to_code_assign (i_it->code );
247
- if (!(code_assign.rhs ().id () == ID_side_effect))
248
- {
249
- expr = i_it->code ;
250
- expr.id (is_inc ? ID_ge : ID_le);
251
- expr.type ().id (ID_bool);
252
- i_it->make_assumption (expr);
253
- }
261
+ expr = i_it->code ;
262
+ expr.id (is_inc ? ID_ge : ID_le);
263
+ expr.type ().id (ID_bool);
264
+ i_it->make_assumption (expr);
254
265
255
266
// change loop head into assumption, skip goto at loop end
256
267
loop_info->build_assumption ();
@@ -276,7 +287,7 @@ void abstract_loopst::update_shrinkability(unsigned loc, irep_idt func)
276
287
// / \param location: line number for assertion
277
288
// / \param dep_graph: dependency graph for the program
278
289
void abstract_loopst::check_assertion (unsigned location,
279
- const dependence_grapht &dep_graph)
290
+ const dependence_grapht &dep_graph, const goto_functionst &goto_functions )
280
291
{
281
292
#ifdef DEBUG_ABSTRACT_LOOPS
282
293
std::cout << " Check assertion at: " << location << " \n " ;
@@ -339,6 +350,18 @@ void abstract_loopst::check_assertion(unsigned location,
339
350
print_nodes (update_set);
340
351
#endif
341
352
353
+ // node set
354
+ nodeset leaf_nodes;
355
+ nodeset update_nodes;
356
+ for (auto loop_n: insloop_map[location])
357
+ {
358
+ irep_idt func = dep_graph[location].PC ->function ;
359
+ abstract_loopt *loop_info = &(absloop_map[func].find (loop_n)->second );
360
+ leaf_nodes.insert (loop_info->var_leaves .begin (),
361
+ loop_info->var_leaves .end ());
362
+ update_nodes.insert (loop_info->var_updates .begin (),
363
+ loop_info->var_updates .end ());
364
+ }
342
365
// check dependence of leaf set
343
366
nodeset diff;
344
367
std::set_difference (leaf_set.begin (), leaf_set.end (),
@@ -358,13 +381,39 @@ void abstract_loopst::check_assertion(unsigned location,
358
381
{
359
382
if (is_in_cycle (loc, dep_graph))
360
383
{
361
- update_shrinkability (loc, dep_graph[loc].PC ->function );
384
+ nodeset entry_set;
385
+ std::queue<unsigned > entry_queue;
386
+ add_to_queue (entry_set, entry_queue, loc);
387
+ while (!entry_queue.empty ())
388
+ {
389
+ unsigned node = entry_queue.front ();
390
+ entry_queue.pop ();
391
+ update_shrinkability (node, dep_graph[node].PC ->function );
392
+ // check loops calling this function call
393
+ goto_functionst::function_mapt::const_iterator f_it=
394
+ goto_functions.function_map .find (dep_graph[node].PC ->function );
395
+
396
+ goto_programt::const_targett begin_function=
397
+ f_it->second .body .instructions .begin ();
398
+
399
+ cfgt::entry_mapt::const_iterator entry=
400
+ cfg.entry_map .find (begin_function);
401
+ if (entry!=cfg.entry_map .end ())
402
+ {
403
+ for (cfgt::edgest::const_iterator
404
+ it=cfg[entry->second ].in .begin ();
405
+ it!=cfg[entry->second ].in .end ();
406
+ ++it)
407
+ {
408
+ add_to_queue (entry_set, entry_queue, it->first );
409
+ }
410
+ }
411
+ }
362
412
}
363
413
else
364
414
{
365
415
// check if the update depends on loop variable
366
416
const goto_programt::instructiont &inst = *(dep_graph[loc].PC );
367
- std::cout << " check location " << loc << " type " << inst.type << " \n " ;
368
417
if (!inst.is_assign ())
369
418
continue ;
370
419
value_setst &value_sets=
@@ -496,34 +545,34 @@ void abstract_loopst::get_loop_info(
496
545
return ;
497
546
}
498
547
548
+ // This is for SVcomp cases where values can be nondet
549
+ const code_assignt &code_assign =
550
+ to_code_assign (dep_graph[loop_info.init_loc ].PC ->code );
551
+ if (code_assign.rhs ().id () == ID_side_effect)
552
+ {
553
+ #ifdef DEBUG_ABSTRACT_LOOPS
554
+ std::cout << " Unshrinkable: Loop variable init to nondet\n " ;
555
+ #endif
556
+ return ;
557
+ }
558
+
499
559
#ifdef DEBUG_ABSTRACT_LOOPS
500
560
std::cout << " Leaf dependency nodes for loop variable: " ;
501
561
print_nodes (loop_info.var_leaves );
502
562
std::cout << " Update node for loop variable: " ;
503
563
print_nodes (loop_info.var_updates );
504
564
#endif
505
565
506
- // // This is for SVcomp cases where values can be nondet
507
- // const code_assignt &code_assign =
508
- // to_code_assign(dep_graph[loop_info.init_loc].PC->code);
509
- // if(code_assign.rhs().id() == ID_side_effect)
510
- // {
511
- // #ifdef DEBUG_ABSTRACT_LOOPS
512
- // std::cout << "Unshrinkable: Loop variable init to nondet\n";
513
- // #endif
514
- // return;
515
- // }
516
-
517
566
// add to the instruction # -> loop # map
518
567
// unsafe with function call, further check when doing abstraction
519
568
for (unsigned n = head->location_number ;
520
569
n <= last->location_number ; n++)
521
570
insloop_map[n].insert (last->loop_number );
522
571
523
572
absloop_map[fn].insert (loopnum_pair (last->loop_number , loop_info));
524
- leaf_nodes.insert (loop_info.var_leaves .begin (), loop_info.var_leaves .end ());
525
- update_nodes.insert (loop_info.var_updates .begin (),
526
- loop_info.var_updates .end ());
573
+ // leaf_nodes.insert(loop_info.var_leaves.begin(), loop_info.var_leaves.end());
574
+ // update_nodes.insert(loop_info.var_updates.begin(),
575
+ // loop_info.var_updates.end());
527
576
}
528
577
529
578
// / Main function for abstraction, has 3 iterations to
@@ -557,7 +606,8 @@ void abstract_loopst::abstract_loops(goto_modelt &goto_model,
557
606
Forall_goto_program_instructions (i_it, it->second .body )
558
607
{
559
608
if (i_it->is_assert ())
560
- check_assertion (i_it->location_number , dep_graph);
609
+ check_assertion (i_it->location_number , dep_graph,
610
+ goto_model.goto_functions );
561
611
}
562
612
}
563
613
}
0 commit comments