ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
steensgaard.h
Go to the documentation of this file.
1 #ifndef STEENSGAARD_H
2 #define STEENSGAARD_H
3 
4 /******Author: Qing Yi, Andrew Long 2007 ********/
5 
6 #include <union_find.h>
7 #include <list>
8 #include <map>
9 #include <string>
10 #include <iostream>
11 #include <assert.h>
12 
13 #define BOT NULL
14 
15 class ECR;
16 struct Lambda {
17  std::list<ECR *> inParams, outParams;
18  std::list<ECR*>& get_inParams() { return inParams; }
19  std::list<ECR*>& get_outParams() { return outParams; }
20 }; ;
21 
22 class ECR : public UF_elem
23 {
26  std::list<ECR *> pending;
28  { return static_cast<ECR*>(UF_elem::find_group()); }
29 
30 
31 public:
32  ECR() : UF_elem(), type(BOT), lambda(BOT) {}
33  ~ECR() {}
34 
35  ECR * union_with(ECR *that) {
36  UF_elem::union_with(that);
37  return static_cast<ECR*>(UF_elem::find_group());
38  }
39 
40  ECR* get_ecr() { return find_group(); }
41  ECR* get_type() {
42  ECR* g = find_group();
43  return (g->type)? g->type->find_group() : g->type;
44  }
45  void set_type(ECR *that) {
46  ECR* g = find_group();
47  g->type = that;
48  }
49  std::list<ECR*>& get_pending() {return find_group()->pending;}
50  Lambda* get_lambda() { return lambda; }
51  void set_lambda(Lambda* l) { lambda = l; }
52 };
53 
54 #define Variable std::string
55 class ECRmap {
56  public:
58  public:
60  VariableAlreadyDefined(const Variable& _var) : var(_var) {}
61  };
62 
63  // x = y
64  void x_eq_y(Variable x, Variable y) {
65  ECR* t1 = get_ECR(x)->get_type();
66  ECR* t2 = get_ECR(y)->get_type();
67  if (t1 != t2)
68  cjoin(t1, t2);
69  }
70  // x = & y
72  ECR * t1 = get_ECR(x)->get_type();
73  ECR * t2 = get_ECR(y);
74  if (t1 != t2) {
75  join(t1, t2);
76  }
77  }
78  // x = *y
80  ECR* t1 = get_ECR(x)->get_type();
81  ECR* t2 = get_ECR(y)->get_type();
82  if (t2->get_type() == BOT) {
83  set_type(t2, t1);
84  }
85  else {
86  ECR* t3 = t2->get_type();
87  if (t1 != t3) {
88  cjoin(t1, t3);
89  }
90  }
91  }
92  // x = op(y1,...yn)
93  void x_eq_op_y(Variable x, const std::list<Variable>& y) {
94  ECR* t1 = get_ECR(x)->get_type();
95  for (std::list<Variable>::const_iterator yp = y.begin();
96  yp != y.end(); ++yp) {
97  ECR* t2 = get_ECR(*yp)->get_type();
98  if (t1 != t2) cjoin(t1, t2);
99  }
100  }
101  // allocate(x)
102  void allocate(Variable x) {
103  ECR* t = get_ECR(x)->get_type();
104  if (t->get_type() == BOT) {
105  ECR* res = new_ECR();
106  set_type(t,res);
107  }
108  }
109  // *x = y
111  ECR* t1 = get_ECR(x)->get_type();
112  ECR* t2 = get_ECR(y)->get_type();
113  if (t1->get_type() == BOT) {
114  set_type(t1, t2);
115  }
116  else {
117  ECR* t3 = t1->get_type();
118  if (t2 != t3)
119  cjoin(t3, t2);
120  }
121  }
122  // outParams = x (inparams)
123  void function_def_x(Variable x, const std::list<Variable>& inParams, const std::list<Variable>& outParams)
124  {
125  ECR* t = get_ECR(x)->get_type();
126  Lambda* l = t->get_lambda();
127  if (l == BOT) {
128  l = new_Lambda();
129  set_lambda(l,inParams, outParams);
130  t->set_lambda(l);
131  }
132  else {
133  std::list<ECR *>::const_iterator p1=l->get_inParams().begin();
134  std::list<Variable>::const_iterator p2=inParams.begin();
135  for ( ; p1 != l->get_inParams().end(); ++p1,++p2) {
136  assert(p2 != inParams.end());
137  join(*p1, get_ECR(*p2)->get_type());
138  }
139  assert(p2 == inParams.end());
140  p1=l->get_outParams().begin();
141  p2=outParams.begin();
142  for ( ; p1 != l->get_outParams().end(); ++p1,++p2) {
143  assert(p2 != outParams.end());
144  join(*p1, get_ECR(*p2)->get_type());
145  }
146  assert(p2 == outParams.end());
147  }
148  }
149  // x = p (y)
150  void function_call_p(Variable p, const std::list<Variable>& x, const std::list<Variable>& y)
151  {
152  ECR* t = get_ECR(p)->get_type();
153  Lambda* l = t->get_lambda();
154  if (l == BOT) {
155  l = new_Lambda();
156  set_lambda(l,y,x);
157  t->set_lambda(l);
158  }
159  else {
160  std::list<ECR *>::const_iterator p1=l->get_inParams().begin();
161  std::list<Variable>::const_iterator p2=y.begin();
162  for ( ; p1 != l->get_inParams().end(); ++p1,++p2) {
163  assert(p2 != y.end());
164  ECR* cur = *p1;
165  assert(cur != 0);
166  Variable v2 = *p2;
167  if (v2 != "")
168  join(cur->get_ecr(), get_ECR(v2)->get_type());
169  }
170  assert(p2 == y.end());
171  p1=l->get_outParams().begin();
172  p2=x.begin();
173  for ( ; p1 != l->get_outParams().end(); ++p1,++p2) {
174  assert(p2 != x.end());
175  ECR* cur = *p1;
176  assert(cur != 0);
177  Variable v2 = *p2;
178  if ( v2 != "")
179  join(get_ECR(v2)->get_type(), cur->get_ecr());
180  }
181  assert(p2 == x.end());
182  }
183  }
184 
185  virtual void dump() { output(std::cerr); }
186  int find_LOC(std::ostream& out, std::map<ECR*, int>& locmap, int& loc, ECR* p)
187  {
188  int cur = -1;
189  std::map<ECR*, int>::const_iterator p1 = locmap.find(p);
190  if (p1 == locmap.end()) {
191  locmap[p] = ++loc;
192  cur = loc;
193  }
194  else
195  cur = p1->second;
196  return cur;
197  }
198  void outputLOC(std::ostream& out, std::map<ECR*, int>& locmap, int& loc, ECR* p) {
199  int max = 0;
200  out << " LOC" << find_LOC(out,locmap,loc,p);
201  for (;;) {
202  p = p->get_type();
203  if (p == 0) break;
204  int cur = find_LOC(out,locmap,loc,p);
205  if (max < 0) break;
206  else if (cur <= max) max = -1;
207  else max = cur;
208  out << "=>" << "LOC" << cur << " ";
209  if (p ->get_pending().size() != 0) {
210  out << "(pending ";
211  for (std::list<ECR*>::const_iterator pp=p->get_pending().begin();
212  pp != p->get_pending().end(); ++pp)
213  outputLOC(out,locmap, loc, (*pp)->get_ecr());
214  out << ") ";
215  }
216  Lambda* t = p->get_lambda();
217  if (t != 0) {
218  out << "(inparams: ";
219  for (std::list<ECR*>::const_iterator pp=t->get_inParams().begin();
220  pp != t->get_inParams().end(); ++pp)
221  outputLOC(out,locmap,loc,(*pp)->get_ecr());
222  out << ") ";
223  out << "->(outparams: ";
224  for (std::list<ECR*>::const_iterator pp=t->get_outParams().begin();
225  pp != t->get_outParams().end(); ++pp)
226  outputLOC(out,locmap,loc,(*pp)->get_ecr());
227  out << ") ";
228  }
229  }
230  }
231 
232  void output(std::ostream& out) {
233  std::map<ECR*, int> locmap;
234  int loc = 0;
235  for (std::map<Variable, ECR*>::iterator
236  itMap = table.begin(); itMap != table.end(); itMap++) {
237  ECR* p = itMap->second->get_ecr();
238  out << itMap->first ;
239  outputLOC(out,locmap,loc,p);
240  out << "\n";
241  }
242  }
243 
245  if (table.find(x) == table.end() || table.find(y) == table.end())
246  return false;
247 
248  if (table[x]->get_type() == table[y]->get_type())
249  return true;
250  else
251  return false;
252  }
253  virtual ~ECRmap() {
254  for (std::list<ECR*>::const_iterator p = ecrList.begin();
255  p != ecrList.end(); ++p) {
256  delete (*p);
257  }
258  }
259 
260  private:
261  std::map<Variable, ECR*> table;
262  std::list<ECR*> ecrList;
263  std::list<Lambda> lambdaList;
265  assert(x != "");
266  std::map<Variable, ECR*>::const_iterator p = table.find(x);
267  ECR* res = 0;
268  if (p == table.end()) {
269  res = new_ECR();
270  table[x] = res;
271  }
272  else
273  res = (*p).second;
274  if (res->get_type() == 0)
275  res->set_type(new_ECR());
276  return res;
277  }
279  ecrList.push_back(new ECR());
280  return ecrList.back();
281  }
283  lambdaList.push_back(Lambda());
284  return &lambdaList.back();
285  }
286  void set_lambda(Lambda* l,const std::list<Variable>& inParams, const std::list<Variable>& outParams) {
287  for (std::list<Variable>::const_iterator p = inParams.begin();
288  p != inParams.end(); ++p) {
289  Variable cur = *p;
290  if (cur != "")
291  l->get_inParams().push_back(get_ECR(cur)->get_type());
292  else l->get_inParams().push_back(0);
293  }
294  for (std::list<Variable>::const_iterator p2 = outParams.begin();
295  p2 != outParams.end(); ++p2) {
296  Variable cur = *p2;
297  if (cur != "")
298  l->get_outParams().push_back(get_ECR(cur)->get_type());
299  else
300  l->get_outParams().push_back(new_ECR());
301  }
302  }
303  void set_type(ECR * e, ECR * t) {
304  e->set_type(t);
305  assert(t != BOT && e->get_type() == t);
306  std::list<ECR*> pending = e->get_pending();
307  if (pending.size()) {
308  for (std::list<ECR*>::const_iterator p=pending.begin();
309  p != pending.end(); ++p)
310  join(t, *p);
311  e->get_pending().clear();
312  }
313  }
314 
315  void cjoin(ECR* e1, ECR* e2) {
316  if (e2->get_type() == BOT) {
317  e2->get_pending().push_back(e1);
318  }
319  else
320  join(e1, e2);
321  }
322 
323  void unify_lambda(Lambda* l1, Lambda* l2)
324  {
325  std::list<ECR *>::const_iterator p1=l1->get_inParams().begin();
326  std::list<ECR *>::const_iterator p2=l2->get_inParams().begin();
327  for ( ; p1 != l1->get_inParams().end(); ++p1,++p2) {
328  assert(p2 != l2->get_inParams().end());
329  join(*p1, *p2);
330  }
331  assert(p2 == l2->get_inParams().end());
332  p1=l1->get_outParams().begin();
333  p2=l2->get_outParams().begin();
334  for ( ; p1 != l1->get_outParams().end(); ++p1,++p2) {
335  assert(p2 != l2->get_outParams().end());
336  join(*p1, *p2);
337  }
338  assert(p2 == l2->get_outParams().end());
339  }
340  void unify(ECR * t1, ECR * t2) {
341  assert(t1 != 0 && t2 != 0);
342  Lambda* l1 = t1->get_lambda();
343  Lambda* l2 = t2->get_lambda();
344  if (l1 && l2) {
345  unify_lambda(l1,l2);
346  }
347  join(t1,t2);
348  }
349 
350  void join(ECR * e1, ECR * e2) {
351  e1 = e1->get_ecr();
352  e2 = e2->get_ecr();
353  if (e1 == e2) return;
354  ECR* t1 = e1->get_type();
355  ECR* t2 = e2->get_type();
356  Lambda* l1 = e1->get_lambda();
357  Lambda* l2 = e2->get_lambda();
358  std::list<ECR*> *pending1 = &e1->get_pending(), *pending2 = &e2->get_pending();
359  ECR* e = e1->union_with(e2);
360  if (l1 == BOT) {
361  if (l2 != BOT)
362  e->set_lambda(l2);
363  }
364  else {
365  e->set_lambda(l1);
366  if (l2 != BOT)
367  unify_lambda(l1,l2);
368  }
369 
370  std::list<ECR*> *pending = &e->get_pending();
371 
372  if (t1 == BOT) {
373  e->set_type(t2);
374  if (t2 == BOT) {
375  if (e == e2) {
376  assert(pending != pending1);
377  pending->insert(pending->end(), pending1->begin(), pending1->end());
378  }
379  else if (e == e1) {
380  assert(pending != pending2);
381  pending->insert(pending->end(), pending2->begin(), pending2->end());
382  }
383  else {
384  assert(pending != pending2 && pending != pending1);
385  *pending = *pending1;
386  pending->insert(pending->end(), pending2->begin(), pending2->end());
387  }
388  }
389  else {
390  if (pending1->size()) {
391  for (std::list<ECR*>::const_iterator p=pending1->begin();
392  p != pending1->end(); ++p)
393  join(e, *p);
394  }
395  pending->clear();
396  }
397  }
398  else {
399  e->set_type(t1);
400  if (t2 == BOT) {
401  if (pending2->size()) {
402  for (std::list<ECR*>::const_iterator p=pending2->begin();
403  p != pending2->end(); ++p)
404  join(e, *p);
405  }
406  }
407  else
408  unify(t1, t2);
409  pending->clear();
410  }
411  }
412 };
413 
414 #endif