goto_programt::targett insert_before_preserve_labels(goto_programt &body, const goto_programt::targett &target) { const goto_programt::targett result=body.insert_before(target); move_labels(body, target, result); return result; }
void loop_transformt::move_returns( goto_programt &program, goto_programt::targett begin, goto_programt::targett end) { goto_programt::targett postend = end; postend++; std::list<goto_programt::targett> returns; for(goto_programt::targett it = begin; it!=end; it++) { if(it->is_return()) returns.push_back(it); } if(returns.size()>0) { for(std::list<goto_programt::targett>::const_iterator it = returns.begin(); it!=returns.end(); it++) { goto_programt::targett newret = program.insert_before(postend); newret->swap(**it); newret->location_number = postend->location_number; (*it)->make_goto(newret); // this creates far exits, // which will be fixed lateron } // fix the loop exit goto_programt::targett firstafter = end; firstafter++; goto_programt::targett loopexit = program.insert_before(firstafter); loopexit->make_goto(postend); program.update(); } }
void stack_depth( goto_programt &goto_program, const symbol_exprt &symbol, const int i_depth, const exprt &max_depth) { assert(!goto_program.instructions.empty()); goto_programt::targett first=goto_program.instructions.begin(); binary_relation_exprt guard(symbol, ID_le, max_depth); goto_programt::targett assert_ins=goto_program.insert_before(first); assert_ins->make_assertion(guard); assert_ins->location=first->location; assert_ins->function=first->function; assert_ins->location.set_comment("Stack depth exceeds "+i2string(i_depth)); assert_ins->location.set_property("stack-depth"); goto_programt::targett plus_ins=goto_program.insert_before(first); plus_ins->make_assignment(); plus_ins->code=code_assignt(symbol, plus_exprt(symbol, from_integer(1, symbol.type()))); plus_ins->location=first->location; plus_ins->function=first->function; goto_programt::targett last=--goto_program.instructions.end(); assert(last->is_end_function()); goto_programt::instructiont minus_ins; minus_ins.make_assignment(); minus_ins.code=code_assignt(symbol, minus_exprt(symbol, from_integer(1, symbol.type()))); minus_ins.location=last->location; minus_ins.function=last->function; goto_program.insert_before_swap(last, minus_ins); }
static bool skip_loops( goto_programt &goto_program, const loop_idst &loop_ids, messaget &message) { loop_idst::const_iterator l_it=loop_ids.begin(); Forall_goto_program_instructions(it, goto_program) { if(l_it==loop_ids.end()) break; if(!it->is_backwards_goto()) continue; const unsigned loop_id=it->loop_number; if(*l_it<loop_id) break; // error handled below if(*l_it>loop_id) continue; goto_programt::targett loop_head=it->get_target(); goto_programt::targett next=it; ++next; assert(next!=goto_program.instructions.end()); goto_programt::targett g=goto_program.insert_before(loop_head); g->make_goto(next, true_exprt()); g->source_location=loop_head->source_location; g->function=loop_head->function; ++l_it; } if(l_it!=loop_ids.end()) { message.error() << "Loop " << *l_it << " not found" << messaget::eom; return true; } return false; }
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); }