diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-10-06 20:42:54 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-10-06 20:42:54 -0400 |
commit | 99ad19546d983957d4bdb5596fc323a260d73fa6 (patch) | |
tree | abcb6fb12dc903d55a607d414f23d1cf7a58650c /lisc | |
parent | 1f618737993bd95cc94cdec0142d95935823a665 (diff) | |
download | roux-99ad19546d983957d4bdb5596fc323a260d73fa6.tar.gz |
use new vector functions instead of reallocs
Diffstat (limited to 'lisc')
-rw-r--r-- | lisc/isel.c | 67 | ||||
-rw-r--r-- | lisc/lisc.h | 4 | ||||
-rw-r--r-- | lisc/parse.c | 4 | ||||
-rw-r--r-- | lisc/ssa.c | 15 | ||||
-rw-r--r-- | lisc/util.c | 76 |
5 files changed, 106 insertions, 60 deletions
diff --git a/lisc/isel.c b/lisc/isel.c index 48f9dfc..49b8f28 100644 --- a/lisc/isel.c +++ b/lisc/isel.c @@ -13,37 +13,6 @@ * constant allocX in the first basic block) */ -static Ref -newtmp(Fn *fn) -{ - static int n; - int t; - - t = fn->ntmp++; - fn->tmp = realloc(fn->tmp, fn->ntmp * sizeof fn->tmp[0]); - if (!fn->tmp) - diag("isel: out of memory"); - memset(&fn->tmp[t], 0, sizeof fn->tmp[t]); - fn->tmp[t].spill = -1; - sprintf(fn->tmp[t].name, "isel%d", ++n); - return TMP(t); -} - -static Ref -newcon(int64_t val, Fn *fn) -{ - int c; - - for (c=0; c<fn->ncon; c++) - if (fn->con[c].type == CNum && fn->con[c].val == val) - return CON(c); - fn->ncon++; - fn->con = realloc(fn->con, fn->ncon * sizeof fn->con[0]); - if (!fn->con) - diag("isel: out of memory"); - fn->con[c] = (Con){.type = CNum, .val = val}; - return CON(c); -} static int noimm(Ref r, Fn *fn) @@ -81,7 +50,7 @@ selcmp(Ref arg[2], int w, Fn *fn) emit(OXCmp, w, R, arg[1], arg[0]); r = arg[1]; if (w && rtype(r) == RCon && noimm(r, fn)) { - curi->arg[0] = newtmp(fn); + curi->arg[0] = newtmp("isel", fn); emit(OCopy, w, curi->arg[0], r, R); } } @@ -110,7 +79,7 @@ sel(Ins i, Fn *fn) cpy[n].s = -1; s = rslot(r0, fn); if (s != -1) { - r0 = newtmp(fn); + r0 = newtmp("isel", fn); i.arg[n] = r0; cpy[n].r = r0; cpy[n].s = s; @@ -131,7 +100,7 @@ sel(Ins i, Fn *fn) /* immediates not allowed for * divisions in x86 */ - r0 = newtmp(fn); + r0 = newtmp("isel", fn); } else r0 = i.arg[1]; emit(OXDiv, w, R, r0, R); @@ -188,7 +157,7 @@ Emit: */ r0 = i.arg[n]; if (rtype(r0) == RCon && noimm(r0, fn)) { - curi->arg[n] = newtmp(fn); + curi->arg[n] = newtmp("isel", fn); emit(OCopy, 1, curi->arg[n], r0, R); } } @@ -205,14 +174,14 @@ Emit: val = (val + 15) & ~INT64_C(15); if (val < 0 || val > INT32_MAX) diag("isel: alloc too large"); - emit(OAlloc, 0, i.to, newcon(val, fn), R); + emit(OAlloc, 0, i.to, getcon(val, fn), R); } else { /* r0 = (i.arg[0] + 15) & -16 */ - r0 = newtmp(fn); - r1 = newtmp(fn); + r0 = newtmp("isel", fn); + r1 = newtmp("isel", fn); emit(OSAlloc, 0, i.to, r0, R); - emit(OAnd, 1, r0, r1, newcon(-16, fn)); - emit(OAdd, 1, r1, i.arg[0], newcon(15, fn)); + emit(OAnd, 1, r0, r1, getcon(-16, fn)); + emit(OAdd, 1, r1, i.arg[0], getcon(15, fn)); } break; default: @@ -502,7 +471,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1) if (!req(i1->arg[1], R)) diag("struct-returning function not implemented"); if (stk) { - r = newcon(-(int64_t)stk, fn); + r = getcon(-(int64_t)stk, fn); emit(OSAlloc, 0, R, r, R); } emit(OCopy, i1->wide, i1->to, TMP(RAX), R); @@ -516,9 +485,9 @@ selcall(Fn *fn, Ins *i0, Ins *i1) diag("isel: unsupported float struct"); if (a->size > 8) { r = TMP(rsave[ni+1]); - r1 = newtmp(fn); + r1 = newtmp("isel", fn); emit(OLoad, 1, r, r1, R); - r = newcon(8, fn); + r = getcon(8, fn); emit(OAdd, 1, r1, i->arg[1], r); r = TMP(rsave[ni]); ni += 2; @@ -580,12 +549,12 @@ selpar(Fn *fn, Ins *i0, Ins *i1) if (i->op == OParc) { if (a->rty[0] == RSse || a->rty[1] == RSse) diag("isel: unsupported float struct"); - r1 = newtmp(fn); + r1 = newtmp("isel", fn); *curi++ = (Ins){OCopy, 1, r1, {r}}; a->rty[0] = r1.val; if (a->size > 8) { r = TMP(rsave[ni++]); - r1 = newtmp(fn); + r1 = newtmp("isel", fn); *curi++ = (Ins){OCopy, 1, r1, {r}}; a->rty[1] = r1.val; } @@ -600,12 +569,12 @@ selpar(Fn *fn, Ins *i0, Ins *i1) ; r1 = i->to; r = TMP(a->rty[0]); - r2 = newcon(a->size, fn); + r2 = getcon(a->size, fn); *curi++ = (Ins){OAlloc+al, 1, r1, {r2}}; *curi++ = (Ins){OStorel, 0, R, {r, r1}}; if (a->size > 8) { - r = newtmp(fn); - r2 = newcon(8, fn); + r = newtmp("isel", fn); + r2 = getcon(8, fn); *curi++ = (Ins){OAdd, 1, r, {r1, r2}}; r1 = TMP(a->rty[1]); *curi++ = (Ins){OStorel, 0, R, {r1, r}}; @@ -695,7 +664,7 @@ isel(Fn *fn) assert(a+1 < p->narg); s = rslot(p->arg[a], fn); if (s != -1) { - p->arg[a] = newtmp(fn); + p->arg[a] = newtmp("isel", fn); emit(OAddr, 1, p->arg[a], SLOT(s), R); } } diff --git a/lisc/lisc.h b/lisc/lisc.h index 511498d..453d2ca 100644 --- a/lisc/lisc.h +++ b/lisc/lisc.h @@ -279,6 +279,10 @@ void emiti(Ins); int bcnt(Bits *); void idup(Ins **, Ins *, ulong); Ins *icpy(Ins *, Ins *, ulong); +void *valloc(ulong, size_t); +void vgrow(void *, ulong); +Ref newtmp(char *, Fn *); +Ref getcon(int64_t, Fn *); /* parse.c */ extern OpDesc opdesc[NOp]; diff --git a/lisc/parse.c b/lisc/parse.c index fd135c1..05cb32c 100644 --- a/lisc/parse.c +++ b/lisc/parse.c @@ -611,9 +611,9 @@ parsefn() err("empty file"); if (curb->jmp.type == JXXX) err("last block misses jump"); - fn->tmp = alloc(ntmp * sizeof tmp[0]); + fn->tmp = valloc(ntmp, sizeof tmp[0]); memcpy(fn->tmp, tmp, ntmp * sizeof tmp[0]); - fn->con = alloc(ncon * sizeof con[0]); + fn->con = valloc(ncon, sizeof con[0]); memcpy(fn->con, con, ncon * sizeof con[0]); fn->ntmp = ntmp; fn->ncon = ncon; diff --git a/lisc/ssa.c b/lisc/ssa.c index 97ba707..e60edc0 100644 --- a/lisc/ssa.c +++ b/lisc/ssa.c @@ -197,6 +197,7 @@ topdef(Blk *b, Fn *f, int w) void ssafix(Fn *f, int t) { + char s[NString]; uint n; int t0, t1, w; Ref rt; @@ -214,7 +215,7 @@ ssafix(Fn *f, int t) /* rename defs and some in-blocks uses */ for (p=b->phi; p; p=p->link) if (req(p->to, rt)) { - t1 = f->ntmp++; + t1 = t0++; p->to = TMP(t1); w |= p->wide; } @@ -227,7 +228,7 @@ ssafix(Fn *f, int t) } if (req(i->to, rt)) { w |= i->wide; - t1 = f->ntmp++; + t1 = t0++; i->to = TMP(t1); } } @@ -251,13 +252,9 @@ ssafix(Fn *f, int t) b->jmp.arg = topdef(b, f, w); } /* add new temporaries */ - f->tmp = realloc(f->tmp, f->ntmp * sizeof f->tmp[0]); - if (!f->tmp) - diag("ssafix: out of memory"); - for (t1=t0; t0<f->ntmp; t0++) { - f->tmp[t0] = f->tmp[t]; - snprintf(f->tmp[t0].name, NString, "%s%d", - f->tmp[t].name, t0-t1); + for (t1=f->ntmp; t1<t0; t1++) { + snprintf(s, NString, "%s%d", f->tmp[t].name, t0-t1); + newtmp(s, f); } free(top); free(bot); diff --git a/lisc/util.c b/lisc/util.c index e62fd1a..399c144 100644 --- a/lisc/util.c +++ b/lisc/util.c @@ -1,5 +1,23 @@ #include "lisc.h" +typedef struct Vec Vec; + +struct Vec { + ulong mag; + size_t esz; + ulong cap; + union { + long long ll; + long double ld; + void *ptr; + } align[]; +}; + +enum { + VMin = 2, + VMag = 0xcabba9e, +}; + Typ typ[NTyp]; Ins insb[NIns], *curi; @@ -80,3 +98,61 @@ icpy(Ins *d, Ins *s, ulong n) memcpy(d, s, n * sizeof(Ins)); return d + n; } + +void * +valloc(ulong len, size_t esz) +{ + ulong cap; + Vec *v; + + v = alloc(len * esz + sizeof(Vec)); + v->mag = VMag; + for (cap=VMin; cap<len; cap*=2) + ; + v->cap = cap; + v->esz = esz; + return v + 1; +} + +void +vgrow(void *vp, ulong len) +{ + Vec *v; + void *v1; + + v = *(Vec **)vp - 1; + assert(v+1 && v->mag == VMag); + if (v->cap >= len) + return; + v1 = valloc(len, v->esz); + memcpy(v1, v+1, v->cap * v->esz); + free(v); + *(Vec **)vp = v1; +} + +Ref +newtmp(char *prfx, Fn *fn) +{ + static int n; + int t; + + t = fn->ntmp++; + vgrow(&fn->tmp, fn->ntmp); + sprintf(fn->tmp[t].name, "%s%d", prfx, ++n); + fn->tmp[t].spill = -1; + return TMP(t); +} + +Ref +getcon(int64_t val, Fn *fn) +{ + int c; + + for (c=0; c<fn->ncon; c++) + if (fn->con[c].type == CNum && fn->con[c].val == val) + return CON(c); + fn->ncon++; + vgrow(&fn->con, fn->ncon); + fn->con[c] = (Con){.type = CNum, .val = val}; + return CON(c); +} |