Beispiel #1
0
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
}
Beispiel #2
0
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();
}