Esempio n. 1
0
/*
 * Insert a looping path (usually an accelerator) into a goto-program,
 * beginning at loop_header and jumping back to loop_header via back_jump.
 * Stores the locations at which the looping path was added in inserted_path.
 *
 * THIS DESTROYS looping_path!!
 */
void acceleratet::insert_looping_path(
  goto_programt::targett &loop_header,
  goto_programt::targett &back_jump,
  goto_programt &looping_path,
  patht &inserted_path)
{
  goto_programt::targett loop_body=loop_header;
  ++loop_body;

  goto_programt::targett jump=program.insert_before(loop_body);
  jump->make_goto();
  jump->guard=side_effect_expr_nondett(bool_typet());
  jump->targets.push_back(loop_body);

  program.destructive_insert(loop_body, looping_path);

  jump=program.insert_before(loop_body);
  jump->make_goto();
  jump->guard=true_exprt();
  jump->targets.push_back(back_jump);

  for(goto_programt::targett t=loop_header;
      t!=loop_body;
      ++t)
  {
    inserted_path.push_back(path_nodet(t));
  }

  inserted_path.push_back(path_nodet(back_jump));
}
Esempio n. 2
0
void all_paths_enumeratort::extend_path(patht &path,
    goto_programt::targett t,
    int succ) {
  goto_programt::targett next;
  goto_programt::targetst succs;
  exprt guard = true_exprt();

  goto_program.get_successors(t, succs);

  for (goto_programt::targetst::iterator it = succs.begin();
       it != succs.end();
       ++it) {
    if (succ == 0) {
      next = *it;
      break;
    }

    succ--;
  }

  if (t->is_goto()) {
    guard = not_exprt(t->guard);

    for (goto_programt::targetst::iterator it = t->targets.begin();
         it != t->targets.end();
         ++it) {
      if (next == *it) {
        guard = t->guard;
        break;
      }
    }
  }

  path.push_back(path_nodet(next, guard));
}
bool all_paths_enumeratort::next(patht &path)
{
  if(last_path.empty())
  {
    // This is the first time we've been called -- build an initial
    // path.
    last_path.push_back(path_nodet(loop_header));

    // This shouldn't be able to fail.
    complete_path(last_path, 0);

    if(is_looping(last_path))
    {
      // If this was a loop path, we're good.  If it wasn't,
      // we'll keep enumerating paths until we hit a looping one.
      // This case is exactly the same as if someone just called
      // next() on us.
      path.clear();
      path.insert(path.begin(), last_path.begin(), last_path.end());
      return true;
    }
  }

  do
  {
#ifdef DEBUG
    std::cout << "Enumerating next path...\n";
#endif

    int decision=backtrack(last_path);
    complete_path(last_path, decision);

    if(is_looping(last_path))
    {
      path.clear();
      path.insert(path.begin(), last_path.begin(), last_path.end());
      return true;
    }
  }
  while(!last_path.empty());

  // We've enumerated all the paths.
  return false;
}
void disjunctive_polynomial_accelerationt::build_path(
    scratch_programt &scratch_program, patht &path) {
  goto_programt::targett t = loop_header;

  do {
    goto_programt::targett next;
    goto_programt::targetst succs;

    goto_program.get_successors(t, succs);

    // We should have a looping path, so we should never hit a location
    // with no successors.
    assert(succs.size() > 0);

    if (succs.size() == 1) {
      // Only one successor -- accumulate it and move on.
      path.push_back(path_nodet(t));
      t = succs.front();
      continue;
    }

    // We have multiple successors.  Examine the distinguisher variables
    // to see which branch was taken.
    bool found_branch = false;

    for (goto_programt::targetst::iterator it = succs.begin();
         it != succs.end();
         ++it) {
      exprt &distinguisher = distinguishing_points[*it];
      bool taken = scratch_program.eval(distinguisher).is_true();

      if (taken) {
        if (!found_branch ||
            ((*it)->location_number < next->location_number)) {
          next = *it;
        }

        found_branch = true;
      }
    }

    assert(found_branch);

    exprt cond = nil_exprt();

    if (t->is_goto()) {
      // If this was a conditional branch (it probably was), figure out
      // if we hit the "taken" or "not taken" branch & accumulate the
      // appropriate guard.
      cond = not_exprt(t->guard);

      for (goto_programt::targetst::iterator it = t->targets.begin();
           it != t->targets.end();
           ++it) {
        if (next == *it) {
          cond = t->guard;
          break;
        }
      }
    }

    path.push_back(path_nodet(t, cond));

    t = next;
  } while (t != loop_header && (loop.find(t) != loop.end()));
}