コード例 #1
0
ファイル: summary.cpp プロジェクト: wh5a/xgill
void BlockSummary::ComputeAssertNames()
{
  BlockCFG *cfg = GetBlockCFG(m_id);
  Assert(cfg);

  // the assertion names need the filename of the containing function.
  Location *loc = cfg->GetPointLocation(cfg->GetEntryPoint());

  // keep track of the last kind/index to be generated for an assertion.
  // the index space should be different for each assertion kind so that
  // different assertions do not interfere with one another. we can get this
  // with a simple counter because the assertions are sorted by kind.
  AssertKind last_kind = ASK_None;
  size_t last_index = 0;

  for (size_t ind = 0; m_assert_list && ind < m_assert_list->Size(); ind++) {
    AssertInfo &info = m_assert_list->At(ind);
    Assert(!info.name_buf);

    // only compute indexes for assertions which need to be checked.
    if (info.cls != ASC_Check) continue;

    // reset the index if this is a new kind of assertion.
    if (info.kind != last_kind) {
      last_kind = info.kind;
      last_index = 0;
    }
    last_index++;

    info.name_buf = new Buffer(256);
    BufferOutStream out(info.name_buf);

    out << AssertKindString(last_kind) << "$"
        << loc->FileName()->Value() << "$"
        << m_id->Function()->Value() << "$"
        << (m_id->Kind() == B_Loop ? m_id->Loop()->Value() : "func") << "$"
        << last_index << '\0';
  }

  cfg->DecRef();
}
コード例 #2
0
ファイル: loopsplit.cpp プロジェクト: wh5a/xgill
// split a single loop from the existing body. this creates a new CFG
// with cloned points and edges for the loop's execution, and fixes up
// the points and edges in base_cfg to add a Loop() summary edge and remove
// the CFG cycle.
BlockCFG* SplitSingleLoop(PPoint loophead, const Vector<PPoint> &all_loops,
                          BlockCFG *base_cfg)
{
    // make a temporary name for the loop.
    char loop_name[100];
    snprintf(loop_name, sizeof(loop_name), "scratch#%d", loophead);

    Variable *function_info = base_cfg->GetId()->BaseVar();

    // make an ID for the split loop.
    function_info->IncRef();
    String *loop_info = String::Make(loop_name);
    BlockId *loop_id = BlockId::Make(B_Loop, function_info, loop_info);

    // make a CFG for the split loop.
    BlockCFG *loop_cfg = BlockCFG::Make(loop_id);
    CopyCFGLocationsVariables(base_cfg, loop_cfg);

    PPointListHash remapping;
    Vector<size_t> old_entry_indexes;
    Vector<size_t> old_exit_indexes;
    Vector<size_t> old_back_indexes;

    CloneLoopBody(base_cfg, loophead, &remapping, loop_cfg,
                  &old_entry_indexes, &old_exit_indexes, &old_back_indexes);

    // fixup the old CFG first. we need to perform the following steps:
    // - create a new point with a Loop() edge going to the head.
    // - add the new point to the body of any loop also containing the head.
    // - change all loop entry edges to go to the new point instead of the head.
    // - delete all backedges on the loop by pointing them to point 0.

    Location *loop_head_loc = base_cfg->GetPointLocation(loophead);

    loop_head_loc->IncRef();
    PPoint summary_point = base_cfg->AddPoint(loop_head_loc);

    loop_id->IncRef();
    PEdge *summary_edge = PEdge::MakeLoop(summary_point, loophead, loop_id);
    base_cfg->AddEdge(summary_edge);

    // mark the new summary point as being reachable from the entry point.
    entry_reach_table->Insert(summary_point);

    // add the new summary point to the body of any other loop which
    // already contains the head of this loop in its body.
    for (size_t lind = 0; lind < all_loops.Size(); lind++) {
        if (body_table->Lookup(PPointPair(all_loops[lind], loophead))) {
            body_table->Insert(PPointPair(all_loops[lind], summary_point));
            body_list_table->Insert(all_loops[lind], summary_point);
        }
    }

    for (size_t oind = 0; oind < old_entry_indexes.Size(); oind++) {
        size_t entry_index = old_entry_indexes[oind];
        PEdge *old_edge = base_cfg->GetEdge(entry_index);

        PPoint source = old_edge->GetSource();
        Assert(old_edge->GetTarget() == loophead);

        PEdge *new_edge = PEdge::ChangeEdge(old_edge, source, summary_point);
        base_cfg->SetEdge(entry_index, new_edge);
    }

    for (size_t oind = 0; oind < old_back_indexes.Size(); oind++) {
        size_t back_index = old_back_indexes[oind];
        PEdge *old_edge = base_cfg->GetEdge(back_index);

        PPoint source = old_edge->GetSource();
        Assert(old_edge->GetTarget() == loophead);

        PEdge *new_edge = PEdge::ChangeEdge(old_edge, source, 0);
        base_cfg->SetEdge(back_index, new_edge);
    }

    // fixup the new CFG second. we need to perform the following steps:
    // - mark the cloned head as the entry point.
    // - create a new point as the exit point.
    // - for each backedge in the original loop, redirect to the exit point.

    PPoint split_entry = remapping.LookupSingle(loophead);

    // find the exit location associated with this loop head, if there is one.
    size_t headind = 0;
    for (; headind < base_cfg->GetLoopHeadCount(); headind++) {
        if (base_cfg->GetLoopHead(headind).point == loophead)
            break;
    }
    Assert(headind < base_cfg->GetLoopHeadCount());
    Location *end_location = base_cfg->GetLoopHead(headind).end_location;

    // if there isn't an end location (goto loop in the original source),
    // just use the location of the loop head itself.
    if (!end_location)
        end_location = loop_head_loc;

    end_location->IncRef();
    PPoint split_exit = loop_cfg->AddPoint(end_location);

    for (size_t oind = 0; oind < old_back_indexes.Size(); oind++) {
        size_t back_index = old_back_indexes[oind];
        PEdge *old_edge = base_cfg->GetEdge(back_index);

        PPoint source = old_edge->GetSource();

        // we should have already dropped the target of this edge.
        Assert(old_edge->GetTarget() == 0);

        PPoint new_source = remapping.LookupSingle(source);
        PEdge *new_edge = PEdge::ChangeEdge(old_edge, new_source, split_exit);
        loop_cfg->AddEdge(new_edge);
    }

    // set the entry/exit points of the loop CFG.
    loop_cfg->SetEntryPoint(split_entry);
    loop_cfg->SetExitPoint(split_exit);

    // trim any unreachable portions of the loop CFG, collapse skips
    // and sort the points.
    TrimUnreachable(loop_cfg, true);
    TopoSortCFG(loop_cfg);

    // set the end location of the loop to the point in the body with the
    // highest line number. the GCC frontend does not have information
    // about the end location of loop bodies.
    Location *highest = end_location;
    for (PPoint point = 1; point <= loop_cfg->GetPointCount(); point++) {
        Location *loc = loop_cfg->GetPointLocation(point);
        if (loc->FileName() == highest->FileName() && loc->Line() > highest->Line())
            highest = loc;
    }
    highest->IncRef();
    loop_cfg->SetPointLocation(loop_cfg->GetExitPoint(), highest);

    return loop_cfg;
}