commit 99ad19546d983957d4bdb5596fc323a260d73fa6
parent 1f618737993bd95cc94cdec0142d95935823a665
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Tue, 6 Oct 2015 20:42:54 -0400
use new vector functions instead of reallocs
Diffstat:
5 files changed, 106 insertions(+), 60 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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);
+}