void DominatorTree::findDominanceFrontiers() { BasicBlock *bb; for (IteratorRef dtIt = iteratorDFS(false); !dtIt->end(); dtIt->next()) { EdgeIterator succIt, chldIt; bb = BasicBlock::get(reinterpret_cast<Node *>(dtIt->get())); bb->getDF().clear(); for (succIt = bb->cfg.outgoing(); !succIt.end(); succIt.next()) { BasicBlock *dfLocal = BasicBlock::get(succIt.getNode()); if (dfLocal->idom() != bb) bb->getDF().insert(dfLocal); } for (chldIt = bb->dom.outgoing(); !chldIt.end(); chldIt.next()) { BasicBlock *cb = BasicBlock::get(chldIt.getNode()); DLList::Iterator dfIt = cb->getDF().iterator(); for (; !dfIt.end(); dfIt.next()) { BasicBlock *dfUp = BasicBlock::get(dfIt); if (dfUp->idom() != bb) bb->getDF().insert(dfUp); } } } }
bool Pass::doRun(Function *func, bool ordered, bool skipPhi) { IteratorRef bbIter; BasicBlock *bb; Instruction *insn, *next; this->func = func; if (!visit(func)) return false; bbIter = ordered ? func->cfg.iteratorCFG() : func->cfg.iteratorDFS(); for (; !bbIter->end(); bbIter->next()) { bb = BasicBlock::get(reinterpret_cast<Graph::Node *>(bbIter->get())); if (!visit(bb)) break; for (insn = skipPhi ? bb->getEntry() : bb->getFirst(); insn != NULL; insn = next) { next = insn->next; if (!visit(insn)) break; } } return !err; }
bool Pass::doRun(Program *prog, bool ordered, bool skipPhi) { for (IteratorRef it = prog->calls.iteratorDFS(false); !it->end(); it->next()) { Graph::Node *n = reinterpret_cast<Graph::Node *>(it->get()); if (!doRun(Function::get(n), ordered, skipPhi)) return false; } return !err; }
void Graph::classifyEdges() { int seq; for (IteratorRef it = iteratorDFS(true); !it->end(); it->next()) { Node *node = reinterpret_cast<Node *>(it->get()); node->visit(0); node->tag = 0; } classifyDFS(root, (seq = 0)); sequence = seq; }
CFGIterator(Graph *graph) { nodes = new Graph::Node * [graph->getSize() + 1]; count = 0; pos = 0; nodes[graph->getSize()] = 0; // TODO: argh, use graph->sequence instead of tag and just raise it by > 1 for (IteratorRef it = graph->iteratorDFS(); !it->end(); it->next()) reinterpret_cast<Graph::Node *>(it->get())->tag = 0; if (graph->getRoot()) search(graph->getRoot(), graph->nextSequence()); }
unsigned int Function::orderInstructions(ArrayList &result) { result.clear(); for (IteratorRef it = cfg.iteratorCFG(); !it->end(); it->next()) { BasicBlock *bb = BasicBlock::get(reinterpret_cast<Graph::Node *>(it->get())); for (Instruction *insn = bb->getFirst(); insn; insn = insn->next) result.insert(insn, insn->serial); } return result.getSize(); }
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); }
DominatorTree::DominatorTree(Graph *cfgraph) : cfg(cfgraph), count(cfg->getSize()) { int i = 0; vert = new Node * [count]; data = new int[5 * count]; for (IteratorRef it = cfg->iteratorDFS(true); !it->end(); it->next(), ++i) { vert[i] = reinterpret_cast<Node *>(it->get()); vert[i]->tag = i; LABEL(i) = i; SEMI(i) = ANCESTOR(i) = -1; } assert(i == count); build(); delete[] vert; delete[] data; }
Graph::~Graph() { for (IteratorRef it = safeIteratorDFS(); !it->end(); it->next()) reinterpret_cast<Node *>(it->get())->cut(); }