Node CVC4::theory::bv::mergeExplanations(const std::vector<Node>& expls) { TNodeSet literals; for (unsigned i = 0; i < expls.size(); ++i) { TNode expl = expls[i]; Assert (expl.getType().isBoolean()); if (expl.getKind() == kind::AND) { for (unsigned i = 0; i < expl.getNumChildren(); ++i) { TNode child = expl[i]; if (child == utils::mkTrue()) continue; literals.insert(child); } } else if (expl != utils::mkTrue()) { literals.insert(expl); } } if (literals.size() == 0) return utils::mkTrue(); if (literals.size() == 1) return *literals.begin(); NodeBuilder<> nb(kind::AND); for (TNodeSet::const_iterator it = literals.begin(); it!= literals.end(); ++it) { nb << *it; } return nb; }
ControlNode* GraphLinker::optimizePhi(PhiNode* phi) { TNodeSet incomingValues; const PhiNode::TIncomingList& incomings = phi->getIncomingList(); assert(incomings.size() > 1); // Phi should have at least two incoming edges for (size_t index = 0; index < incomings.size(); index++) incomingValues.insert(incomings[index].node); assert(incomingValues.size()); if (traces_enabled) std::printf("GraphLinker::optimizePhi : phi node %u has %u unique incoming values\n", phi->getIndex(), incomingValues.size()); if (incomingValues.size() > 1) return phi; // Phi is ok, no need to optimize. Leave everything as is. // It seem that phi node is redundant becasue all of it's incomings link to the same value. // This may happen in a diamond-shaped reference diagram if incoming value stored in the top // domain and consumed in the bottom one. Left and right domains are not affected. // We may safely remove the phi because incoming value dominates it's consumer. if (traces_enabled) std::printf("GraphLinker::optimizePhi : phi node %u is redundant and may be removed\n", phi->getIndex()); // This is the real value that should be returned ControlNode* const value = *incomingValues.begin(); // Unlink and erase phi value->removeConsumer(phi); value->removeEdge(phi); m_graph->eraseNode(phi); return value; }