edit
[satune.git] / src / Translator / decomposeorderresolver.cc
index 0e652d8d6e813169979e2a10fdb7a6479e754f7e..0dbaf8d1881861b03003bde07be16d15963e0834 100644 (file)
@@ -11,7 +11,7 @@
 #include "ordernode.h"
 #include "ordergraph.h"
 
-DecomposeOrderResolver::DecomposeOrderResolver(Order * _order) :
+DecomposeOrderResolver::DecomposeOrderResolver(Order *_order) :
        graph(NULL),
        order(_order)
 {
@@ -25,42 +25,52 @@ DecomposeOrderResolver::~DecomposeOrderResolver() {
 
 void DecomposeOrderResolver::mustOrderEdge(uint64_t first, uint64_t second) {
        DOREdge edge(first, second, 0, first, second);
-       if (!edges.contains(&edge)) {
-               DOREdge *newedge=new DOREdge(first, second, 0, first, second);
+       DOREdge *oldedge=edges.get(&edge);
+       if (oldedge != NULL) {
+               oldedge->mustbetrue=true;
+       } else {
+               DOREdge *newedge = new DOREdge(first, second, 0, first, second);
+               newedge->mustbetrue=true;
                edges.add(newedge);
        }
 }
 
 void DecomposeOrderResolver::remapEdge(uint64_t first, uint64_t second, uint64_t newfirst, uint64_t newsecond) {
        DOREdge edge(first, second, 0, first, second);
-       DOREdge *oldedge=edges.get(&edge);
+       DOREdge *oldedge = edges.get(&edge);
        if (oldedge != NULL) {
                edges.remove(oldedge);
-               oldedge->newfirst=newfirst;
-               oldedge->newsecond=newsecond;
+               oldedge->newfirst = newfirst;
+               oldedge->newsecond = newsecond;
                edges.add(oldedge);
        } else {
-               DOREdge *newedge=new DOREdge(first, second, 0, newfirst, newsecond);
+               DOREdge *newedge = new DOREdge(first, second, 0, newfirst, newsecond);
                edges.add(newedge);
        }
 }
 
 void DecomposeOrderResolver::setEdgeOrder(uint64_t first, uint64_t second, uint sccNum) {
        DOREdge edge(first, second, 0, first, second);
-       DOREdge *oldedge=edges.get(&edge);
+       DOREdge *oldedge = edges.get(&edge);
        if (oldedge != NULL) {
-               oldedge->orderindex=sccNum;
+               oldedge->orderindex = sccNum;
        } else {
-               DOREdge *newedge=new DOREdge(first, second, sccNum, first, second);
+               DOREdge *newedge = new DOREdge(first, second, sccNum, first, second);
                edges.add(newedge);
        }
+       /* Also fix up reverse edge if it exists */
+       DOREdge revedge(second, first, 0, second, first);
+       oldedge = edges.get(&revedge);
+       if (oldedge != NULL) {
+               oldedge->orderindex = sccNum;
+       }
 }
 
 void DecomposeOrderResolver::setOrder(uint sccNum, Order *neworder) {
        orders.setExpand(sccNum, neworder);
 }
 
-Order * DecomposeOrderResolver::getOrder(uint sccNum) {
+Order *DecomposeOrderResolver::getOrder(uint sccNum) {
        Order *neworder = NULL;
        if (orders.getSize() > sccNum)
                neworder = orders.get(sccNum);
@@ -70,15 +80,20 @@ Order * DecomposeOrderResolver::getOrder(uint sccNum) {
 void DecomposeOrderResolver::buildGraph() {
        graph = new OrderGraph(order);
        SetIteratorDOREdge *iterator = edges.iterator();
-       while(iterator->hasNext()) {
-               DOREdge * doredge = iterator->next();
-               if (doredge->orderindex == 0) {
+       while (iterator->hasNext()) {
+               DOREdge *doredge = iterator->next();
+               if (doredge->mustbetrue) {
                        graph->addEdge(doredge->origfirst, doredge->origsecond);
-               } else {
-                       Order * suborder = orders.get(doredge->orderindex);
+                       if (doredge->newfirst != doredge->origfirst || doredge->newsecond!=doredge->origsecond) {
+                               graph->addEdge(doredge->newfirst, doredge->newsecond);
+                       }
+               } else if (doredge->orderindex != 0) {
+                       Order *suborder = orders.get(doredge->orderindex);
                        bool isEdge = suborder->encoding.resolver->resolveOrder(doredge->newfirst, doredge->newsecond);
                        if (isEdge)
                                graph->addEdge(doredge->origfirst, doredge->origsecond);
+                       else if (order->type == SATC_TOTAL)
+                               graph->addEdge(doredge->origsecond, doredge->origfirst);
                }
        }
        delete iterator;
@@ -92,9 +107,15 @@ bool DecomposeOrderResolver::resolveOrder(uint64_t first, uint64_t second) {
                buildGraph();
 
        OrderNode *from = graph->lookupOrderNodeFromOrderGraph(first);
-       ASSERT(from != NULL);
+       if (from == NULL) {
+               ASSERT(order->type != SATC_TOTAL);
+               return false;
+       }
        OrderNode *to = graph->lookupOrderNodeFromOrderGraph(second);
-       ASSERT(to != NULL);
+       if (to == NULL) {
+               ASSERT(order->type != SATC_TOTAL);
+               return false;
+       }
        switch (order->type) {
        case SATC_TOTAL:
                return from->sccNum < to->sccNum;