summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-02-27 23:29:40 -0800
committerOri Bernstein <ori@eigenstate.org>2016-02-27 23:29:40 -0800
commit8e1b57e6cb50118d28a86115520b7331cc0fdf23 (patch)
treec74a9a213d9c059add8eb43883bd2eb65e188add
parent16fb3943b8f4d15b91b133f01678d04793d0d138 (diff)
downloadmc-8e1b57e6cb50118d28a86115520b7331cc0fdf23.tar.gz
Add ability to deduplicate types.
-rw-r--r--parse/parse.h2
-rw-r--r--parse/type.c22
2 files changed, 19 insertions, 5 deletions
diff --git a/parse/parse.h b/parse/parse.h
index 80b3be6..2f42dd9 100644
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -142,6 +142,7 @@ struct Type {
char ispkglocal; /* Tyname: whether this is package local or not */
char isimport; /* Tyname: whether tyis type was imported. */
char isreflect; /* Tyname: whether this type has reflection info */
+ char isemitted; /* Tyname: whether this type has been emitted */
};
struct Ucon {
@@ -420,6 +421,7 @@ void tyinit(Stab *st); /* sets up built in types */
Type *mktype(Srcloc l, Ty ty);
Type *tydup(Type *t); /* shallow duplicate; all subtypes/members/... kept */
+Type *tydedup(Type *t);
Type *mktyvar(Srcloc l);
Type *mktyparam(Srcloc l, char *name);
Type *mktygeneric(Srcloc l, Node *name, Type **params, size_t nparams, Type *base);
diff --git a/parse/type.c b/parse/type.c
index ea1c2ea..4cd2716 100644
--- a/parse/type.c
+++ b/parse/type.c
@@ -28,6 +28,7 @@ size_t ntraittab;
Node **impltab;
size_t nimpltab;
+static Htab *tydeduptab;
/* Built in type constraints */
static Trait *traits[Ntypes + 1][4];
static int tybfmt(char *buf, size_t len, Type *t);
@@ -40,6 +41,20 @@ char stackness[] = {
int isstacktype(Type *t) { return stackness[tybase(t)->type]; }
+Type *tydedup(Type *ty)
+{
+ Type *had;
+
+ had = htget(tydeduptab, ty);
+ if (!had) {
+ htput(tydeduptab, ty, ty);
+ return ty;
+ }
+ /* if one is emitted, both are */
+ ty->isemitted = ty->isemitted || had->isemitted;
+ return had;
+}
+
Type *mktype(Srcloc loc, Ty ty)
{
Type *t;
@@ -644,11 +659,6 @@ ulong tyhash(void *ty)
t = (Type *)ty;
switch (t->type) {
- /* Important: we want tyhash to be consistent cross-file, since it
- * is used in naming trait impls and such.
- *
- * We should find a better name.
- */
case Tyvar: hash = inthash(t->tid); break;
case Typaram: hash = strhash(t->pname); break;
case Tyunion: hash = inthash(t->type); break;
@@ -893,6 +903,7 @@ void tyinit(Stab *st)
Type *ty;
Trait *tr;
+ tydeduptab = mkht(tyhash, tyeq);
/* this must be done after all the types are created, otherwise we will
* clobber the memoized bunch of types with the type params. */
#define Tc(c, n) \
@@ -948,6 +959,7 @@ void tyinit(Stab *st)
ty = mktype(Zloc, t); \
if (n) { \
puttype(st, mkname(Zloc, n), ty); \
+ htput(tydeduptab, ty, ty); \
} \
}
#include "types.def"