merge to branch master
authorHamed <hamed.gorjiara@gmail.com>
Tue, 19 Sep 2017 23:39:05 +0000 (16:39 -0700)
committerHamed <hamed.gorjiara@gmail.com>
Tue, 19 Sep 2017 23:39:05 +0000 (16:39 -0700)
src/AST/set.cc
src/AST/set.h
src/ASTAnalyses/Encoding/encodinggraph.cc
src/ASTAnalyses/Encoding/encodinggraph.h
src/ASTAnalyses/Encoding/graphstructs.h [new file with mode: 0644]
src/ASTAnalyses/Encoding/subgraph.cc [new file with mode: 0644]
src/ASTAnalyses/Encoding/subgraph.h [new file with mode: 0644]
src/Collections/array.h
src/Collections/cppvector.h
src/Collections/hashset.h
src/Collections/vector.h

index 66f8461ace3a070975749dfccd479f4a5b98b55a..bd1b3d6e431f013a32ce4bc43123c22bcb68c775 100644 (file)
@@ -33,12 +33,24 @@ bool Set::exists(uint64_t element) {
        if (isRange) {
                return element >= low && element <= high;
        } else {
-               uint size = members->getSize();
-               for (uint i = 0; i < size; i++) {
-                       if (element == members->get(i))
+               //Use Binary Search
+               uint low=0;
+               uint high=members->getSize()-1;
+               while(true) {
+                       uint middle=(low+high)/2;
+                       uint64_t val=members->get(middle);
+                       if (element < val) {
+                               high=middle;
+                               if (middle==low)
+                                       return false;
+                       } else if (element > val) {
+                               low=middle;
+                               if (middle==high)
+                                       return false;
+                       } else {
                                return true;
+                       }
                }
-               return false;
        }
 }
 
@@ -83,6 +95,31 @@ Set *Set::clone(CSolver *solver, CloneMap *map) {
        return s;
 }
 
+uint Set::getUnionSize(Set *s) {
+       uint sSize = s->getSize();
+       uint thisSize = getSize();
+       uint sIndex = 0;
+       uint thisIndex = 0;
+       uint sum = 0;
+       uint64_t sValue = s->getElement(sIndex);
+       uint64_t thisValue = getElement(thisIndex);
+       while(thisIndex < thisSize && sIndex < sSize) {
+               if (sValue < thisValue) {
+                       sValue = s->getElement(++sIndex);
+                       sum++;
+               } else if (thisValue < sValue) {
+                       thisValue = getElement(++thisIndex);
+                       sum++;
+               } else {
+                       thisValue = getElement(++thisIndex);
+                       sValue = s->getElement(++sIndex);
+                       sum++;
+               }
+       }
+       sum += (thisSize - thisIndex) + (sSize - sIndex);
+       
+       return sum;
+}
 
 void Set::serialize(Serializer* serializer){
        if(serializer->isSerialized(this))
index ef10b39bdaf3dc75830dde6d980a0a155b1293eb..ad89504db94e76170464d1eb5c29c943dd1106c3 100644 (file)
@@ -24,6 +24,7 @@ public:
        uint64_t getNewUniqueItem() {return low++;}
        uint64_t getMemberAt(uint index);
        uint64_t getElement(uint index);
+       uint getUnionSize(Set *s);
        virtual bool isMutableSet() {return false;}
        virtual Set *clone(CSolver *solver, CloneMap *map);
        virtual void serialize(Serializer* serializer);
@@ -34,7 +35,6 @@ protected:
        uint64_t low;//also used to count unique items
        uint64_t high;
        Vector<uint64_t> *members;
-
 };
 
 int intcompare(const void *p1, const void *p2);
index 60437f5ea4fd266f4f62437da3e9d255140b7943..75a98b1ea7ecc43b66b88700612ab6f4d32032f0 100644 (file)
@@ -6,12 +6,26 @@
 #include "set.h"
 #include "csolver.h"
 #include "tunable.h"
+#include "qsort.h"
+#include "subgraph.h"
+#include "elementencoding.h"
 #include "boolean.h"
 
 EncodingGraph::EncodingGraph(CSolver * _solver) :
        solver(_solver) {
-       
+}
 
+int sortEncodingEdge(const void * p1, const void *p2) {
+       const EncodingEdge * e1 = * (const EncodingEdge **) p1;
+       const EncodingEdge * e2 = * (const EncodingEdge **) p2;
+       uint64_t v1 = e1->getValue();
+       uint64_t v2 = e2->getValue();
+       if (v1 < v2)
+               return 1;
+       else if (v1 == v2)
+               return 0;
+       else
+               return -1;
 }
 
 void EncodingGraph::buildGraph() {
@@ -29,6 +43,35 @@ void EncodingGraph::buildGraph() {
                        ASSERT(0);
                }
        }
+       bsdqsort(edgeVector.expose(), edgeVector.getSize(), sizeof(EncodingEdge *), sortEncodingEdge);
+       decideEdges();
+}
+
+void EncodingGraph::encode() {
+       SetIteratorEncodingSubGraph * itesg=subgraphs.iterator();
+       while(itesg->hasNext()) {
+               EncodingSubGraph *sg=itesg->next();
+               sg->encode();
+       }
+       delete itesg;
+
+       ElementIterator it(solver);
+       while(it.hasNext()) {
+               Element * e = it.next();
+               switch(e->type) {
+               case ELEMSET:
+               case ELEMFUNCRETURN: {
+                       ElementEncoding *encoding=e->getElementEncoding();
+                       if (encoding->getElementEncodingType() == ELEM_UNASSIGNED) {
+                               //Do assignment...
+                       }
+                       break;
+               }
+               default:
+                       break;
+               }
+       }
+       
 }
 
 void EncodingGraph::mergeNodes(EncodingNode *first, EncodingNode *second) {
@@ -36,6 +79,7 @@ void EncodingGraph::mergeNodes(EncodingNode *first, EncodingNode *second) {
        EncodingSubGraph *graph2=graphMap.get(second);
        if (graph1 == NULL && graph2 == NULL) {
                graph1 = new EncodingSubGraph();
+               subgraphs.add(graph1);
                graphMap.put(first, graph1);
                graph1->addNode(first);
        }
@@ -53,6 +97,7 @@ void EncodingGraph::mergeNodes(EncodingNode *first, EncodingNode *second) {
                        graph1->addNode(node);
                        graphMap.put(node, graph1);
                }
+               subgraphs.remove(graph2);
                delete nodeit;
                delete graph2;
        } else {
@@ -121,6 +166,70 @@ void EncodingGraph::processPredicate(BooleanPredicate *b) {
        }
 }
 
+uint convertSize(uint cost) {
+       cost = 1.2 * cost; // fudge factor
+       return NEXTPOW2(cost);
+}
+
+void EncodingGraph::decideEdges() {
+       uint size=edgeVector.getSize();
+       for(uint i=0; i<size; i++) {
+               EncodingEdge *ee = edgeVector.get(i);
+               EncodingNode *left = ee->left;
+               EncodingNode *right = ee->right;
+               
+               if (ee->encoding != EDGE_UNASSIGNED ||
+                               left->encoding != BINARYINDEX ||
+                               right->encoding != BINARYINDEX)
+                       continue;
+               
+               uint64_t eeValue = ee->getValue();
+               if (eeValue == 0)
+                       return;
+
+               EncodingSubGraph *leftGraph = graphMap.get(left);
+               EncodingSubGraph *rightGraph = graphMap.get(right);
+               if (leftGraph == NULL && rightGraph !=NULL) {
+                       EncodingNode *tmp = left; left=right; right=tmp;
+                       EncodingSubGraph *tmpsg = leftGraph; leftGraph = rightGraph; rightGraph = tmpsg;
+               }
+
+               uint leftSize=0, rightSize=0, newSize=0;
+               uint64_t totalCost=0;
+               if (leftGraph == NULL && rightGraph == NULL) {
+                       leftSize=convertSize(left->getSize());
+                       rightSize=convertSize(right->getSize());
+                       newSize=convertSize(left->s->getUnionSize(right->s));
+                       newSize=(leftSize > newSize) ? leftSize: newSize;
+                       newSize=(rightSize > newSize) ? rightSize: newSize;
+                       totalCost = (newSize - leftSize) * left->elements.getSize() +
+                               (newSize - rightSize) * right->elements.getSize();
+               } else if (leftGraph != NULL && rightGraph == NULL) {
+                       leftSize=convertSize(leftGraph->encodingSize);
+                       rightSize=convertSize(right->getSize());
+                       newSize=convertSize(leftGraph->estimateNewSize(right));
+                       newSize=(leftSize > newSize) ? leftSize: newSize;
+                       newSize=(rightSize > newSize) ? rightSize: newSize;
+                       totalCost = (newSize - leftSize) * leftGraph->numElements +
+                               (newSize - rightSize) * right->elements.getSize();
+               } else {
+                       //Neither are null
+                       leftSize=convertSize(leftGraph->encodingSize);
+                       rightSize=convertSize(rightGraph->encodingSize);
+                       newSize=convertSize(leftGraph->estimateNewSize(rightGraph));
+                       newSize=(leftSize > newSize) ? leftSize: newSize;
+                       newSize=(rightSize > newSize) ? rightSize: newSize;
+                       totalCost = (newSize - leftSize) * leftGraph->numElements +
+                               (newSize - rightSize) * rightGraph->numElements;
+               }
+               double conversionfactor = 0.5;
+               if ((totalCost * conversionfactor) < eeValue) {
+                       //add the edge
+                       mergeNodes(left, right);
+               }
+       }
+}
+
 static TunableDesc EdgeEncodingDesc(EDGE_UNASSIGNED, EDGE_MATCH, EDGE_UNASSIGNED);
 
 EncodingEdge * EncodingGraph::getEdge(EncodingNode *left, EncodingNode *right, EncodingNode *dst) {
@@ -135,22 +244,36 @@ EncodingEdge * EncodingGraph::getEdge(EncodingNode *left, EncodingNode *right, E
                        v2=v1;
                        v1=tmp;
                }
-               result->setEncoding((EdgeEncodingType)solver->getTuner()->getVarTunable(v1, v2, EDGEENCODING, &EdgeEncodingDesc));
+
+               if ((left != NULL && left->encoding==BINARYINDEX) &&
+                               (right != NULL) && right->encoding==BINARYINDEX) {
+                       EdgeEncodingType type=(EdgeEncodingType)solver->getTuner()->getVarTunable(v1, v2, EDGEENCODING, &EdgeEncodingDesc);
+                       result->setEncoding(type);
+                       if (type == EDGE_MATCH) {
+                               mergeNodes(left, right);
+                       }
+               }
                edgeMap.put(result, result);
+               edgeVector.push(result);
+               if (left != NULL)
+                       left->edges.add(result);
+               if (right != NULL)
+                       right->edges.add(result);
+               if (dst != NULL)
+                       dst->edges.add(result);
        }
        return result;
 }
 
 EncodingNode::EncodingNode(Set *_s) :
-       s(_s),
-       numElements(0) {
+       s(_s) {
 }
 
-uint EncodingNode::getSize() {
+uint EncodingNode::getSize() const {
        return s->getSize();
 }
 
-VarType EncodingNode::getType() {
+VarType EncodingNode::getType() const {
        return s->getType();
 }
 
@@ -167,8 +290,6 @@ EncodingNode * EncodingGraph::createNode(Element *e) {
                encodingMap.put(s, n);
        }
        n->addElement(e);
-       if (discovered.add(e))
-               n->numElements++;
        return n;
 }
 
@@ -207,47 +328,11 @@ bool equalsEncodingEdge(EncodingEdge *e1, EncodingEdge *e2) {
        return e1->left == e2->left && e1->right == e2->right && e1->dst == e2->dst;
 }
 
-EncodingSubGraph::EncodingSubGraph() {
-}
-
-void EncodingSubGraph::addNode(EncodingNode *n) {
-       nodes.add(n);
-       Set *s=n->s;
-       uint size=s->getSize();
-       for(uint i=0; i<size; i++) {
-               uint64_t val=s->getElement(i);
-               values.add(val);
-       }
+uint64_t EncodingEdge::getValue() const {
+       uint lSize = (left != NULL) ? left->getSize() : 1;
+       uint rSize = (right != NULL) ? right->getSize() : 1;
+       uint min = (lSize < rSize) ? lSize : rSize;
+       return numEquals * min + numComparisons * lSize * rSize;
 }
 
-SetIteratorEncodingNode * EncodingSubGraph::nodeIterator() {
-       return nodes.iterator();
-}
 
-uint EncodingSubGraph::computeIntersection(Set *s) {
-       uint intersect=0;
-       uint size=s->getSize();
-       for(uint i=0; i<size; i++) {
-               uint64_t val=s->getElement(i);
-               if (values.contains(val))
-                       intersect++;
-       }
-       return intersect;
-}
-
-uint EncodingSubGraph::computeIntersection(EncodingSubGraph *g) {
-       if (g->values.getSize() > values.getSize()) {
-               //iterator over smaller set
-               return g->computeIntersection(this);
-       }
-       
-       uint intersect=0;
-       SetIterator64Int * iter=g->values.iterator();
-       while(iter->hasNext()) {
-               uint64_t val=iter->next();
-               if (values.contains(val))
-                       intersect++;
-       }
-       delete iter;
-       return intersect;
-}
index 4057dd2ed7c10115081320768bf04d0fa150dd43..5fe6d2ad023ee53c93ffc98f289dd88dbaaffa1c 100644 (file)
@@ -2,31 +2,25 @@
 #define ENCODINGGRAPH_H
 #include "classlist.h"
 #include "structs.h"
-
-uint hashEncodingEdge(EncodingEdge *edge);
-bool equalsEncodingEdge(EncodingEdge *e1, EncodingEdge *e2);
-class EncodingSubGraph;
-
-
-typedef Hashtable<EncodingEdge *, EncodingEdge *, uintptr_t, PTRSHIFT, hashEncodingEdge, equalsEncodingEdge> HashtableEdge;
-typedef Hashset<EncodingNode *, uintptr_t, PTRSHIFT> HashsetEncodingNode;
-typedef SetIterator<EncodingNode *, uintptr_t, PTRSHIFT> SetIteratorEncodingNode;
-typedef Hashtable<EncodingNode *, EncodingSubGraph *, uintptr_t, PTRSHIFT> HashtableNodeToSubGraph;
+#include "graphstructs.h"
 
 class EncodingGraph {
  public:
        EncodingGraph(CSolver * solver);
        void buildGraph();
+       void encode();
        
        CMEMALLOC;
  private:
        CSolver * solver;
        HashtableEncoding encodingMap;
        HashtableEdge edgeMap;
+       Vector<EncodingEdge *> edgeVector;
        HashsetElement discovered;
        HashtableNodeToSubGraph graphMap;
-
+       HashsetEncodingSubGraph subgraphs;
        
+       void decideEdges();
        void mergeNodes(EncodingNode *first, EncodingNode *second);
        void processElement(Element *e);
        void processFunction(ElementFunction *f);
@@ -39,34 +33,20 @@ class EncodingNode {
  public:
        EncodingNode(Set *_s);
        void addElement(Element *e);
-       uint getSize();
-       VarType getType();
+       uint getSize() const;
+       VarType getType() const;
        void setEncoding(ElementEncodingType e) {encoding=e;}
        
        CMEMALLOC;
  private:
        Set *s;
        HashsetElement elements;
-       uint numElements;
+       HashsetEncodingEdge edges;
        ElementEncodingType encoding;
        friend class EncodingGraph;
        friend class EncodingSubGraph;
 };
 
-class EncodingSubGraph {
- public:
-       EncodingSubGraph();
-       void addNode(EncodingNode *n);
-       SetIteratorEncodingNode * nodeIterator();
-       uint computeIntersection(Set *s);
-       uint computeIntersection(EncodingSubGraph *g);
-       
-       CMEMALLOC;
- private:
-       HashsetEncodingNode nodes;
-       Hashset64Int values;
-};
-
 enum EdgeEncodingType { EDGE_UNASSIGNED, EDGE_BREAK, EDGE_MATCH};
 typedef enum EdgeEncodingType EdgeEncodingType;
 
@@ -75,6 +55,7 @@ class EncodingEdge {
        EncodingEdge(EncodingNode *_l, EncodingNode *_r);
        EncodingEdge(EncodingNode *_l, EncodingNode *_r, EncodingNode *_d);
        void setEncoding(EdgeEncodingType e) {encoding=e;}
+       uint64_t getValue() const;
        CMEMALLOC;
        
  private:
@@ -88,6 +69,7 @@ class EncodingEdge {
        friend uint hashEncodingEdge(EncodingEdge *edge);
        friend bool equalsEncodingEdge(EncodingEdge *e1, EncodingEdge *e2);
        friend class EncodingGraph;
+       friend class EncodingSubGraph;
 };
 
 #endif
diff --git a/src/ASTAnalyses/Encoding/graphstructs.h b/src/ASTAnalyses/Encoding/graphstructs.h
new file mode 100644 (file)
index 0000000..89add61
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef GRAPHSTRUCTS_H
+#define GRAPHSTRUCTS_H
+#include "classlist.h"
+#include "structs.h"
+
+uint hashEncodingEdge(EncodingEdge *edge);
+bool equalsEncodingEdge(EncodingEdge *e1, EncodingEdge *e2);
+class EncodingSubGraph;
+
+
+typedef Hashtable<EncodingEdge *, EncodingEdge *, uintptr_t, PTRSHIFT, hashEncodingEdge, equalsEncodingEdge> HashtableEdge;
+typedef Hashset<EncodingNode *, uintptr_t, PTRSHIFT> HashsetEncodingNode;
+typedef SetIterator<EncodingNode *, uintptr_t, PTRSHIFT> SetIteratorEncodingNode;
+typedef Hashset<EncodingEdge *, uintptr_t, PTRSHIFT> HashsetEncodingEdge;
+typedef SetIterator<EncodingEdge *, uintptr_t, PTRSHIFT> SetIteratorEncodingEdge;
+
+typedef Hashtable<EncodingNode *, EncodingSubGraph *, uintptr_t, PTRSHIFT> HashtableNodeToSubGraph;
+typedef Hashset<EncodingSubGraph *, uintptr_t, PTRSHIFT> HashsetEncodingSubGraph;
+typedef SetIterator<EncodingSubGraph *, uintptr_t, PTRSHIFT> SetIteratorEncodingSubGraph;
+#endif
diff --git a/src/ASTAnalyses/Encoding/subgraph.cc b/src/ASTAnalyses/Encoding/subgraph.cc
new file mode 100644 (file)
index 0000000..f75d7c8
--- /dev/null
@@ -0,0 +1,362 @@
+#include "subgraph.h"
+#include "encodinggraph.h"
+#include "set.h"
+#include "qsort.h"
+
+EncodingSubGraph::EncodingSubGraph() :
+       encodingSize(0),
+       numElements(0),
+       maxEncodingVal(0) {
+}
+
+uint hashNodeValuePair(NodeValuePair *nvp) {
+       return (uint) (nvp->value ^ ((uintptr_t)nvp->node));
+}
+
+bool equalsNodeValuePair(NodeValuePair *nvp1, NodeValuePair *nvp2) {
+       return nvp1->value == nvp2->value && nvp1->node == nvp2->node;
+}
+
+int sortEncodingValue(const void *p1, const void *p2) {
+       const EncodingValue * e1 = * (const EncodingValue **) p1;
+       const EncodingValue * e2 = * (const EncodingValue **) p2;
+       uint se1=e1->notequals.getSize();
+       uint se2=e2->notequals.getSize();
+       if (se1 > se2)
+               return -1;
+       else if (se2 == se1)
+               return 0;
+       else
+               return 1;
+}
+
+void EncodingSubGraph::solveEquals() {
+       Vector<EncodingValue *> toEncode;
+       Vector<bool> encodingArray;
+       SetIteratorEncodingValue *valIt=values.iterator();
+       while(valIt->hasNext()) {
+               EncodingValue *ev=valIt->next();
+               if (!ev->inComparison)
+                       toEncode.push(ev);
+               else
+                       ev->assigned = true;
+       }
+       delete valIt;
+       bsdqsort(toEncode.expose(), toEncode.getSize(), sizeof(EncodingValue *), sortEncodingValue);
+       uint toEncodeSize=toEncode.getSize();
+       for(uint i=0; i<toEncodeSize; i++) {
+               EncodingValue * ev=toEncode.get(i);
+               encodingArray.clear();
+               SetIteratorEncodingValue *conflictIt=ev->notequals.iterator();
+               while(conflictIt->hasNext()) {
+                       EncodingValue * conflict=conflictIt->next();
+                       if (conflict->assigned) {
+                               encodingArray.setExpand(conflict->encoding, true);
+                       }
+               }
+               delete conflictIt;
+               uint encoding=0;
+               for(;encoding<encodingArray.getSize();encoding++) {
+                       //See if this is unassigned
+                       if (!encodingArray.get(encoding))
+                               break;
+               }
+               if (encoding > maxEncodingVal)
+                       maxEncodingVal = encoding;
+               ev->encoding = encoding;
+               ev->assigned = true;
+       }
+}
+
+void EncodingSubGraph::solveComparisons() {
+       HashsetEncodingValue discovered;
+       Vector<EncodingValue *> tovisit;
+       SetIteratorEncodingValue *valIt=values.iterator();
+       while(valIt->hasNext()) {
+               EncodingValue *ev=valIt->next();
+               if (discovered.add(ev)) {
+                       tovisit.push(ev);
+                       while(tovisit.getSize()!=0) {
+                               EncodingValue * val=tovisit.last(); tovisit.pop();
+                               SetIteratorEncodingValue *nextIt=val->larger.iterator();
+                               uint minVal = val->encoding + 1;
+                               while(nextIt->hasNext()) {
+                                       EncodingValue *nextVal=nextIt->next();
+                                       if (nextVal->encoding < minVal) {
+                                               if (minVal > maxEncodingVal)
+                                                       maxEncodingVal = minVal;
+                                               nextVal->encoding = minVal;
+                                               discovered.add(nextVal);
+                                               tovisit.push(nextVal);
+                                       }
+                               }
+                               delete nextIt;
+                       }
+               }
+       }
+       delete valIt;
+}
+
+uint EncodingSubGraph::estimateNewSize(EncodingSubGraph *sg) {
+       uint newSize=0;
+       SetIteratorEncodingNode * nit = sg->nodes.iterator();
+       while(nit->hasNext()) {
+               EncodingNode *en = nit->next();
+               uint size=estimateNewSize(en);
+               if (size > newSize)
+                       newSize = size;
+       }
+       delete nit;
+       return newSize;
+}
+
+uint EncodingSubGraph::estimateNewSize(EncodingNode *n) {
+       SetIteratorEncodingEdge * eeit = n->edges.iterator();
+       uint newsize=n->getSize();
+       while(eeit->hasNext()) {
+               EncodingEdge * ee = eeit->next();
+               if (ee->left != NULL && ee->left != n && nodes.contains(ee->left)) {
+                       uint intersectSize = n->s->getUnionSize(ee->left->s);
+                       if (intersectSize > newsize)
+                               newsize = intersectSize;
+               }
+               if (ee->right != NULL && ee->right != n && nodes.contains(ee->right)) {
+                       uint intersectSize = n->s->getUnionSize(ee->right->s);
+                       if (intersectSize > newsize)
+                               newsize = intersectSize;
+               }
+               if (ee->dst != NULL && ee->dst != n && nodes.contains(ee->dst)) {
+                       uint intersectSize = n->s->getUnionSize(ee->dst->s);
+                       if (intersectSize > newsize)
+                               newsize = intersectSize;
+               }
+       }
+       delete eeit;
+       return newsize;
+}
+
+void EncodingSubGraph::addNode(EncodingNode *n) {
+       nodes.add(n);
+       uint newSize=estimateNewSize(n);
+       numElements += n->elements.getSize();
+       if (newSize > encodingSize)
+               encodingSize=newSize;
+}
+
+SetIteratorEncodingNode * EncodingSubGraph::nodeIterator() {
+       return nodes.iterator();
+}
+
+void EncodingSubGraph::encode() {
+       computeEncodingValue();
+       computeComparisons();
+       computeEqualities();
+       solveComparisons();
+       solveEquals();
+}
+
+void EncodingSubGraph::computeEqualities() {
+       SetIteratorEncodingNode *nodeit=nodes.iterator();
+       while(nodeit->hasNext()) {
+               EncodingNode *node=nodeit->next();
+               generateEquals(node, node);
+               
+               SetIteratorEncodingEdge *edgeit=node->edges.iterator();
+               while(edgeit->hasNext()) {
+                       EncodingEdge *edge=edgeit->next();
+                       //skip over comparisons as we have already handled them
+                       if (edge->numComparisons != 0)
+                               continue;
+                       if (edge->numEquals == 0)
+                               continue;
+                       if (edge->left == NULL || !nodes.contains(edge->left))
+                               continue;
+                       if (edge->right == NULL || !nodes.contains(edge->right))
+                               continue;
+                       //examine only once
+                       if (edge->left != node)
+                               continue;
+                       //We have a comparison edge between two nodes in the subgraph
+                       //For now we don't support multiple encoding values with the same encoding....
+                       //So we enforce != constraints for every Set...
+                       if (edge->left != edge->right)
+                               generateEquals(edge->left, edge->right);
+               }
+               delete edgeit;
+       }
+       delete nodeit;
+}
+
+void EncodingSubGraph::computeComparisons() {
+       SetIteratorEncodingNode *nodeit=nodes.iterator();
+       while(nodeit->hasNext()) {
+               EncodingNode *node=nodeit->next();
+               SetIteratorEncodingEdge *edgeit=node->edges.iterator();
+               while(edgeit->hasNext()) {
+                       EncodingEdge *edge=edgeit->next();
+                       if (edge->numComparisons == 0)
+                               continue;
+                       if (edge->left == NULL || !nodes.contains(edge->left))
+                               continue;
+                       if (edge->right == NULL || !nodes.contains(edge->right))
+                               continue;
+                       //examine only once
+                       if (edge->left != node)
+                               continue;
+                       //We have a comparison edge between two nodes in the subgraph
+                       generateComparison(edge->left, edge->right);
+               }
+               delete edgeit;
+       }
+       delete nodeit;
+       
+       
+}
+
+void EncodingSubGraph::orderEV(EncodingValue *earlier, EncodingValue *later) {
+       earlier->larger.add(later);
+}
+
+void EncodingSubGraph::generateEquals(EncodingNode *left, EncodingNode *right) {
+       Set *lset=left->s;
+       Set *rset=right->s;
+       uint lSize=lset->getSize(), rSize=rset->getSize();
+       for(uint lindex=0; lindex < lSize; lindex++) {
+               for(uint rindex=0; rindex < rSize; rindex++) {
+                       uint64_t lVal=lset->getElement(lindex);
+                       NodeValuePair nvp1(left, lVal);
+                       EncodingValue *lev = map.get(&nvp1);
+                       uint64_t rVal=rset->getElement(rindex);
+                       NodeValuePair nvp2(right, rVal);
+                       EncodingValue *rev = map.get(&nvp2);
+                       if (lev != rev) {
+                               if (lev->inComparison && rev->inComparison) {
+                                       //Need to assign during comparison stage...
+                                       //Thus promote to comparison
+                                       if (lVal < rVal) {
+                                               orderEV(lev, rev);
+                                       } else {
+                                               orderEV(rev, lev);
+                                       }
+                               } else {
+                                       lev->notequals.add(rev);
+                                       rev->notequals.add(lev);
+                               }
+                       }
+               }
+       }
+}
+
+void EncodingSubGraph::generateComparison(EncodingNode *left, EncodingNode *right) {
+       Set *lset=left->s;
+       Set *rset=right->s;
+       uint lindex=0, rindex=0;
+       uint lSize=lset->getSize(), rSize=rset->getSize();
+       uint64_t lVal=lset->getElement(lindex);
+       NodeValuePair nvp1(left, lVal);
+       EncodingValue *lev = map.get(&nvp1);
+       lev->inComparison = true;
+       uint64_t rVal=rset->getElement(rindex);
+       NodeValuePair nvp2(right, rVal);
+       EncodingValue *rev = map.get(&nvp2);
+       rev->inComparison = true;
+       EncodingValue *last = NULL;
+
+       while(lindex < lSize || rindex < rSize) {
+               if (last != NULL) {
+                       if (lev != NULL)
+                               orderEV(last, lev);
+                       if (rev != NULL && lev != rev)
+                               orderEV(last, rev);
+               }
+               if (lev != rev) {
+                       if (rev == NULL || lVal < rVal) {
+                               if (rev != NULL)
+                                       orderEV(lev, rev);
+                               last = lev;
+                               if (++lindex < lSize) {
+                                       lVal=lset->getElement(lindex);
+                                       NodeValuePair nvpl(left, lVal);
+                                       lev = map.get(&nvpl);
+                                       lev->inComparison = true;
+                               } else
+                                       lev = NULL;
+                       } else {
+                               if (lev != NULL)
+                                       orderEV(rev, lev);
+                               last = rev;
+                               if (++rindex < rSize) {
+                                       rVal=rset->getElement(rindex);
+                                       NodeValuePair nvpr(right, rVal);
+                                       rev = map.get(&nvpr);
+                                       rev->inComparison = true;
+                               } else
+                                       rev = NULL;
+                       }
+               } else {
+                       last = lev;
+                       if (++lindex < lSize) {
+                               lVal=lset->getElement(lindex);
+                               NodeValuePair nvpl(left, lVal);
+                               lev = map.get(&nvpl);
+                               lev->inComparison = true;
+                       } else
+                               lev = NULL;
+
+                       if (++rindex < rSize) {
+                               rVal=rset->getElement(rindex);
+                               NodeValuePair nvpr(right, rVal);
+                               rev = map.get(&nvpr);
+                               rev->inComparison = true;
+                       } else
+                               rev = NULL;
+               }
+       }
+}
+
+void EncodingSubGraph::computeEncodingValue() {
+       SetIteratorEncodingNode *nodeit=nodes.iterator();
+       while(nodeit->hasNext()) {
+               EncodingNode *node=nodeit->next();
+               Set * set = node->s;
+               uint setSize = set->getSize();
+               for(uint i=0; i<setSize; i++) {
+                       uint64_t val = set->getElement(i);
+                       NodeValuePair nvp(node, val);
+                       if (!map.contains(&nvp)) {
+                               traverseValue(node, val);
+                       }
+               }
+       }
+       delete nodeit;
+}
+
+void EncodingSubGraph::traverseValue(EncodingNode *node, uint64_t value) {
+       EncodingValue *ecv=new EncodingValue(value);
+       values.add(ecv);
+       HashsetEncodingNode discovered;
+       Vector<EncodingNode *> tovisit;
+       tovisit.push(node);
+       discovered.add(node);
+       while(tovisit.getSize()!=0) {
+               EncodingNode *n=tovisit.last();tovisit.pop();
+               //Add encoding node to structures
+               ecv->nodes.add(n);
+               NodeValuePair *nvp=new NodeValuePair(n, value);
+               map.put(nvp, ecv);
+               SetIteratorEncodingEdge *edgeit=node->edges.iterator();
+               while(edgeit->hasNext()) {
+                       EncodingEdge *ee=edgeit->next();
+                       if (!discovered.contains(ee->left) && nodes.contains(ee->left) && ee->left->s->exists(value)) {
+                               tovisit.push(ee->left);
+                               discovered.add(ee->left);
+                       }
+                       if (!discovered.contains(ee->right) && nodes.contains(ee->right) && ee->right->s->exists(value)) {
+                               tovisit.push(ee->right);
+                               discovered.add(ee->right);
+                       }
+               }
+               delete edgeit;
+       }
+}
+
diff --git a/src/ASTAnalyses/Encoding/subgraph.h b/src/ASTAnalyses/Encoding/subgraph.h
new file mode 100644 (file)
index 0000000..7738445
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef SUBGRAPH_H
+#define SUBGRAPH_H
+#include "classlist.h"
+#include "structs.h"
+#include "graphstructs.h"
+
+class NodeValuePair {
+ public:
+ NodeValuePair(EncodingNode *n, uint64_t val) : node(n), value(val) {}
+       EncodingNode *node;
+       uint64_t value;
+};
+
+class EncodingValue;
+
+typedef Hashset<EncodingValue *, uintptr_t, PTRSHIFT> HashsetEncodingValue;
+typedef SetIterator<EncodingValue *, uintptr_t, PTRSHIFT> SetIteratorEncodingValue;
+
+class EncodingValue {
+ public:
+ EncodingValue(uint64_t _val) : value(_val), encoding(0), inComparison(false), assigned(false) {}
+       void merge(EncodingValue *value);
+       uint64_t value;
+       uint encoding;
+       bool inComparison;
+       bool assigned;
+       HashsetEncodingNode nodes;
+       HashsetEncodingValue larger;
+       HashsetEncodingValue notequals;
+};
+
+uint hashNodeValuePair(NodeValuePair *nvp);
+bool equalsNodeValuePair(NodeValuePair *nvp1, NodeValuePair *nvp2);
+
+typedef Hashtable<NodeValuePair *, EncodingValue *, uintptr_t, 0, hashNodeValuePair, equalsNodeValuePair> NVPMap;
+
+class EncodingSubGraph {
+ public:
+       EncodingSubGraph();
+       void addNode(EncodingNode *n);
+       SetIteratorEncodingNode * nodeIterator();
+       void encode();
+       
+       CMEMALLOC;
+ private:
+       uint estimateNewSize(EncodingNode *n);
+       uint estimateNewSize(EncodingSubGraph *sg);
+       void traverseValue(EncodingNode *node, uint64_t value);
+       void computeEncodingValue();
+       void computeComparisons();
+       void computeEqualities();
+       void solveComparisons();
+       void solveEquals();
+       void generateComparison(EncodingNode *left, EncodingNode *right);
+       void generateEquals(EncodingNode *left, EncodingNode *right);
+       void orderEV(EncodingValue *smaller, EncodingValue *larger);
+
+       HashsetEncodingValue values;
+       HashsetEncodingNode nodes;
+       NVPMap map;
+       uint encodingSize;
+       uint numElements;
+       uint maxEncodingVal;
+       
+       friend class EncodingGraph;
+};
+
+#endif
index 496bdc65613e0586d2ad7de75bff3c8a7ab05422..03d83cd34672f4b83fa92b1f1d0857ac63ac7a46 100644 (file)
@@ -27,7 +27,7 @@ public:
                }
        }
 
-       type get(uint index) {
+       type get(uint index) const {
                return array[index];
        }
 
@@ -35,7 +35,7 @@ public:
                array[index] = item;
        }
 
-       uint getSize() {
+       uint getSize() const {
                return size;
        }
 
index e9164df61bdbe6426fb53093fd0016bae922e82f..2d4cc1956df10579e362966c84371f4f34d5c63f 100644 (file)
@@ -24,7 +24,7 @@ public:
                size--;
        }
 
-       type last() {
+       type last() const {
                return array[size - 1];
        }
 
@@ -49,7 +49,7 @@ public:
                array[size++] = item;
        }
 
-       type get(uint index) {
+       type get(uint index) const {
                return array[index];
        }
 
@@ -63,7 +63,7 @@ public:
                array[index] = item;
        }
 
-       uint getSize() {
+       uint getSize() const {
                return size;
        }
 
index cdba3b2d970e16352e95264db403a8245fa08ec1..13edbf95895e589d88fb4d548e575e7cf677408c 100644 (file)
@@ -205,11 +205,11 @@ public:
                return true;
        }
 
-       unsigned int getSize() {
+       unsigned int getSize() const {
                return table->getSize();
        }
 
-       bool isEmpty() {
+       bool isEmpty() const {
                return getSize() == 0;
        }
 
index ac32d853d7945f5762e795b5df8292a215d4c569..58e7abd3a6d6f94d9782e9aaeb77ebf558ee176a 100644 (file)
@@ -81,7 +81,7 @@
        void setVector ## name(Vector ## name * vector, uint index, type item) { \
                vector->array[index] = item;                                          \
        }                                                                     \
-       uint getSizeVector ## name(Vector ## name * vector) {                  \
+       uint getSizeVector ## name(const Vector ## name * vector) {                                             \
                return vector->size;                                                \
        }                                                                     \
        void deleteVector ## name(Vector ## name * vector) {                     \