diff options
Diffstat (limited to 'ir')
| -rw-r--r-- | ir/dump.c | 2 | ||||
| -rw-r--r-- | ir/inliner.c | 7 | ||||
| -rw-r--r-- | ir/ir.c | 36 | ||||
| -rw-r--r-- | ir/ir.h | 15 | ||||
| -rw-r--r-- | ir/ssa.c | 2 |
5 files changed, 25 insertions, 37 deletions
@@ -107,7 +107,7 @@ dumpref(enum op o, union ref ref) else bfmt(out, "%d", ref.i); break; case RXCON: - con = &conht[ref.i]; + con = &contab.p[ref.i]; if (con->deref) bfmt(out, "*["); if (con->issym || con->isdat) { bfmt(out, "$%y", xcon2sym(ref.i)); diff --git a/ir/inliner.c b/ir/inliner.c index 0853d26..2ce817b 100644 --- a/ir/inliner.c +++ b/ir/inliner.c @@ -4,7 +4,7 @@ struct savedfunc { int mark; uint ninstr; struct instr *instrtab; - struct xcon *conht; + struct xcon *contab; struct call *calltab; union ref **phitab; struct block *entry; @@ -82,7 +82,7 @@ maybeinlinee(struct function *fn) } while ((b = b->lnext)); sv->instrtab = alloccopy(&savearena, instrtab, sizeof *instrtab * (sv->ninstr = ninstr), 0); - sv->conht = alloccopy(&savearena, conht, sizeof *conht * (1<<12), 0); // HACK + sv->contab = alloccopy(&savearena, contab.p, sizeof *contab.p * contab.n, 0); if (calltab.n) { sv->calltab = alloccopy(&savearena, calltab.p, sizeof *calltab.p * calltab.n, 0); for (int i = 0; i < calltab.n; ++i) { @@ -104,9 +104,8 @@ maybeinlinee(struct function *fn) static union ref mapref(short *instrmap, struct savedfunc *sv, union ref r) { - int newcon(const struct xcon *con); if (r.t == RTMP) return r.i = instrmap[r.i], r; - if (r.t == RXCON) return r.i = newcon(&sv->conht[r.i]), r; + if (r.t == RXCON) return newxcon(&sv->contab[r.i]); assert(r.t != RADDR); assert(r.t != RSTACK); return r; @@ -35,10 +35,9 @@ static struct arena **usearena; struct calltab calltab; struct phitab phitab; struct dattab dattab; +struct contab contab; struct addr addrht[1 << 12]; static int naddrht; -struct xcon conht[1 << 12]; -static int nconht; int visitmark; void @@ -47,6 +46,7 @@ irinit(struct function *fn) static struct call callsbuf[64]; static union ref *phisbuf[64]; static struct irdat datsbuf[64]; + static struct xcon consbuf[64]; assert(fn->arena && !fn->passarena); @@ -57,11 +57,10 @@ irinit(struct function *fn) vinit(&calltab, callsbuf, countof(callsbuf)); for (int i = 0; i < phitab.n; ++i) xbfree(phitab.p[i]); vinit(&phitab, phisbuf, countof(phisbuf)); + vinit(&contab, consbuf, countof(consbuf)); if (!dattab.p) vinit(&dattab, datsbuf, countof(datsbuf)); if (naddrht >= countof(addrht)/2) memset(addrht, naddrht = 0, sizeof addrht); - if (nconht >= countof(conht)/2) - memset(conht, nconht = 0, sizeof conht); if (!type2cls[TYINT]) { for (int i = TYBOOL; i <= TYUVLONG; ++i) { int siz = targ_primsizes[i]; @@ -100,23 +99,12 @@ newaddr(const struct addr *addr) } } -int -newcon(const struct xcon *con) +union ref +newxcon(const struct xcon *con) { - uint h = hashb(0, con, sizeof *con); - uint i = h, n = countof(conht); assert((con->issym ^ con->isdat) || con->cls); - for (;; ++i) { - i &= countof(conht) - 1; - if (!conht[i].issym && !conht[i].isdat && !conht[i].cls) { - conht[i] = *con; - ++nconht; - return i; - } else if (!memcmp(&conht[i], con, sizeof *con)) { - return i; - } - assert(--n > 0 && "conht full"); - } + vpush(&contab, *con); + return mkref(RXCON, contab.n-1); } union irtype @@ -137,7 +125,7 @@ mkintcon(enum irclass k, vlong i) struct xcon con = { .cls = k, .i = i }; if (cls2siz[k] == 4) /* check upper half is zero or -1 */ assert(in_range((i >> 32) + 1, 0, 1)); - return mkref(RXCON, newcon(&con)); + return newxcon(&con); } } @@ -145,14 +133,14 @@ union ref mkfltcon(enum irclass k, double f) { struct xcon con = { .cls = k, .f = k == KF32 ? (float) f : f }; - return mkref(RXCON, newcon(&con)); + return newxcon(&con); } union ref mksymref(internstr s, enum symflags symflags) { struct xcon con = { .issym = 1, .sym = s, .flag = symflags }; - return mkref(RXCON, newcon(&con)); + return newxcon(&con); } union ref @@ -176,13 +164,13 @@ mkdatref(internstr name, union type ctype, uint siz, uint align, const void *byt if (n) memcpy(p, bytes, n); if (dat.section != Stext) memset(p+n, 0, siz - n); vpush(&dattab, dat); - return mkref(RXCON, newcon(&(struct xcon){.isdat = 1, .deref = deref, .dat = dattab.n - 1, .flag = SLOCAL})); + return newxcon(&(struct xcon){.isdat = 1, .deref = deref, .dat = dattab.n - 1, .flag = SLOCAL}); } internstr xcon2sym(int ref) { - struct xcon con = conht[ref]; + struct xcon con = contab.p[ref]; assert(con.issym ^ con.isdat); return con.issym ? con.sym : dattab.p[con.dat].name; } @@ -241,10 +241,10 @@ extern uchar cls2store[]; extern const uchar siz2intcls[]; extern struct instr instrtab[]; extern struct use *instruse[]; -extern struct xcon conht[]; extern struct calltab {vec_of(struct call);} calltab; extern struct phitab {vec_of(union ref *);} phitab; extern struct dattab {vec_of(struct irdat);} dattab; +extern struct contab {vec_of(struct xcon);} contab; extern struct addr addrht[]; extern int visitmark; #define mkinstr(O, C, ...) ((struct instr) { .op = (O), .cls = (C), .reg=0, __VA_ARGS__ }) @@ -253,16 +253,17 @@ void irinit(struct function *); void irfini(struct function *); #define cls2type(k) ((union irtype){.cls=(k)}) union irtype mkirtype(union type); +union ref newxcon(const struct xcon *); union ref mkintcon(enum irclass, vlong); union ref mkfltcon(enum irclass, double); #define iscon(r) in_range((r).t, RICON, RXCON) -#define concls(r) ((r).t == RICON ? KI32 : conht[(r).i].cls) +#define concls(r) ((r).t == RICON ? KI32 : contab.p[(r).i].cls) #define isintcon(r) (iscon(r) && kisint(concls(r))) -#define isfltcon(r) ((r).t == RXCON && kisflt(conht[(r).i].cls)) -#define isnumcon(r) ((r).t == RICON || ((r).t == RXCON && conht[(r).i].cls)) -#define isaddrcon(r,derefok) ((r).t == RXCON && !conht[(r).i].cls && (derefok || !conht[(r).i].deref)) -#define intconval(r) ((r).t == RICON ? (r).i : conht[(r).i].i) -#define fltconval(r) ((r).t == RICON ? (r).i : conht[(r).i].f) +#define isfltcon(r) ((r).t == RXCON && kisflt(contab.p[(r).i].cls)) +#define isnumcon(r) ((r).t == RICON || ((r).t == RXCON && contab.p[(r).i].cls)) +#define isaddrcon(r,derefok) ((r).t == RXCON && !contab.p[(r).i].cls && (derefok || !contab.p[(r).i].deref)) +#define intconval(r) ((r).t == RICON ? (r).i : contab.p[(r).i].i) +#define fltconval(r) ((r).t == RICON ? (r).i : contab.p[(r).i].f) union ref mksymref(internstr, enum symflags); union ref mkdatref(internstr name, union type ctype, uint siz, uint align, const void *, uint n, bool deref); internstr xcon2sym(int ref); @@ -30,7 +30,7 @@ copyopt(struct function *fn) union ref arg = ins->l; if (arg.t == RTMP) k = insrescls(instrtab[arg.i]); else if (arg.t == RICON) k = cls2siz[ins->cls] == 4 ? KI32 : KI64; - else if (arg.t == RXCON) k = isnumcon(arg) ? conht[arg.i].cls : KPTR; + else if (arg.t == RXCON) k = isnumcon(arg) ? concls(arg) : KPTR; else continue; if (ins->cls != k) continue; |