aboutsummaryrefslogtreecommitdiffhomepage
path: root/ir
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2026-02-19 20:29:16 +0100
committerlemon <lsof@mailbox.org>2026-02-19 20:29:16 +0100
commitad8067a1ab1871cf57936828fb1b40c15cd3349d (patch)
treead86757ae0f84f1fd7dd58373cdb4f50d7f036d6 /ir
parent1430f62ebed808458baccbdf0e41b806334ff704 (diff)
IR: just use an array for extended constants
The extra work of using a hashtable to intern them is probably unnecessary.
Diffstat (limited to 'ir')
-rw-r--r--ir/dump.c2
-rw-r--r--ir/inliner.c7
-rw-r--r--ir/ir.c36
-rw-r--r--ir/ir.h15
-rw-r--r--ir/ssa.c2
5 files changed, 25 insertions, 37 deletions
diff --git a/ir/dump.c b/ir/dump.c
index cf8d788..bb6a2fd 100644
--- a/ir/dump.c
+++ b/ir/dump.c
@@ -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;
diff --git a/ir/ir.c b/ir/ir.c
index 01d8060..b5f9de8 100644
--- a/ir/ir.c
+++ b/ir/ir.c
@@ -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;
}
diff --git a/ir/ir.h b/ir/ir.h
index 73a50bd..c7abaa7 100644
--- a/ir/ir.h
+++ b/ir/ir.h
@@ -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);
diff --git a/ir/ssa.c b/ir/ssa.c
index 9d248f4..6598fba 100644
--- a/ir/ssa.c
+++ b/ir/ssa.c
@@ -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;