void loop_transformt::transform(goto_programt &goto_program) { goto_program.compute_incoming_edges(); // pass 1: simple stuff Forall_goto_program_instructions(it, goto_program) if(it->is_backwards_goto()) { assert(it->targets.size()==1); goto_programt::targett begin = it->targets.front(); goto_programt::targett end = it; split_multi_head(goto_program, begin, end); transform_do_while(goto_program, begin, end); move_returns(goto_program, begin, end); } // pass 2: loop simulation Forall_goto_program_instructions(it, goto_program) if(it->is_backwards_goto()) { goto_programt::targett begin = it->targets.front(); goto_programt::targett end = it; std::set<goto_programt::targett> entries; std::set<goto_programt::targett> exits; analyze(goto_program, begin, end, entries, exits); transform(goto_program, begin, end, entries, exits); it=end; } goto_program.update(); #if 1 // Another run for debugging forall_goto_program_instructions(it, goto_program) if(it->is_backwards_goto()) { goto_programt::const_targett begin = it->targets.front(); goto_programt::const_targett end = it; run_checks(goto_program, begin, end); } #endif }
void remove_skip(goto_programt &goto_program) { typedef std::map<goto_programt::targett, goto_programt::targett> new_targetst; new_targetst new_targets; // remove skip statements for(goto_programt::instructionst::iterator it=goto_program.instructions.begin(); it!=goto_program.instructions.end();) { goto_programt::targett old_target=it; // for collecting labels std::list<irep_idt> labels; while(is_skip(it)) { // don't remove the last skip statement, // it could be a target if(it==--goto_program.instructions.end()) break; // save labels labels.splice(labels.end(), it->labels); it++; } goto_programt::targett new_target=it; // save labels it->labels.splice(it->labels.begin(), labels); if(new_target!=old_target) { while(new_target!=old_target) { // remember the old targets new_targets[old_target]=new_target; old_target=goto_program.instructions.erase(old_target); } } else it++; } // adjust gotos Forall_goto_program_instructions(i_it, goto_program) if(i_it->is_goto()) { for(goto_programt::instructiont::targetst::iterator t_it=i_it->targets.begin(); t_it!=i_it->targets.end(); t_it++) { new_targetst::const_iterator result=new_targets.find(*t_it); if(result!=new_targets.end()) *t_it=result->second; } } // remove the last skip statement unless it's a target goto_program.compute_incoming_edges(); if(!goto_program.instructions.empty() && is_skip(--goto_program.instructions.end()) && !goto_program.instructions.back().is_target()) goto_program.instructions.pop_back(); }