bool sortVerticesByAddress(const ControlFlowGraph::ConstVertexNodeIterator &a, const ControlFlowGraph::ConstVertexNodeIterator &b) { const CfgVertex &av = a->value(); const CfgVertex &bv = b->value(); if (av.type() != bv.type() || av.type() != V_BASIC_BLOCK) return av.type() < bv.type(); return av.address() < bv.address(); }
Sawyer::Optional<bool> Partitioner::basicBlockOptionalMayReturn(const ControlFlowGraph::ConstVertexNodeIterator &start) const { ASSERT_require(start != cfg_.vertices().end()); // Return a cached value if there is one if (start->value().type() == V_BASIC_BLOCK) { if (BasicBlock::Ptr bblock = start->value().bblock()) { bool b; if (bblock->mayReturn().getOptional().assignTo(b)) return b; } } // Do the hard work std::vector<MayReturnVertexInfo> vertexInfo(cfg_.nVertices()); return basicBlockOptionalMayReturn(start, vertexInfo); }
// Internal: Run the may-return analysis on the callees and return true if any of them have a positive or indeterminate // may-return property. boost::logic::tribool Partitioner::mayReturnDoesCalleeReturn(const ControlFlowGraph::ConstVertexNodeIterator &caller, std::vector<MayReturnVertexInfo> &vertexInfo) const { ASSERT_require(caller != cfg_.vertices().end()); if (!vertexInfo[caller->id()].processedCallees) { vertexInfo[caller->id()].anyCalleesReturn = false; bool hasPositiveCallee = false, hasIndeterminateCallee = false; BOOST_FOREACH (const ControlFlowGraph::EdgeNode &edge, caller->outEdges()) { if (edge.value().type() == E_FUNCTION_CALL) { ControlFlowGraph::ConstVertexNodeIterator callee = edge.target(); bool mayReturn = false; if (!basicBlockOptionalMayReturn(callee, vertexInfo).assignTo(mayReturn)) { hasIndeterminateCallee = true; } else if (mayReturn) { hasPositiveCallee = true; break; } } } if (hasPositiveCallee) { vertexInfo[caller->id()].anyCalleesReturn = true; } else if (hasIndeterminateCallee) { vertexInfo[caller->id()].anyCalleesReturn = boost::logic::indeterminate; } vertexInfo[caller->id()].processedCallees = true; }