|
| 1 | +/* |
| 2 | + * aggressive_slicer.cpp |
| 3 | + * |
| 4 | + * Created on: 18 Jun 2018 |
| 5 | + * Author: polgreen |
| 6 | + */ |
| 7 | + |
| 8 | +#include "aggressive_slicer.h" |
| 9 | +#include "remove_function.h" |
| 10 | +#include <analyses/call_graph_helpers.h> |
| 11 | +#include <goto-programs/goto_model.h> |
| 12 | +#include <goto-programs/show_properties.h> |
| 13 | +#include <util/message.h> |
| 14 | + |
| 15 | +void aggressive_slicert::slice_for_function(irep_idt destination_function) |
| 16 | +{ |
| 17 | + if(preserve_all_direct_paths) |
| 18 | + { |
| 19 | + /// Note that we have previously disconnected all nodes unreachable |
| 20 | + /// from the start function, |
| 21 | + /// which means that any reaching functions are also reachable from |
| 22 | + /// the start function. |
| 23 | + for(const auto &func : |
| 24 | + get_reaching_functions(call_graph, destination_function)) |
| 25 | + functions_to_keep.insert(func); |
| 26 | + } |
| 27 | + else |
| 28 | + { |
| 29 | + for(const auto &func : get_shortest_function_path( |
| 30 | + call_graph, start_function, destination_function)) |
| 31 | + functions_to_keep.insert(func); |
| 32 | + } |
| 33 | +} |
| 34 | + |
| 35 | +void aggressive_slicert::get_all_functions_containing_properties() |
| 36 | +{ |
| 37 | + for(const auto &fct : goto_model.goto_functions.function_map) |
| 38 | + { |
| 39 | + if(!fct.second.is_inlined()) |
| 40 | + { |
| 41 | + for(const auto &ins : fct.second.body.instructions) |
| 42 | + if(ins.is_assert()) |
| 43 | + slice_for_function(ins.function); |
| 44 | + } |
| 45 | + } |
| 46 | +} |
| 47 | + |
| 48 | +void aggressive_slicert::find_functions_that_contain_name_snippet() |
| 49 | +{ |
| 50 | + for(const auto &name_snippet : name_snippets) |
| 51 | + { |
| 52 | + forall_goto_functions(f_it, goto_model.goto_functions) |
| 53 | + { |
| 54 | + if(id2string(f_it->first).find(name_snippet) != std::string::npos) |
| 55 | + functions_to_keep.insert(f_it->first); |
| 56 | + } |
| 57 | + } |
| 58 | +} |
| 59 | + |
| 60 | +void aggressive_slicert::doit() |
| 61 | +{ |
| 62 | + messaget message(message_handler); |
| 63 | + |
| 64 | + functions_to_keep.insert(CPROVER_PREFIX "initialize"); |
| 65 | + functions_to_keep.insert(start_function); |
| 66 | + |
| 67 | + // Necessary to compute cone of influence |
| 68 | + if(preserve_all_direct_paths) |
| 69 | + disconnect_unreachable_functions(call_graph, start_function); |
| 70 | + |
| 71 | + // if no properties are specified, preserve all functions containing |
| 72 | + // any property |
| 73 | + if(user_specified_properties.empty()) |
| 74 | + { |
| 75 | + message.debug() << "No properties given, so aggressive slicer " |
| 76 | + << "is running over all possible properties" |
| 77 | + << messaget::eom; |
| 78 | + get_all_functions_containing_properties(); |
| 79 | + } |
| 80 | + |
| 81 | + // if a name snippet is given, get list of all functions containing |
| 82 | + // name snippet to preserve |
| 83 | + if(!name_snippets.empty()) |
| 84 | + find_functions_that_contain_name_snippet(); |
| 85 | + |
| 86 | + for(const auto &p : user_specified_properties) |
| 87 | + { |
| 88 | + auto property_loc = find_property(p, goto_model.goto_functions); |
| 89 | + if(!property_loc.has_value()) |
| 90 | + throw "unable to find property in call graph"; |
| 91 | + slice_for_function(property_loc.value().get_function()); |
| 92 | + } |
| 93 | + |
| 94 | + // Add functions within distance of shortest path functions |
| 95 | + // to the list |
| 96 | + if(call_depth != 0) |
| 97 | + { |
| 98 | + for(const auto &func : get_functions_reachable_within_n_steps( |
| 99 | + call_graph, functions_to_keep, call_depth, true)) |
| 100 | + functions_to_keep.insert(func); |
| 101 | + } |
| 102 | + |
| 103 | + message.debug() << "Preserving the following functions \n"; |
| 104 | + for(const auto &func : functions_to_keep) |
| 105 | + message.debug() << func << messaget::eom; |
| 106 | + |
| 107 | + forall_goto_functions(f_it, goto_model.goto_functions) |
| 108 | + { |
| 109 | + if(functions_to_keep.find(f_it->first) == functions_to_keep.end()) |
| 110 | + remove_function(goto_model, f_it->first, message_handler); |
| 111 | + } |
| 112 | +} |
0 commit comments