void DecomposeOrderTransform::doTransform() {
HashsetOrder *orders = solver->getActiveOrders()->copy();
- SetIteratorOrder * orderit=orders->iterator();
- while(orderit->hasNext()) {
+ SetIteratorOrder *orderit = orders->iterator();
+ while (orderit->hasNext()) {
Order *order = orderit->next();
if (GETVARTUNABLE(solver->getTuner(), order->type, DECOMPOSEORDER, &onoff) == 0) {
continue;
}
+ DecomposeOrderResolver *dor=new DecomposeOrderResolver(order);
+ order->setOrderResolver(dor);
+
OrderGraph *graph = buildOrderGraph(order);
if (order->type == SATC_PARTIAL) {
//Required to do SCC analysis for partial order graphs. It
//makes sure we don't incorrectly optimize graphs with negative
//polarity edges
- completePartialOrderGraph(graph);
+ graph->completePartialOrderGraph();
}
bool mustReachGlobal = GETVARTUNABLE(solver->getTuner(), order->type, MUSTREACHGLOBAL, &onoff);
-
if (mustReachGlobal)
reachMustAnalysis(solver, graph, false);
bool mustReachLocal = GETVARTUNABLE(solver->getTuner(), order->type, MUSTREACHLOCAL, &onoff);
-
if (mustReachLocal) {
//This pair of analysis is also optional
if (order->type == SATC_PARTIAL) {
}
}
-
bool mustReachPrune = GETVARTUNABLE(solver->getTuner(), order->type, MUSTREACHPRUNE, &onoff);
+ HashsetOrderEdge *edgesRemoved = NULL;
+
+ if (mustReachPrune) {
+ edgesRemoved = new HashsetOrderEdge();
+ removeMustBeTrueNodes(graph, edgesRemoved);
+ }
- if (mustReachPrune)
- removeMustBeTrueNodes(solver, graph);
-
//This is needed for splitorder
- computeStronglyConnectedComponentGraph(graph);
- decomposeOrder(order, graph);
+ graph->computeStronglyConnectedComponentGraph();
+ decomposeOrder(order, graph, edgesRemoved, dor);
+ if (edgesRemoved != NULL)
+ delete edgesRemoved;
+ delete graph;
}
delete orderit;
delete orders;
}
-void DecomposeOrderTransform::decomposeOrder (Order *currOrder, OrderGraph *currGraph) {
- Vector<Order *> ordervec;
+void DecomposeOrderTransform::decomposeOrder (Order *currOrder, OrderGraph *currGraph, HashsetOrderEdge *edgesRemoved, DecomposeOrderResolver *dor) {
Vector<Order *> partialcandidatevec;
uint size = currOrder->constraints.getSize();
for (uint i = 0; i < size; i++) {
BooleanOrder *orderconstraint = currOrder->constraints.get(i);
OrderNode *from = currGraph->getOrderNodeFromOrderGraph(orderconstraint->first);
OrderNode *to = currGraph->getOrderNodeFromOrderGraph(orderconstraint->second);
+ OrderEdge *edge = currGraph->lookupOrderEdgeFromOrderGraph(from, to);
+ OrderEdge *invedge = currGraph->lookupOrderEdgeFromOrderGraph(to, from);
+ if (edgesRemoved != NULL) {
+ if (edgesRemoved->contains(edge)) {
+ dor->mustOrderEdge(from->getID(), to->getID());
+ solver->replaceBooleanWithTrue(orderconstraint);
+ continue;
+ } else if (edgesRemoved->contains(invedge)) {
+ dor->mustOrderEdge(to->getID(), from->getID());
+ solver->replaceBooleanWithFalse(orderconstraint);
+ continue;
+ }
+ }
+
if (from->sccNum != to->sccNum) {
- OrderEdge *edge = currGraph->lookupOrderEdgeFromOrderGraph(from, to);
if (edge != NULL) {
if (edge->polPos) {
+ dor->mustOrderEdge(from->getID(), to->getID());
solver->replaceBooleanWithTrue(orderconstraint);
} else if (edge->polNeg) {
+ if (currOrder->type == SATC_TOTAL)
+ dor->mustOrderEdge(to->getID(), from->getID());
solver->replaceBooleanWithFalse(orderconstraint);
} else {
//This case should only be possible if constraint isn't in AST
;
}
} else {
- OrderEdge *invedge = currGraph->lookupOrderEdgeFromOrderGraph(to, from);
if (invedge != NULL) {
if (invedge->polPos) {
+ dor->mustOrderEdge(to->getID(), from->getID());
solver->replaceBooleanWithFalse(orderconstraint);
} else if (edge->polNeg) {
//This case shouldn't happen... If we have a partial order,
} else {
//Build new order and change constraint's order
Order *neworder = NULL;
- if (ordervec.getSize() > from->sccNum)
- neworder = ordervec.get(from->sccNum);
+ neworder = dor->getOrder(from->sccNum);
if (neworder == NULL) {
MutableSet *set = solver->createMutableSet(currOrder->set->getType());
neworder = solver->createOrder(currOrder->type, set);
- ordervec.setExpand(from->sccNum, neworder);
+ dor->setOrder(from->sccNum, neworder);
if (currOrder->type == SATC_PARTIAL)
partialcandidatevec.setExpand(from->sccNum, neworder);
else
((MutableSet *)neworder->set)->addElementMSet(to->id);
}
if (currOrder->type == SATC_PARTIAL) {
- OrderEdge *edge = currGraph->getOrderEdgeFromOrderGraph(from, to);
if (edge->polNeg)
partialcandidatevec.setExpand(from->sccNum, NULL);
}
orderconstraint->order = neworder;
+ dor->setEdgeOrder(from->getID(), to->getID(), from->sccNum);
neworder->addOrderConstraint(orderconstraint);
}
}
- currOrder->setOrderResolver( new DecomposeOrderResolver(currGraph, ordervec) );
solver->getActiveOrders()->remove(currOrder);
uint pcvsize = partialcandidatevec.getSize();
for (uint i = 0; i < pcvsize; i++) {
}
}
}
+
+bool DecomposeOrderTransform::isMustBeTrueNode(OrderNode *node) {
+ SetIteratorOrderEdge *iterator = node->inEdges.iterator();
+ while (iterator->hasNext()) {
+ OrderEdge *edge = iterator->next();
+ if (!edge->mustPos) {
+ delete iterator;
+ return false;
+ }
+ }
+ delete iterator;
+ iterator = node->outEdges.iterator();
+ while (iterator->hasNext()) {
+ OrderEdge *edge = iterator->next();
+ if (!edge->mustPos) {
+ delete iterator;
+ return false;
+ }
+ }
+ delete iterator;
+ return true;
+}
+
+void DecomposeOrderTransform::bypassMustBeTrueNode(OrderGraph *graph, OrderNode *node, HashsetOrderEdge *edgesRemoved) {
+ node->removed = true;
+ SetIteratorOrderEdge *iterin = node->inEdges.iterator();
+ while (iterin->hasNext()) {
+ OrderEdge *inEdge = iterin->next();
+ OrderNode *srcNode = inEdge->source;
+ srcNode->outEdges.remove(inEdge);
+ edgesRemoved->add(inEdge);
+ SetIteratorOrderEdge *iterout = node->outEdges.iterator();
+ while (iterout->hasNext()) {
+ OrderEdge *outEdge = iterout->next();
+ OrderNode *sinkNode = outEdge->sink;
+ sinkNode->inEdges.remove(outEdge);
+ edgesRemoved->add(outEdge);
+ //Adding new edge to new sink and src nodes ...
+ if (srcNode == sinkNode) {
+ solver->setUnSAT();
+ delete iterout;
+ delete iterin;
+ graph->removeNode(node);
+ return;
+ }
+ //Add new order constraint
+ BooleanEdge orderconstraint = solver->orderConstraint(graph->getOrder(), srcNode->getID(), sinkNode->getID());
+ solver->addConstraint(orderconstraint);
+
+ //Add new edge
+ OrderEdge *newEdge = graph->getOrderEdgeFromOrderGraph(srcNode, sinkNode);
+ newEdge->mustPos = true;
+ newEdge->polPos = true;
+ if (newEdge->mustNeg)
+ solver->setUnSAT();
+ srcNode->outEdges.add(newEdge);
+ sinkNode->inEdges.add(newEdge);
+ }
+ delete iterout;
+ }
+ delete iterin;
+ graph->removeNode(node);
+}
+
+void DecomposeOrderTransform::removeMustBeTrueNodes(OrderGraph *graph, HashsetOrderEdge *edgesRemoved) {
+ SetIteratorOrderNode *iterator = graph->getNodes();
+ while (iterator->hasNext()) {
+ OrderNode *node = iterator->next();
+ if (isMustBeTrueNode(node)) {
+ bypassMustBeTrueNode(graph, node, edgesRemoved);
+ }
+ }
+ delete iterator;
+}