diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2016-04-18 14:03:06 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2016-04-18 14:03:06 -0400 |
commit | c43a07086bdeefe029c5b6da4ec1c8020126d5ca (patch) | |
tree | d497b43234d5d59ca40ceb22154d24e15fdeb395 | |
parent | c6f3adc52d375d434e3dfd2d23056f0bfdbcdc67 (diff) | |
download | roux-c43a07086bdeefe029c5b6da4ec1c8020126d5ca.tar.gz |
factor some subtyping logic in clsmerge()
-rw-r--r-- | all.h | 2 | ||||
-rw-r--r-- | parse.c | 23 | ||||
-rw-r--r-- | ssa.c | 8 | ||||
-rw-r--r-- | util.c | 17 |
4 files changed, 32 insertions, 18 deletions
diff --git a/all.h b/all.h index c729b86..19125b0 100644 --- a/all.h +++ b/all.h @@ -190,6 +190,7 @@ enum FCmp { }; enum Class { + Kx = -1, /* "top" class (see usecheck() and clsmerge()) */ Kw, Kl, Ks, @@ -488,6 +489,7 @@ void idup(Ins **, Ins *, ulong); Ins *icpy(Ins *, Ins *, ulong); void *vnew(ulong, size_t); void vgrow(void *, ulong); +int clsmerge(short *, short); int phicls(int, Tmp *); Ref newtmp(char *, int, Fn *); void chuse(Ref, int, Fn *); diff --git a/parse.c b/parse.c index fa4bd7d..03a89f1 100644 --- a/parse.c +++ b/parse.c @@ -4,7 +4,6 @@ enum { Ke = -2, /* Erroneous mode */ - Kx = -1, /* Invalid operand */ Km = Kl, /* Memory pointer (for x64) */ }; @@ -364,7 +363,7 @@ tmpref(char *v) for (t=Tmp0; t<curf->ntmp; t++) if (strcmp(v, curf->tmp[t].name) == 0) return TMP(t); - newtmp(0, -1, curf); + newtmp(0, Kx, curf); strcpy(curf->tmp[t].name, v); return TMP(t); } @@ -645,7 +644,7 @@ Ins: } static int -oktype(Ref r, int k, Fn *fn) +usecheck(Ref r, int k, Fn *fn) { return rtype(r) != RTmp || fn->tmp[r.val].cls == k || (fn->tmp[r.val].cls == Kl && k == Kw); @@ -672,13 +671,9 @@ typecheck(Fn *fn) for (i=b->ins; i-b->ins < b->nins; i++) if (rtype(i->to) == RTmp) { t = &fn->tmp[i->to.val]; - k = t->cls; - if (k == -1 || (k == Kl && i->cls == Kw)) - k = i->cls; - if (k != i->cls) + if (clsmerge(&t->cls, i->cls)) err("temporary %%%s is assigned with" " multiple types", t->name); - t->cls = k; } } for (b=fn->start; b; b=b->link) { @@ -693,7 +688,7 @@ typecheck(Fn *fn) if (bshas(ppb, p->blk[n]->id)) err("multiple entries for @%s in phi %%%s", p->blk[n]->name, t->name); - if (!oktype(p->arg[n], k, fn)) + if (!usecheck(p->arg[n], k, fn)) err("invalid type for operand %%%s in phi %%%s", fn->tmp[p->arg[n].val].name, t->name); bsset(ppb, p->blk[n]->id); @@ -719,7 +714,7 @@ typecheck(Fn *fn) err("missing %s operand in %s", n == 1 ? "second" : "first", opdesc[i->op].name); - if (!oktype(r, k, fn)) + if (!usecheck(r, k, fn)) err("invalid type for %s operand %%%s in %s", n == 1 ? "second" : "first", t->name, opdesc[i->op].name); @@ -727,12 +722,12 @@ typecheck(Fn *fn) r = b->jmp.arg; if (isret(b->jmp.type)) { if (b->jmp.type == JRetc) { - if (!oktype(r, Kl, fn)) + if (!usecheck(r, Kl, fn)) goto JErr; - } else if (!oktype(r, b->jmp.type-JRetw, fn)) + } else if (!usecheck(r, b->jmp.type-JRetw, fn)) goto JErr; } - if (b->jmp.type == JJnz && !oktype(r, Kw, fn)) + if (b->jmp.type == JJnz && !usecheck(r, Kw, fn)) JErr: err("invalid type for jump argument %%%s in block @%s", fn->tmp[r.val].name, b->name); @@ -763,7 +758,7 @@ parsefn(int export) curf->con[0].type = CBits; curf->export = export; blink = &curf->start; - curf->retty = -1; + curf->retty = Kx; if (peek() != TGlo) rcls = parsecls(&curf->retty); else diff --git a/ssa.c b/ssa.c index c35fd7e..e5f0f44 100644 --- a/ssa.c +++ b/ssa.c @@ -288,7 +288,8 @@ phiins(Fn *fn) Ins *i; Phi *p; Ref r; - int t, n, k, nt; + int t, n, nt; + short k; bsinit(u, fn->nblk); bsinit(defs, fn->nblk); @@ -324,9 +325,8 @@ phiins(Fn *fn) bsset(u, b->id); *--bp = b; } - if (k == -1) - k = i->cls; - assert(k == i->cls); + if (clsmerge(&k, i->cls)) + die("invalid input"); } } } diff --git a/util.c b/util.c index 96efdfd..527f214 100644 --- a/util.c +++ b/util.c @@ -189,6 +189,23 @@ vgrow(void *vp, ulong len) } int +clsmerge(short *pk, short k) +{ + short k1; + + k1 = *pk; + if (k1 == Kx) { + *pk = k; + return 0; + } + if ((k1 == Kw && k == Kl) || (k1 == Kl && k == Kw)) { + *pk = Kw; + return 0; + } + return k1 != k; +} + +int phicls(int t, Tmp *tmp /*, int c*/) { if (tmp[t].phi) |