void WherePostcondition::PrintHook(OutStream &out) const { BlockId *id = m_frame->CFG()->GetId(); Variable *func_var = id->BaseVar(); PEdge *edge = m_frame->CFG()->GetSingleOutgoingEdge(m_point); if (edge->IsLoop()) { PEdgeLoop *nedge = edge->AsLoop(); out << nedge->GetLoopId()->Loop()->Value() << " " << func_var->GetName()->Value(); } else { PEdgeCall *nedge = edge->AsCall(); if (Variable *callee = nedge->GetDirectFunction()) { // direct call, just one hook function. out << "post " << callee->GetName()->Value(); } else { // indirect call, one hook function for each callee. CallEdgeSet *callees = CalleeCache.Lookup(func_var); bool found_callee = false; if (callees) { for (size_t eind = 0; eind < callees->GetEdgeCount(); eind++) { const CallEdge &edge = callees->GetEdge(eind); if (edge.where.id == id && edge.where.point == m_point) { if (found_callee) out << "$"; // add the separator found_callee = true; out << "post " << edge.callee->GetName()->Value(); } } } CalleeCache.Release(func_var); } } }
// assign the final names to all loops within cfg. loop naming is done after // the CFGs have been finalized as it depends on the topo ordering of points. static void FillLoopNames(BlockCFG *cfg, const char *prefix, const Vector<BlockCFG*> &cfg_list) { size_t found_loops = 0; for (size_t eind = 0; eind < cfg->GetEdgeCount(); eind++) { PEdgeLoop *edge = cfg->GetEdge(eind)->IfLoop(); if (!edge) continue; BlockId *loop = edge->GetLoopId(); // check for a duplicate. there can be multiple summary edges for // a loop if we reduced some irreducible loops or if there are // isomorphic points in the outer body of a nested loop. if (loop->WriteLoop() != NULL) continue; char name_buf[100]; snprintf(name_buf, sizeof(name_buf), "%s#%d", prefix, (int) found_loops); String *write_name = String::Make(name_buf); loop->SetWriteLoop(write_name); found_loops++; // recurse on the CFG for the loop itself, to get any nested loops. bool found = false; for (size_t ind = 0; ind < cfg_list.Size(); ind++) { if (cfg_list[ind]->GetId() == loop) { Assert(!found); found = true; FillLoopNames(cfg_list[ind], name_buf, cfg_list); } } Assert(found); } }