1 /***** tl_spin: tl_cache.c *****/
4 * This file is part of the public release of Spin. It is subject to the
5 * terms in the LICENSE file that is included in this source directory.
6 * Tool documentation is available at http://spinroot.com
8 * Based on the translation algorithm by Gerth, Peled, Vardi, and Wolper,
9 * presented at the PSTV Conference, held in 1995, Warsaw, Poland 1995.
14 typedef struct Cache {
21 static Cache *stored = (Cache *) 0;
22 static unsigned long Caches, CacheHits;
24 static int ismatch(Node *, Node *);
25 static int sameform(Node *, Node *);
27 extern void fatal(char *, char *);
42 printf("\nCACHE DUMP:\n");
43 for (d = stored; d; d = d->nxt, nr++)
44 { if (d->same) continue;
45 printf("B%3d: ", nr); dump(d->before); printf("\n");
46 printf("A%3d: ", nr); dump(d->after); printf("\n");
48 printf("============\n");
56 for (d = stored; d; d = d->nxt, nr++)
57 if (isequal(d->before, n))
59 if (d->same && ismatch(n, d->before)) return n;
60 return dupnode(d->after);
71 if ((m = in_cache(n)) != ZN)
75 d = (Cache *) tl_emalloc(sizeof(Cache));
76 d->before = dupnode(n);
77 d->after = Canonical(n); /* n is released */
79 if (ismatch(d->before, d->after))
81 releasenode(1, d->after);
86 return dupnode(d->after);
92 printf("cache stores : %9ld\n", Caches);
93 printf("cache hits : %9ld\n", CacheHits);
97 releasenode(int all_levels, Node *n)
102 { releasenode(1, n->lft);
104 releasenode(1, n->rgt);
111 tl_nn(int t, Node *ll, Node *rl)
112 { Node *n = (Node *) tl_emalloc(sizeof(Node));
127 n = (Node *) tl_emalloc(sizeof(Node));
129 n->sym = p->sym; /* same name */
142 d->lft = dupnode(n->lft);
143 d->rgt = dupnode(n->rgt);
148 one_lft(int ntyp, Node *x, Node *in)
156 if (in->ntyp != ntyp)
159 if (one_lft(ntyp, x, in->lft))
162 return one_lft(ntyp, x, in->rgt);
166 all_lfts(int ntyp, Node *from, Node *in)
170 if (from->ntyp != ntyp)
171 return one_lft(ntyp, from, in);
173 if (!one_lft(ntyp, from->lft, in))
176 return all_lfts(ntyp, from->rgt, in);
180 sametrees(int ntyp, Node *a, Node *b)
181 { /* toplevel is an AND or OR */
182 /* both trees are right-linked, but the leafs */
183 /* can be in different places in the two trees */
185 if (!all_lfts(ntyp, a, b))
188 return all_lfts(ntyp, b, a);
191 static int /* a better isequal() */
192 sameform(Node *a, Node *b)
194 if (!a && !b) return 1;
195 if (!a || !b) return 0;
196 if (a->ntyp != b->ntyp) return 0;
200 && strcmp(a->sym->name, b->sym->name) != 0)
208 if (!a->sym || !b->sym) fatal("sameform...", (char *) 0);
209 return !strcmp(a->sym->name, b->sym->name);
216 return sameform(a->lft, b->lft);
219 if (!sameform(a->lft, b->lft))
221 if (!sameform(a->rgt, b->rgt))
226 case OR: /* the hard case */
227 return sametrees(a->ntyp, a, b);
230 printf("type: %d\n", a->ntyp);
231 fatal("cannot happen, sameform", (char *) 0);
238 isequal(Node *a, Node *b)
245 { if (b->ntyp == TRUE)
248 { if (a->ntyp == TRUE)
253 if (a->ntyp != b->ntyp)
258 && strcmp(a->sym->name, b->sym->name) != 0)
261 if (isequal(a->lft, b->lft)
262 && isequal(a->rgt, b->rgt))
265 return sameform(a, b);
269 ismatch(Node *a, Node *b)
271 if (!a && !b) return 1;
272 if (!a || !b) return 0;
273 if (a->ntyp != b->ntyp) return 0;
277 && strcmp(a->sym->name, b->sym->name) != 0)
280 if (ismatch(a->lft, b->lft)
281 && ismatch(a->rgt, b->rgt))
288 any_term(Node *srch, Node *in)
293 return any_term(srch, in->lft) ||
294 any_term(srch, in->rgt);
296 return isequal(in, srch);
300 any_and(Node *srch, Node *in)
304 if (srch->ntyp == AND)
305 return any_and(srch->lft, in) &&
306 any_and(srch->rgt, in);
308 return any_term(srch, in);
312 any_lor(Node *srch, Node *in)
317 return any_lor(srch, in->lft) ||
318 any_lor(srch, in->rgt);
320 return isequal(in, srch);
324 anywhere(int tok, Node *srch, Node *in)
329 case AND: return any_and(srch, in);
330 case OR: return any_lor(srch, in);
331 case 0: return any_term(srch, in);
333 fatal("cannot happen, anywhere", (char *) 0);