2 * File: ordertransform.cc
5 * Created on August 28, 2017, 10:35 AM
8 #include "decomposeordertransform.h"
10 #include "orderedge.h"
11 #include "ordernode.h"
13 #include "mutableset.h"
14 #include "ordergraph.h"
16 #include "decomposeorderresolver.h"
18 #include "orderanalysis.h"
21 DecomposeOrderTransform::DecomposeOrderTransform(CSolver *_solver)
26 DecomposeOrderTransform::~DecomposeOrderTransform() {
29 void DecomposeOrderTransform::doTransform() {
30 HashsetOrder *orders = solver->getActiveOrders()->copy();
31 SetIteratorOrder *orderit = orders->iterator();
32 while (orderit->hasNext()) {
33 Order *order = orderit->next();
35 if (GETVARTUNABLE(solver->getTuner(), order->type, DECOMPOSEORDER, &onoff) == 0) {
39 DecomposeOrderResolver *dor=new DecomposeOrderResolver(order);
40 order->setOrderResolver(dor);
42 OrderGraph *graph = buildOrderGraph(order);
43 if (order->type == SATC_PARTIAL) {
44 //Required to do SCC analysis for partial order graphs. It
45 //makes sure we don't incorrectly optimize graphs with negative
47 graph->completePartialOrderGraph();
50 bool mustReachGlobal = GETVARTUNABLE(solver->getTuner(), order->type, MUSTREACHGLOBAL, &onoff);
53 reachMustAnalysis(solver, graph, false);
55 bool mustReachLocal = GETVARTUNABLE(solver->getTuner(), order->type, MUSTREACHLOCAL, &onoff);
58 //This pair of analysis is also optional
59 if (order->type == SATC_PARTIAL) {
60 localMustAnalysisPartial(solver, graph);
62 localMustAnalysisTotal(solver, graph);
66 bool mustReachPrune = GETVARTUNABLE(solver->getTuner(), order->type, MUSTREACHPRUNE, &onoff);
67 HashsetOrderEdge *edgesRemoved = NULL;
70 edgesRemoved = new HashsetOrderEdge();
71 removeMustBeTrueNodes(graph, edgesRemoved);
74 //This is needed for splitorder
75 graph->computeStronglyConnectedComponentGraph();
76 decomposeOrder(order, graph, edgesRemoved, dor);
77 if (edgesRemoved != NULL)
85 void DecomposeOrderTransform::decomposeOrder (Order *currOrder, OrderGraph *currGraph, HashsetOrderEdge *edgesRemoved, DecomposeOrderResolver *dor) {
86 Vector<Order *> partialcandidatevec;
87 uint size = currOrder->constraints.getSize();
88 for (uint i = 0; i < size; i++) {
89 BooleanOrder *orderconstraint = currOrder->constraints.get(i);
90 OrderNode *from = currGraph->getOrderNodeFromOrderGraph(orderconstraint->first);
91 OrderNode *to = currGraph->getOrderNodeFromOrderGraph(orderconstraint->second);
92 OrderEdge *edge = currGraph->lookupOrderEdgeFromOrderGraph(from, to);
93 OrderEdge *invedge = currGraph->lookupOrderEdgeFromOrderGraph(to, from);
94 if (edgesRemoved != NULL) {
95 if (edgesRemoved->contains(edge)) {
96 dor->mustOrderEdge(from->getID(), to->getID());
97 solver->replaceBooleanWithTrue(orderconstraint);
99 } else if (edgesRemoved->contains(invedge)) {
100 dor->mustOrderEdge(to->getID(), from->getID());
101 solver->replaceBooleanWithFalse(orderconstraint);
106 if (from->sccNum != to->sccNum) {
109 dor->mustOrderEdge(from->getID(), to->getID());
110 solver->replaceBooleanWithTrue(orderconstraint);
111 } else if (edge->polNeg) {
112 if (currOrder->type == SATC_TOTAL)
113 dor->mustOrderEdge(to->getID(), from->getID());
114 solver->replaceBooleanWithFalse(orderconstraint);
116 //This case should only be possible if constraint isn't in AST
117 //This can happen, so don't do anything
121 if (invedge != NULL) {
122 if (invedge->polPos) {
123 dor->mustOrderEdge(to->getID(), from->getID());
124 solver->replaceBooleanWithFalse(orderconstraint);
125 } else if (edge->polNeg) {
126 //This case shouldn't happen... If we have a partial order,
127 //then we should have our own edge...If we have a total
128 //order, then this edge should be positive...
131 //This case should only be possible if constraint isn't in AST
132 //This can happen, so don't do anything
138 //Build new order and change constraint's order
139 Order *neworder = NULL;
140 neworder = dor->getOrder(from->sccNum);
141 if (neworder == NULL) {
142 MutableSet *set = solver->createMutableSet(currOrder->set->getType());
143 neworder = solver->createOrder(currOrder->type, set);
144 dor->setOrder(from->sccNum, neworder);
145 if (currOrder->type == SATC_PARTIAL)
146 partialcandidatevec.setExpand(from->sccNum, neworder);
148 partialcandidatevec.setExpand(from->sccNum, NULL);
150 if (from->status != ADDEDTOSET) {
151 from->status = ADDEDTOSET;
152 ((MutableSet *)neworder->set)->addElementMSet(from->id);
154 if (to->status != ADDEDTOSET) {
155 to->status = ADDEDTOSET;
156 ((MutableSet *)neworder->set)->addElementMSet(to->id);
158 if (currOrder->type == SATC_PARTIAL) {
160 partialcandidatevec.setExpand(from->sccNum, NULL);
162 orderconstraint->order = neworder;
163 dor->setEdgeOrder(from->getID(), to->getID(), from->sccNum);
164 neworder->addOrderConstraint(orderconstraint);
167 solver->getActiveOrders()->remove(currOrder);
168 uint pcvsize = partialcandidatevec.getSize();
169 for (uint i = 0; i < pcvsize; i++) {
170 Order *neworder = partialcandidatevec.get(i);
171 if (neworder != NULL) {
172 neworder->type = SATC_TOTAL;
177 bool DecomposeOrderTransform::isMustBeTrueNode(OrderNode *node) {
178 SetIteratorOrderEdge *iterator = node->inEdges.iterator();
179 while (iterator->hasNext()) {
180 OrderEdge *edge = iterator->next();
181 if (!edge->mustPos) {
187 iterator = node->outEdges.iterator();
188 while (iterator->hasNext()) {
189 OrderEdge *edge = iterator->next();
190 if (!edge->mustPos) {
199 void DecomposeOrderTransform::bypassMustBeTrueNode(OrderGraph *graph, OrderNode *node, HashsetOrderEdge *edgesRemoved) {
200 node->removed = true;
201 SetIteratorOrderEdge *iterin = node->inEdges.iterator();
202 while (iterin->hasNext()) {
203 OrderEdge *inEdge = iterin->next();
204 OrderNode *srcNode = inEdge->source;
205 srcNode->outEdges.remove(inEdge);
206 edgesRemoved->add(inEdge);
207 SetIteratorOrderEdge *iterout = node->outEdges.iterator();
208 while (iterout->hasNext()) {
209 OrderEdge *outEdge = iterout->next();
210 OrderNode *sinkNode = outEdge->sink;
211 sinkNode->inEdges.remove(outEdge);
212 edgesRemoved->add(outEdge);
213 //Adding new edge to new sink and src nodes ...
214 if (srcNode == sinkNode) {
218 graph->removeNode(node);
221 //Add new order constraint
222 BooleanEdge orderconstraint = solver->orderConstraint(graph->getOrder(), srcNode->getID(), sinkNode->getID());
223 solver->addConstraint(orderconstraint);
226 OrderEdge *newEdge = graph->getOrderEdgeFromOrderGraph(srcNode, sinkNode);
227 newEdge->mustPos = true;
228 newEdge->polPos = true;
229 if (newEdge->mustNeg)
231 srcNode->outEdges.add(newEdge);
232 sinkNode->inEdges.add(newEdge);
237 graph->removeNode(node);
240 void DecomposeOrderTransform::removeMustBeTrueNodes(OrderGraph *graph, HashsetOrderEdge *edgesRemoved) {
241 SetIteratorOrderNode *iterator = graph->getNodes();
242 while (iterator->hasNext()) {
243 OrderNode *node = iterator->next();
244 if (isMustBeTrueNode(node)) {
245 bypassMustBeTrueNode(graph, node, edgesRemoved);