bug fixes
[satune.git] / src / AST / asthash.cc
1 #include "asthash.h"
2 #include "mymemory.h"
3 #include "structs.h"
4 #include "boolean.h"
5 #include "element.h"
6
7 #define HASHNEXT(hash, newval) {hash += newval; hash += hash << 10; hash ^= hash >> 6;}
8 #define HASHFINAL(hash) {hash += hash << 3; hash ^= hash >> 11; hash += hash << 15;}
9
10 bool compareArray(Array<BooleanEdge> *inputs1, Array<BooleanEdge> *inputs2) {
11         if (inputs1->getSize() != inputs2->getSize())
12                 return false;
13         for (uint i = 0; i < inputs1->getSize(); i++) {
14                 if (inputs1->get(i) != inputs2->get(i))
15                         return false;
16         }
17         return true;
18 }
19
20 bool compareArray(Array<Element *> *inputs1, Array<Element *> *inputs2) {
21         if (inputs1->getSize() != inputs2->getSize())
22                 return false;
23         for (uint i = 0; i < inputs1->getSize(); i++) {
24                 if (inputs1->get(i) != inputs2->get(i))
25                         return false;
26         }
27         return true;
28 }
29
30 uint hashArray(Array<BooleanEdge> *inputs) {
31         uint hash = 0;
32         for (uint i = 0; i < inputs->getSize(); i++) {
33                 uint newval = (uint)(uintptr_t) inputs->get(i).getRaw();
34                 HASHNEXT(hash, newval);
35         }
36         HASHFINAL(hash);
37         return hash;
38 }
39
40 uint hashArray(Array<Element *> *inputs) {
41         uint hash = 0;
42         for (uint i = 0; i < inputs->getSize(); i++) {
43                 uint newval = (uint)(uintptr_t) inputs->get(i);
44                 HASHNEXT(hash, newval);
45         }
46         HASHFINAL(hash);
47         return hash;
48 }
49
50 uint hashBoolean(Boolean *b) {
51         switch (b->type) {
52         case ORDERCONST: {
53                 BooleanOrder *o = (BooleanOrder *)b;
54                 uint hash = 0;
55                 HASHNEXT(hash, (uint) o->first);
56                 HASHNEXT(hash, (uint) o->second);
57                 HASHNEXT(hash, (((uint)(uintptr_t) o->order) & 0xffff));
58                 HASHFINAL(hash);
59                 return hash;
60         }
61
62         case BOOLEANVAR: {
63                 return (uint)(uintptr_t) b;
64         }
65         case LOGICOP: {
66                 BooleanLogic *l = (BooleanLogic *)b;
67                 return ((uint)l->op) + 43 * hashArray(&l->inputs);
68         }
69         case PREDICATEOP: {
70                 BooleanPredicate *p = (BooleanPredicate *)b;
71                 uint hash = 0;
72                 HASHNEXT(hash, hashArray(&p->inputs));
73                 HASHNEXT(hash, (uint)(uintptr_t) p->predicate);
74                 HASHNEXT(hash, (uint)(uintptr_t) p->undefStatus);
75                 HASHFINAL(hash);
76                 return hash;
77         }
78         default:
79                 ASSERT(0);
80         }
81 }
82
83 bool compareBoolean(Boolean *b1, Boolean *b2) {
84         if (b1->type != b2->type)
85                 return false;
86         switch (b1->type) {
87         case ORDERCONST: {
88                 BooleanOrder *o1 = (BooleanOrder *)b1;
89                 BooleanOrder *o2 = (BooleanOrder *)b2;
90                 return (o1->order == o2->order) && (o1->first == o2->first) && (o1->second == o2->second);
91         }
92         case BOOLEANVAR: {
93                 return b1 == b2;
94         }
95         case LOGICOP: {
96                 BooleanLogic *l1 = (BooleanLogic *)b1;
97                 BooleanLogic *l2 = (BooleanLogic *)b2;
98                 return (l1->op == l2->op) && compareArray(&l1->inputs, &l2->inputs);
99         }
100         case PREDICATEOP: {
101                 BooleanPredicate *p1 = (BooleanPredicate *)b1;
102                 BooleanPredicate *p2 = (BooleanPredicate *)b2;
103                 return (p1->predicate == p2->predicate) &&
104                                          p1->undefStatus == p2->undefStatus &&
105                                          compareArray(&p1->inputs, &p2->inputs);
106         }
107         default:
108                 ASSERT(0);
109         }
110 }
111
112 uint hashElement(Element *e) {
113         switch (e->type) {
114         case ELEMSET: {
115                 return (uint)(uintptr_t) e;
116         }
117         case ELEMFUNCRETURN: {
118                 ElementFunction *ef = (ElementFunction *) e;
119                 uint hash = 0;
120                 HASHNEXT(hash, hashArray (&ef->inputs));
121                 HASHNEXT(hash, (uint)(uintptr_t) ef->getFunction());
122                 HASHNEXT(hash, (uint)(uintptr_t) ef->overflowstatus);
123                 HASHFINAL(hash);
124                 return hash;
125         }
126         case ELEMCONST: {
127                 ElementConst *ec = (ElementConst *) e;
128                 return ((uint) ec->value);
129         }
130         default:
131                 ASSERT(0);
132         }
133 }
134
135 bool compareElement(Element *e1, Element *e2) {
136         if (e1->type != e2->type)
137                 return false;
138         switch (e1->type) {
139         case ELEMSET: {
140                 return e1 == e2;
141         }
142         case ELEMFUNCRETURN: {
143                 ElementFunction *ef1 = (ElementFunction *) e1;
144                 ElementFunction *ef2 = (ElementFunction *) e2;
145                 return (ef1->getFunction() == ef2->getFunction()) &&
146                                          (ef1->overflowstatus == ef2->overflowstatus) &&
147                                          compareArray(&ef1->inputs, &ef2->inputs);
148         }
149         case ELEMCONST: {
150                 ElementConst *ec1 = (ElementConst *) e1;
151                 ElementConst *ec2 = (ElementConst *) e2;
152                 return (ec1->value == ec2->value);
153         }
154         default:
155                 ASSERT(0);
156         }
157 }