44 for(
const auto &t : loop)
47 t->is_goto() && t->condition().is_true() && t->targets.size() == 1 &&
48 t->targets.front() == loop_header &&
49 t->location_number > back_jump->location_number)
63 for(
const auto &t : loop)
65 if(t->is_backwards_goto())
67 if(t->targets.size()!=1 ||
68 t->get_target()!=loop_header)
86 pathst loop_paths, exit_paths;
88 int num_accelerated=0;
89 std::list<path_acceleratort> accelerators;
97 std::cout <<
"Not accelerating an outer loop\n";
133 std::cout <<
"Not inserting accelerator because of underapproximation\n";
139 accelerators.push_back(accelerator);
143 std::cout <<
"Accelerated path:\n";
146 std::cout <<
"Accelerator has "
148 <<
" instructions\n";
160 std::cout <<
"Overflow loc is " << overflow_loc->location_number <<
'\n';
161 std::cout <<
"Back jump is " << back_jump->location_number <<
'\n';
163 for(std::list<path_acceleratort>::iterator it=accelerators.begin();
164 it!=accelerators.end();
174 return num_accelerated;
207 patht &inserted_path)
231 inserted_path.push_back(
path_nodet(back_jump));
245 for(
const auto &loop_instruction : loop)
251 for(
const auto &new_instruction : added)
258 t->swap(*loop_header);
263 overflow_loc->swap(*loop_end);
273 overflow_loc=loop_end;
281 for(subsumed_pathst::iterator it=
subsumed.begin();
285 if(!it->subsumed.empty())
289 std::cout <<
"Restricting path:\n";
296 patht double_accelerator;
297 patht::iterator jt=double_accelerator.begin();
298 double_accelerator.insert(
299 jt, it->accelerator.begin(), it->accelerator.end());
300 double_accelerator.insert(
301 jt, it->accelerator.begin(), it->accelerator.end());
305 std::cout <<
"Restricting path:\n";
308 automaton.
add_path(double_accelerator);
311 std::cout <<
"Building trace automaton...\n";
319 for(std::set<exprt>::iterator it=accelerator.
dirty_vars.begin();
335 dirty_var=jt->second;
339 std::cout <<
"Setting dirty flag " <<
format(dirty_var) <<
" for "
373 const exprt &lhs = it->assign_lhs();
386 std::set<symbol_exprt>
read;
388 if(it->has_condition())
394 for(
const auto &var :
read)
412 for(std::set<exprt>::iterator it=accelerator.
dirty_vars.begin();
416 if(it->id()==ID_symbol && it->type() ==
bool_typet())
428 std::cout <<
"Underapproximate variable: " <<
format(*it) <<
'\n';
439 ret.module=
"accelerate";
441 ret.pretty_name=name;
483 <<
"Inserting trace automaton with "
485 << accept_states.size() <<
" accepting states and "
486 << transitions.size() <<
" transitions\n";
496 for(
const auto &sym : automaton.
alphabet)
510 trace_automatont::sym_mapt::iterator begin,
511 trace_automatont::sym_mapt::iterator end,
517 std::map<unsigned int, unsigned int> successor_counts;
518 unsigned int max_count=0;
519 unsigned int likely_next=0;
524 for(trace_automatont::sym_mapt::iterator p=begin; p!=end; ++p)
527 unsigned int to=state_pair.second;
528 unsigned int count=0;
530 if(successor_counts.find(to)==successor_counts.end())
536 count=successor_counts[to] + 1;
539 successor_counts[to]=count;
541 if(count > max_count)
550 if(successor_counts.size()==1)
552 if(accept_states.find(likely_next)!=accept_states.end())
559 state_machine.
assign(state,
566 state_machine.
assign(next_state,
569 for(trace_automatont::sym_mapt::iterator p=begin; p!=end; ++p)
572 unsigned int from=state_pair.first;
573 unsigned int to=state_pair.second;
591 state_machine.
assign(next_state, rhs);
595 state_machine.
assign(state, next_state);
597 for(state_sett::iterator it=accept_states.begin();
598 it!=accept_states.end();
608 int num_accelerated=0;
610 for(natural_loops_mutablet::loop_mapt::iterator it =
621 if(num_accelerated > 0)
623 std::cout <<
"Engaging crush mode...\n";
629 std::cout <<
"Crush mode engaged.\n";
632 return num_accelerated;
643 std::cout <<
"Accelerating function " << gf_entry.first <<
'\n';
645 gf_entry.second.body, goto_model, message_handler, use_z3, guard_manager);
649 if(num_accelerated > 0)
651 std::cout <<
"Added " << num_accelerated
652 <<
" accelerator(s)\n";
void accelerate_functions(goto_modelt &goto_model, message_handlert &message_handler, bool use_z3, guard_managert &guard_manager)
static exprt guard(const exprt::operandst &guards, exprt cond)
void insert_accelerator(goto_programt::targett &loop_header, goto_programt::targett &back_jump, path_acceleratort &accelerator, subsumed_patht &subsumed_path)
void insert_automaton(trace_automatont &automaton)
acceleration_utilst utils
symbolt make_symbol(std::string name, typet type)
natural_loops_mutablet natural_loops
message_handlert & message_handler
void decl(symbol_exprt &sym, goto_programt::targett t)
symbol_tablet & symbol_table
bool contains_nested_loops(goto_programt::targett &loop_header)
void build_state_machine(trace_automatont::sym_mapt::iterator p, trace_automatont::sym_mapt::iterator end, state_sett &accept_states, symbol_exprt state, symbol_exprt next_state, scratch_programt &state_machine)
void make_overflow_loc(goto_programt::targett loop_header, goto_programt::targett &loop_end, goto_programt::targett &overflow_loc)
overflow_mapt overflow_locs
void set_dirty_vars(path_acceleratort &accelerator)
goto_functionst & goto_functions
bool is_underapproximate(path_acceleratort &accelerator)
static const int accelerate_limit
goto_programt::targett find_back_jump(goto_programt::targett loop_header)
guard_managert & guard_manager
void insert_looping_path(goto_programt::targett &loop_header, goto_programt::targett &back_jump, goto_programt &looping_path, patht &inserted_path)
int accelerate_loop(goto_programt::targett &loop_header)
symbolt fresh_symbol(std::string base, typet type)
A goto_instruction_codet representing an assignment in the program.
A goto_instruction_codet representing the declaration of a local variable.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
bool accelerate(path_acceleratort &accelerator)
Base class for all expressions.
const source_locationt & source_location() const
typet & type()
Return the type of the expression.
The Boolean constant false.
function_mapt function_map
goto_functionst goto_functions
GOTO functions.
This class represents an instruction in the GOTO intermediate representation.
A generic container class for the GOTO intermediate representation of one function.
static instructiont make_assumption(const exprt &g, const source_locationt &l=source_locationt::nil())
instructionst instructions
The list of instructions in the goto program.
void update()
Update all indices.
void insert_before_swap(targett target)
Insertion that preserves jumps to "target".
void destructive_insert(const_targett target, goto_programt &p)
Inserts the given program p before target.
instructionst::iterator targett
static instructiont make_assignment(const code_assignt &_code, const source_locationt &l=source_locationt::nil())
Create an assignment instruction.
static instructiont make_skip(const source_locationt &l=source_locationt::nil())
targett insert_after(const_targett target)
Insertion after the instruction pointed-to by the given instruction iterator target.
targett add(instructiont &&instruction)
Adds a given instruction at the end.
static instructiont make_goto(targett _target, const source_locationt &l=source_locationt::nil())
targett insert_before(const_targett target)
Insertion before the instruction pointed-to by the given instruction iterator target.
std::list< targett > targetst
The trinary if-then-else operator.
bool is_loop_header(const T instruction) const
Returns true if instruction is the header of any loop.
A loop, specified as a set of instructions.
bool insert_instruction(const T instruction)
Adds instruction to this loop.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
void add_overflow_checks()
goto_programt overflow_path
std::set< exprt > dirty_vars
goto_programt pure_accelerator
targett assume(const exprt &guard)
targett assign(const exprt &lhs, const exprt &rhs)
A side_effect_exprt that returns a non-deterministically chosen value.
Expression to hold a symbol (variable)
const irep_idt & get_identifier() const
const symbolt & lookup_ref(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
bool add(const symbolt &symbol)
Add a new symbol to the symbol table.
irep_idt module
Name of module the symbol belongs to.
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
void get_transitions(sym_mapt &transitions)
void accept_states(state_sett &states)
std::pair< sym_mapt::iterator, sym_mapt::iterator > sym_range_pairt
std::multimap< goto_programt::targett, state_pairt, goto_programt::target_less_than > sym_mapt
std::pair< statet, statet > state_pairt
void add_path(patht &path)
The Boolean constant true.
The type of an expression, extends irept.
const source_locationt & source_location() const
static bool find_symbols(symbol_kindt, const typet &, std::function< bool(const symbol_exprt &)>, std::unordered_set< irep_idt > &bindings, const std::vector< irep_idt > &subs_to_find)
Find identifiers with id ID_symbol of the sub expressions and the subs with ID in subs_to_find consid...
Goto Programs with Functions.
int __CPROVER_ID java::java io InputStream read
Compute natural loops in a goto_function.
void output_path(const patht &path, std::ostream &str)
std::list< patht > pathst
std::list< path_nodet > patht
API to expression classes.
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
This is unused by this implementation of guards, but can be used by other implementations of the same...
std::set< statet > state_sett
unsignedbv_typet unsigned_poly_type()