void Function::printCFGraph(const char *filePath) { FILE *out = fopen(filePath, "a"); if (!out) { ERROR("failed to open file: %s\n", filePath); return; } INFO("printing control flow graph to: %s\n", filePath); fprintf(out, "digraph G {\n"); for (IteratorRef it = cfg.iteratorDFS(); !it->end(); it->next()) { BasicBlock *bb = BasicBlock::get( reinterpret_cast<Graph::Node *>(it->get())); int idA = bb->getId(); for (Graph::EdgeIterator ei = bb->cfg.outgoing(); !ei.end(); ei.next()) { int idB = BasicBlock::get(ei.getNode())->getId(); switch (ei.getType()) { case Graph::Edge::TREE: fprintf(out, "\t%i -> %i;\n", idA, idB); break; case Graph::Edge::FORWARD: fprintf(out, "\t%i -> %i [color=green];\n", idA, idB); break; case Graph::Edge::CROSS: fprintf(out, "\t%i -> %i [color=red];\n", idA, idB); break; case Graph::Edge::BACK: fprintf(out, "\t%i -> %i;\n", idA, idB); break; case Graph::Edge::DUMMY: fprintf(out, "\t%i -> %i [style=dotted];\n", idA, idB); break; default: assert(0); break; } } } fprintf(out, "}\n"); fclose(out); }
BasicBlock * BasicBlock::clone(ClonePolicy<Function>& pol) const { BasicBlock *bb = new BasicBlock(pol.context()); pol.set(this, bb); for (Instruction *i = getFirst(); i; i = i->next) bb->insertTail(i->clone(pol)); pol.context()->cfg.insert(&bb->cfg); for (Graph::EdgeIterator it = cfg.outgoing(); !it.end(); it.next()) { BasicBlock *obb = BasicBlock::get(it.getNode()); bb->cfg.attach(&pol.get(obb)->cfg, it.getType()); } return bb; }
void search(Graph::Node *node, const int sequence) { Stack bb, cross; bb.push(node); while (bb.getSize()) { node = reinterpret_cast<Graph::Node *>(bb.pop().u.p); assert(node); if (!node->visit(sequence)) continue; node->tag = 0; for (Graph::EdgeIterator ei = node->outgoing(); !ei.end(); ei.next()) { switch (ei.getType()) { case Graph::Edge::TREE: case Graph::Edge::FORWARD: case Graph::Edge::DUMMY: if (++(ei.getNode()->tag) == ei.getNode()->incidentCountFwd()) bb.push(ei.getNode()); break; case Graph::Edge::BACK: continue; case Graph::Edge::CROSS: if (++(ei.getNode()->tag) == 1) cross.push(ei.getNode()); break; default: assert(!"unknown edge kind in CFG"); break; } } nodes[count++] = node; if (bb.getSize() == 0) cross.moveTo(bb); } }