fix replacement around macro expansion; add new benchmarks from Stavros Aronis
[satcheck.git] / eprecord.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 "eprecord.h"
11 #include "change.h"
12 #include "model.h"
13 #include "planner.h"
14
15 EPRecord::EPRecord(EventType _event, ExecPoint *_execpoint, EPValue *_branch, uintptr_t _offset, unsigned int _numinputs, uint _len, bool _anyvalue) :
16         valuevector(new ValueVector()),
17         execpoint(_execpoint),
18         completed(NULL),
19         branch(_branch),
20         setarray((IntHashSet **)model_malloc(sizeof(IntHashSet *)*(_numinputs+VC_BASEINDEX))),
21         nextRecord(NULL),
22         childRecord(NULL),
23         philooptable(NULL),
24         offset(_offset),
25         event(_event),
26         jointhread(THREAD_ID_T_NONE),
27         numinputs(_numinputs+VC_BASEINDEX),
28         len(_len),
29         anyvalue(_anyvalue),
30         phi(false),
31         loopphi(false),
32         size(0),
33         func_shares_goalset(false),
34         ptr(NULL)
35 {
36         for(unsigned int i=0;i<numinputs;i++)
37                 setarray[i]=new IntHashSet();
38 }
39
40 EPRecord::~EPRecord() {
41         if (!func_shares_goalset && (completed != NULL))
42                 delete completed;
43         delete valuevector;
44         if (completed != NULL)
45                 delete completed;
46         if (philooptable!=NULL) {
47                 EPRecordIDIterator *rit=philooptable->iterator();
48                 while(rit->hasNext()) {
49                         struct RecordIDPair *val=rit->next();
50                         model_free(val);
51                 }
52                 delete rit;
53                 delete philooptable;
54         }
55         model_free(setarray);
56 }
57
58 const char * eventToStr(EventType event) {
59         switch(event) {
60         case ALLOC:
61                 return "alloc";
62         case LOAD:
63                 return "load";
64         case RMW:
65                 return "rmw";
66         case STORE:
67                 return "store";
68         case BRANCHDIR:
69                 return "br_dir";
70         case MERGE:
71                 return "merge";
72         case FUNCTION:
73                 return "func";
74         case EQUALS:
75                 return "equals";
76         case THREADCREATE:
77                 return "thr_create";
78         case THREADBEGIN:
79                 return "thr_begin";
80         case THREADJOIN:
81                 return "join";
82         case YIELD:
83                 return "yield";
84         case NONLOCALTRANS:
85                 return "nonlocal";
86         case LABEL:
87                 return "label";
88         case LOOPENTER:
89                 return "loopenter";
90         case LOOPSTART:
91                 return "loopstart";
92         case FENCE:
93                 return "fence";
94         default:
95                 return "unknown";
96         }
97 }
98
99 IntHashSet * EPRecord::getReturnValueSet() {
100         switch(event) {
101         case FUNCTION:
102         case EQUALS:
103                 return getSet(VC_FUNCOUTINDEX);
104         case RMW:
105                 return getSet(VC_RMWOUTINDEX);
106         case LOAD:
107                 return getSet(VC_RFINDEX);
108         case ALLOC:
109         case BRANCHDIR:
110         case MERGE:
111         case STORE:
112         case THREADCREATE:
113         case THREADBEGIN:
114         case THREADJOIN:
115         case YIELD:
116         case FENCE:
117         case NONLOCALTRANS:
118         case LABEL:
119         case LOOPENTER:
120         case LOOPSTART:
121                 ASSERT(false);
122                 return NULL;
123         default:
124                 ASSERT(false);
125                 return NULL;
126         }
127 }
128
129 void EPRecord::print(int f) {
130         if (event==RMW) {
131                 if (op==ADD)
132                         dprintf(f, "add");
133                 else if (op==EXC)
134                         dprintf(f, "exc");
135                 else
136                         dprintf(f, "cas");
137         } else
138                 dprintf(f, "%s",eventToStr(event));
139         IntHashSet *i=NULL;
140         switch(event) {
141         case LOAD:
142                 i=setarray[VC_RFINDEX];
143                 break;
144         case STORE:
145                 i=setarray[VC_BASEINDEX];
146                 break;
147         case RMW:
148                 i=setarray[VC_RMWOUTINDEX];
149                 break;
150         case FUNCTION: {
151                 if (!getPhi()) {
152                         CGoalIterator *cit=completed->iterator();
153                         dprintf(f, "{");
154                         while(cit->hasNext()) {
155                                 CGoal *goal=cit->next();
156                                 dprintf(f,"(");
157                                 for(uint i=0;i<getNumFuncInputs();i++) {
158                                         dprintf(f,"%lu ", goal->getValue(i+VC_BASEINDEX));
159                                 }
160                                 dprintf(f,"=> %lu)", goal->getOutput());
161                         }
162                         delete cit;
163                 }
164                 break;
165         }
166         default:
167                 ;
168         }
169         if (i!=NULL) {
170                 IntIterator *it=i->iterator();
171                 dprintf(f, "{");
172
173                 while(it->hasNext()) {
174                         dprintf(f, "%lu ", it->next());
175                 }
176                 dprintf(f, "}");
177                 delete it;
178         }
179
180         for(uint i=0;i<numinputs;i++) {
181                 IntIterator *it=setarray[i]->iterator();
182                 dprintf(f,"{");
183                 while(it->hasNext()) {
184                         uint64_t v=it->next();
185                         dprintf(f,"%lu ", v);
186                 }
187                 dprintf(f,"}");
188                 delete it;
189         }
190         dprintf(f, "}");
191
192         
193         execpoint->print(f);
194 }
195
196 void EPRecord::print() {
197         model_print("%s",eventToStr(event));
198         execpoint->print();
199         model_print(" CR=%p ", this);
200         model_print(" NR=%p", nextRecord);
201 }
202
203 bool EPRecord::hasAddr(const void * addr) {
204         return getSet(VC_ADDRINDEX)->contains((uintptr_t)addr);
205 }
206
207 int EPRecord::getIndex(EPValue *val) {
208         for(unsigned int i=0;i<valuevector->size();i++) {
209                 EPValue *epv=(*valuevector)[i];
210                 if (epv==val)
211                         return i;
212         }
213         return -1;
214 }
215
216 int EPRecord::getIndex(uint64_t val) {
217         for(unsigned int i=0;i<valuevector->size();i++) {
218                 EPValue *epv=(*valuevector)[i];
219                 if (epv->getValue()==val)
220                         return i;
221         }
222         return -1;
223 }
224
225 bool EPRecord::hasValue(uint64_t val) {
226         for(unsigned int i=0;i<valuevector->size();i++) {
227                 EPValue *epv=(*valuevector)[i];
228                 if (epv->getValue()==val)
229                         return true;
230         }
231         return false;
232 }
233
234 bool compatibleStoreLoad(EPRecord *store, EPRecord *load) {
235         return true;
236 }