void unified_difft::output_diff( const irep_idt &identifier, const goto_programt &old_goto_program, const goto_programt &new_goto_program, const differencest &differences, std::ostream &os) const { goto_program_difft diff; get_diff( identifier, old_goto_program, new_goto_program, differences, diff); bool has_diff=false; for(const auto &d : diff) { if(d.second!=differencet::SAME) { has_diff=true; break; } } if(!has_diff) return; os << "/** " << identifier << " **/\n"; for(const auto &d : diff) { switch(d.second) { case differencet::SAME: os << ' '; new_goto_program.output_instruction( ns_new, identifier, os, d.first); break; case differencet::DELETED: os << '-'; old_goto_program.output_instruction( ns_old, identifier, os, d.first); break; case differencet::NEW: os << '+'; new_goto_program.output_instruction( ns_new, identifier, os, d.first); break; } } }
void output_path( const patht &path, const goto_programt &program, const namespacet &ns, std::ostream &str) { for(const auto &step : path) program.output_instruction(ns, "path", str, step.loc); }
void loop_transformt::transform_do_while( goto_programt &program, goto_programt::targett &begin, goto_programt::targett &end) const { if(!end->guard.is_true()) { #if 0 std::cout << "TRANSFORM DO-WHILE" << std::endl; #endif goto_programt::targett next = end; next++; assert(next!=program.instructions.end()); goto_programt::instructiont newguard; newguard.make_goto(next); newguard.guard = end->guard; newguard.guard.make_not(); newguard.location = end->location; end->guard.make_true(); unsigned ln = end->location_number; // doesn't get swapped program.insert_before_swap(end, newguard); // end now points to the new guard goto_programt::targett old_guard = end; old_guard++; end->location_number=ln; old_guard->location_number=ln; program.update(); #if 0 std::cout << "Transformed: " << std::endl; goto_programt::const_targett it = begin; for (; it!=end; it++) program.output_instruction(ns, "", std::cout, it); program.output_instruction(ns, "", std::cout, it); #endif } }
void loop_transformt::split_multi_head( goto_programt &program, goto_programt::targett begin, goto_programt::targett end) { #if 0 std::cout << "SPLIT MULTI-HEAD (" << begin->incoming_edges.size() << ")" << std::endl; #endif unsigned dontmatter = 0; goto_programt::targett prev = begin; prev--; forall_incoming_edges(it, begin) { if((*it)==prev) dontmatter++; else if((*it)==end) dontmatter++; } if(begin->incoming_edges.size() > dontmatter) { #if 0 std::cout << "Splitting " << begin->incoming_edges.size() << "-head" << std::endl; #endif goto_programt::targett newskip = program.insert_before(begin); newskip->make_skip(); newskip->location_number = begin->location_number; newskip->function = begin->function; newskip->location = begin->location; // redirect gotos forall_incoming_edges(it, begin) { const goto_programt::targett &from = *it; if(from!=prev && from!=end && from->is_goto() && from->targets.front()==begin) // gotos right before the loop // aren't necessarily jumping to begin { assert(from->targets.size()==1); from->targets.clear(); from->targets.push_back(newskip); } } program.update(); #if 0 namespacet ns(context); std::cout << "Split loop: " << std::endl; goto_programt::const_targett it = newskip; for (; it!=end; it++) program.output_instruction(ns, "", std::cout, it); program.output_instruction(ns, "", std::cout, it); #endif assert(begin->incoming_edges.size()<=2); }