Fix yield bug
[satcheck.git] / execpoint.cc
1 /*      Copyright (c) 2015 Regents of the University of California
2  *
3  *      Author: Brian Demsky <bdemsky@uci.edu>
4  *
5  *      This program is free software; you can redistribute it and/or
6  *      modify it under the terms of the GNU General Public License
7  *      version 2 as published by the Free Software Foundation.
8  */
9
10 #include "execpoint.h"
11 #include "mymemory.h"
12 #include <string.h>
13 #include "mcutil.h"
14 #include "common.h"
15 #include <stdlib.h>
16
17 ExecPoint::ExecPoint(int _length, thread_id_t thread_id) :
18         length(_length<<1),
19         size(0),
20         pairarray((execcount_t *)model_malloc(sizeof(execcount_t)*length)),
21         hashvalue(id_to_int(thread_id)),
22         tid(thread_id)
23 {
24 }
25
26 ExecPoint::ExecPoint(ExecPoint *e) :
27         length(e->size),
28         size(e->size),
29         pairarray((execcount_t *)model_malloc(sizeof(execcount_t)*length)),
30         hashvalue(e->hashvalue),
31         tid(e->tid)
32 {
33         memcpy(pairarray, e->pairarray, sizeof(execcount_t)*length);
34 }
35
36 ExecPoint::~ExecPoint() {
37         model_free(pairarray);
38 }
39
40 void ExecPoint::reset() {
41         size=0;
42         hashvalue=id_to_int(tid);
43 }
44
45 /** Return CR_AFTER means that ep occurs after this.
46                 Return CR_BEFORE means tha te occurs before this.
47                 Return CR_EQUALS means that they are the same point.
48                 Return CR_INCOMPARABLE means that they are not comparable.
49  */
50
51 CompareResult ExecPoint::compare(const ExecPoint * ep) const {
52         if (this==ep)
53                 return CR_EQUALS;
54         unsigned int minsize=(size<ep->size) ? size : ep->size;
55         for(unsigned int i=0;i<minsize;i+=2) {
56                 ASSERT(pairarray[i]==ep->pairarray[i]);
57                 if (pairarray[i+1]!=ep->pairarray[i+1]) {
58                         //we have a difference
59                         if (pairarray[i]==EP_BRANCH)
60                                 return CR_INCOMPARABLE;
61                         else if (pairarray[i+1]<ep->pairarray[i+1])
62                                 return CR_AFTER;
63                         else
64                                 return CR_BEFORE;
65                 }
66         }
67         if (size < ep->size)
68                 return CR_AFTER;
69         else if (size > ep->size)
70                 return CR_BEFORE;
71         else
72                 return CR_EQUALS;
73 }
74
75 void ExecPoint::pop() {
76         hashvalue = rotate_right((hashvalue ^ pairarray[size-1]), 3);
77         size-=2;
78 }
79
80 bool ExecPoint::directInLoop() {
81         return ((ExecPointType)pairarray[size-4])==EP_LOOP;
82 }
83
84 bool ExecPoint::inLoop() {
85         int index;
86         for(index=size-2;index>0;index-=2) {
87                 if ((ExecPointType)pairarray[index]==EP_LOOP)
88                         return true;
89         }
90         return false;
91 }
92
93 ExecPointType ExecPoint::getType() {
94         return (ExecPointType)pairarray[size-2];
95 }
96
97 void ExecPoint::push(ExecPointType type, execcount_t value) {
98         if (size==length) {
99                 length=length<<1;
100                 execcount_t *tmp=(execcount_t *)model_malloc(sizeof(execcount_t)*length);
101                 memcpy(tmp, pairarray, sizeof(execcount_t)*size);
102                 model_free(pairarray);
103                 pairarray=tmp;
104         }
105         hashvalue = rotate_left(hashvalue, 3) ^ value;
106         pairarray[size++]=type;
107         pairarray[size++]=value;
108 }
109
110 void ExecPoint::incrementTop() {
111         execcount_t current=pairarray[size-1];
112         hashvalue = hashvalue ^ current ^ (current+1);
113         pairarray[size-1]=current+1;
114 }
115
116 unsigned int ExecPointHash(ExecPoint *e) {
117         return e->hashvalue;
118 }
119
120 bool ExecPointEquals(ExecPoint *e1, ExecPoint * e2) {
121         if (e1 == NULL)
122                 return e2==NULL;
123         if (e1->tid != e2->tid || e1->size != e2->size || e1->hashvalue != e2->hashvalue)
124                 return false;
125         for(unsigned int i=0;i<e1->size;i++) {
126                 if (e1->pairarray[i]!=e2->pairarray[i])
127                         return false;
128         }
129         return true;
130 }
131
132 void ExecPoint::print(int f) {
133         model_dprintf(f,"<tid=%u,",tid);
134         for(unsigned int i=0;i<size;i+=2) {
135                 switch((ExecPointType)pairarray[i]) {
136                 case EP_BRANCH:
137                         model_dprintf(f,"br");
138                         break;
139                 case EP_COUNTER:
140                         model_dprintf(f,"cnt");
141                         break;
142                 case EP_LOOP:
143                         model_dprintf(f,"lp");
144                         break;
145                 default:
146                         ASSERT(false);
147                 }
148                 model_dprintf(f, "(%u)", pairarray[i+1]);
149                 if ((i+2)<size)
150                         model_dprintf(f, ", ");
151         }
152         model_dprintf(f, ">");
153 }
154
155 void ExecPoint::print() {
156         model_print("<tid=%u,",tid);
157         for(unsigned int i=0;i<size;i+=2) {
158                 switch((ExecPointType)pairarray[i]) {
159                 case EP_BRANCH:
160                         model_print("br");
161                         break;
162                 case EP_COUNTER:
163                         model_print("cnt");
164                         break;
165                 case EP_LOOP:
166                         model_print("lp");
167                         break;
168                 default:
169                         ASSERT(false);
170                 }
171                 model_print("(%u)", pairarray[i+1]);
172                 if ((i+2)<size)
173                         model_print(", ");
174         }
175         model_print(">");
176 }