void BlockSyntaxNode::printAST(SyntaxNode *root, std::ostream &os) { os << std::setw(4) << std::dec << nodenum << " "; os << "[label=\""; if (pbb) { switch (pbb->getType()) { case ONEWAY: os << "Oneway"; if (notGoto) os << " (ignored)"; break; case TWOWAY: os << "Twoway"; break; case NWAY: os << "Nway"; break; case CALL: os << "Call"; break; case RET: os << "Ret"; break; case FALL: os << "Fall"; break; case COMPJUMP: os << "Computed jump"; break; case COMPCALL: os << "Computed call"; break; case INVALID: os << "Invalid"; break; } os << " " << std::hex << pbb->getLowAddr(); } else os << "block"; os << "\"];" << std::endl; if (pbb) { for (int i = 0; i < pbb->getNumOutEdges(); i++) { PBB out = pbb->getOutEdge(i); os << std::setw(4) << std::dec << nodenum << " "; SyntaxNode *to = root->findNodeFor(out); assert(to); os << " -> " << to->getNumber() << " [style=dotted"; if (pbb->getNumOutEdges() > 1) os << ",label=" << i; os << "];" << std::endl; } } else { for (unsigned i = 0; i < statements.size(); i++) statements[i]->printAST(root, os); for (unsigned i = 0; i < statements.size(); i++) { os << std::setw(4) << std::dec << nodenum << " "; os << " -> " << statements[i]->getNumber() << " [label=\"" << i << "\"];" << std::endl; } } }
int BlockSyntaxNode::evaluate(SyntaxNode *root) { #if DEBUG_EVAL if (this == root) std::cerr << "begin eval =============" << std::endl; #endif if (pbb) return 1; int n = 1; if (statements.size() == 1) { SyntaxNode *out = statements[0]->getOutEdge(root, 0); if (out->getBB() != NULL && out->getBB()->getNumInEdges() > 1) { #if DEBUG_EVAL std::cerr << "add 15" << std::endl; #endif n += 15; } else { #if DEBUG_EVAL std::cerr << "add 30" << std::endl; #endif n += 30; } } for (unsigned i = 0; i < statements.size(); i++) { n += statements[i]->evaluate(root); if (statements[i]->isGoto()) { if (i != statements.size() - 1) { #if DEBUG_EVAL std::cerr << "add 100" << std::endl; #endif n += 100; } else { #if DEBUG_EVAL std::cerr << "add 50" << std::endl; #endif n += 50; } } else if (statements[i]->isBranch()) { SyntaxNode *loop = root->getEnclosingLoop(this); std::cerr << "branch " << statements[i]->getNumber() << " not in loop" << std::endl; if (loop) { std::cerr << "branch " << statements[i]->getNumber() << " in loop " << loop->getNumber() << std::endl; // this is a bit C specific SyntaxNode *out = loop->getOutEdge(root, 0); if (out && statements[i]->getOutEdge(root, 0) == out) { std::cerr << "found break" << std::endl; n += 10; } if (statements[i]->getOutEdge(root, 0) == loop) { std::cerr << "found continue" << std::endl; n += 10; } } else { #if DEBUG_EVAL std::cerr << "add 50" << std::endl; #endif n += 50; } } else if (i < statements.size() - 1 && statements[i]->getOutEdge(root, 0) != statements[i + 1]) { #if DEBUG_EVAL std::cerr << "add 25" << std::endl; std::cerr << statements[i]->getNumber() << " -> " << statements[i]->getOutEdge(root, 0)->getNumber() << " not " << statements[i + 1]->getNumber() << std::endl; #endif n += 25; } } #if DEBUG_EVAL if (this == root) std::cerr << "end eval = " << n << " =============" << std::endl; #endif return n; }