ref: a07a52d75ed87ab92e5985f553a41d8bbff11d24
parent: 5c5b656a306888ea563f10c911e362a0632e7112
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Jul 13 19:21:09 EDT 2015
Correctly deduplicate types.
--- a/parse/type.c
+++ b/parse/type.c
@@ -678,21 +678,14 @@
return hash;
}
-int tyeq(void *t1, void *t2)
+int tyeq_rec(Type *a, Type *b, Bitset *visited)
{
- Type *a, *b;
size_t i;
- a = (Type *)t1;
- b = (Type *)t2;
- if (a == b)
- return 1;
if (!a || !b)
return 0;
if (a->type != b->type)
return 0;
- if (a->tid == b->tid)
- return 1;
if (a->narg != b->narg)
return 0;
if (a->nsub != b->nsub)
@@ -699,6 +692,17 @@
return 0;
if (a->nmemb != b->nmemb)
return 0;
+
+ if (a == b)
+ return 1;
+ if (a->tid == b->tid)
+ return 1;
+ if (bshas(visited, a->tid) || bshas(visited, b->tid))
+ return 1;
+
+ bsput(visited, a->tid);
+ bsput(visited, b->tid);
+
switch (a->type) {
case Typaram:
return streq(a->pname, b->pname);
@@ -714,7 +718,7 @@
for (i = 0; i < a->nmemb; i++) {
if (!nameeq(a->udecls[i]->name, b->udecls[i]->name))
return 0;
- if (!tyeq(a->udecls[i]->etype, b->udecls[i]->etype))
+ if (!tyeq_rec(a->udecls[i]->etype, b->udecls[i]->etype, visited))
return 0;
}
break;
@@ -722,7 +726,7 @@
for (i = 0; i < a->nmemb; i++) {
if (strcmp(declname(a->sdecls[i]), declname(b->sdecls[i])) != 0)
return 0;
- if (!tyeq(decltype(a->sdecls[i]), decltype(b->sdecls[i])))
+ if (!tyeq_rec(decltype(a->sdecls[i]), decltype(b->sdecls[i]), visited))
return 0;
}
break;
@@ -730,10 +734,10 @@
if (!nameeq(a->name, b->name))
return 0;
for (i = 0; i < a->narg; i++)
- if (!tyeq(a->arg[i], b->arg[i]))
+ if (!tyeq_rec(a->arg[i], b->arg[i], visited))
return 0;
for (i = 0; i < a->nsub; i++)
- if (!tyeq(a->sub[i], b->sub[i]))
+ if (!tyeq_rec(a->sub[i], b->sub[i], visited))
return 0;
break;
case Tyarray:
@@ -744,9 +748,20 @@
break;
}
for (i = 0; i < a->nsub; i++)
- if (!tyeq(a->sub[i], b->sub[i]))
+ if (!tyeq_rec(a->sub[i], b->sub[i], visited))
return 0;
return 1;
+}
+
+int tyeq(void *a, void *b)
+{
+ Bitset *bs;
+ int eq;
+
+ bs = mkbs();
+ eq = tyeq_rec(a, b, bs);
+ bsfree(bs);
+ return eq;
}
size_t tyidfmt(char *buf, size_t sz, Type *ty)
--- a/parse/use.c
+++ b/parse/use.c
@@ -726,6 +726,7 @@
size_t i;
Type *t, *old;
+
/*
* merge duplicate definitions.
* This allows us to compare named types by id, instead
@@ -736,11 +737,23 @@
t = htget(tidmap, itop(typefixid[i]));
if (!t)
die("Unable to find type for id %zd\n", typefixid[i]);
- if ((t->type == Tyname || t->type == Tygeneric) && !t->issynth) {
- t = htget(tydedup, t);
- }
*typefixdest[i] = t;
}
+ for (i = 0; i < ntypefixdest; i++) {
+ old = *typefixdest[i];
+ if (old->type == Tyname || old->type == Tygeneric) {
+ t = htget(tydedup, old);
+ if (!t) {
+ t = old;
+ htput(tydedup, old, old);
+ } else {
+ if (strcmp(tystr(old), tystr(t)))
+ printf("deduping %s -> %s\n", tystr(old), tystr(t));
+ }
+ *typefixdest[i] = t;
+ }
+ }
+
/* check for duplicate type definitions */
for (i = 0; i < ntypefixdest; i++) {
t = htget(tidmap, itop(typefixid[i]));
@@ -750,6 +763,7 @@
if (old && !tyeq(t, old) && !isspecialization(t, old))
lfatal(t->loc, "Duplicate definition of type %s on %s:%d", tystr(old), file->file.files[old->loc.file], old->loc.line);
}
+ for (i = 0; i < ntypefixdest; i++)
lfree(&typefixdest, &ntypefixdest);
lfree(&typefixid, &ntypefixid);
}
@@ -779,23 +793,6 @@
lfree(&traitfixid, &ntraitfixid);
}
-ulong tdhash(void *pt)
-{
- Type *t;
-
- t = pt;
- return t->type * namehash(t->name);
-}
-
-int tdeq(void *pa, void *pb)
-{
- Type *a, *b;
-
- a = pa;
- b = pb;
- return a->type == b->type && nameeq(a->name, b->name);
-}
-
/* Usefile format:
* U<pkgname>
* T<pickled-type>
@@ -818,7 +815,7 @@
pushstab(file->file.globls);
if (!tydedup)
- tydedup = mkht(tdhash, tdeq);
+ tydedup = mkht(tyhash, tyeq);
if (fgetc(f) != 'U')
return 0;
if (rdint(f) != Abiversion) {
@@ -903,8 +900,6 @@
ty->ishidden = 1;
if (!gettype(s, ty->name) && !ty->ishidden)
puttype(s, ty->name, ty);
- if (!hthas(tydedup, ty))
- htput(tydedup, ty, ty);
} else if (ty->type == Tyunion) {
for (i = 0; i < ty->nmemb; i++)
if (!getucon(s, ty->udecls[i]->name) && !ty->udecls[i]->synth)