From a6c2f8a9177eeae64b83e4aeafe46dbe310b3861 Mon Sep 17 00:00:00 2001 From: lemon Date: Thu, 25 Dec 2025 13:28:56 +0100 Subject: avoid GOT relocations in unnecessary instances Also change xcon to have a flagset for symbols (whether it's a function, locally defined; later: thread local, etc). --- ir/intrin.c | 2 +- ir/ir.c | 8 ++++---- ir/ir.h | 9 +++++++-- 3 files changed, 12 insertions(+), 7 deletions(-) (limited to 'ir') diff --git a/ir/intrin.c b/ir/intrin.c index d31f9bb..dcd05a5 100644 --- a/ir/intrin.c +++ b/ir/intrin.c @@ -24,7 +24,7 @@ intrin(struct block *blk, int *curi, enum intrin in, struct arg *args, int narg, /* memcpy */ *args[1].ty = *args[0].ty = mktyperef(cls2type(KPTR)); insertinstr(blk, (*curi)++, mkarginstr(cls2type(cls), mkintcon(cls, td->siz))); - *this = mkinstr(Ocall, 0, mksymref(intern("memcpy"), 1), this->r); + *this = mkinstr(Ocall, 0, mksymref(intern("memcpy"), SFUNC), this->r); calltab.p[this->r.i].narg = 3; calltab.p[this->r.i].ret = cls2type(0); return 0; diff --git a/ir/ir.c b/ir/ir.c index 1f1c9bc..29d52d4 100644 --- a/ir/ir.c +++ b/ir/ir.c @@ -101,7 +101,7 @@ newcon(const struct xcon *con) { uint h = hashb(0, con, sizeof *con); uint i = h, n = countof(conht); - assert((con->issym ^ con->isdat && !(con->isdat && con->isfunc)) || con->cls); + assert((con->issym ^ con->isdat) || con->cls); for (;; ++i) { i &= countof(conht) - 1; if (!conht[i].issym && !conht[i].isdat && !conht[i].cls) { @@ -145,9 +145,9 @@ mkfltcon(enum irclass k, double f) } union ref -mksymref(internstr s, bool isfunc) +mksymref(internstr s, enum symflags symflags) { - struct xcon con = { .issym = 1, .sym = s, .isfunc = isfunc }; + struct xcon con = { .issym = 1, .sym = s, .flag = symflags }; return mkref(RXCON, newcon(&con)); } @@ -172,7 +172,7 @@ 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})); + return mkref(RXCON, newcon(&(struct xcon){.isdat = 1, .deref = deref, .dat = dattab.n - 1, .flag = SLOCAL})); } internstr diff --git a/ir/ir.h b/ir/ir.h index 8e18e1f..8402864 100644 --- a/ir/ir.h +++ b/ir/ir.h @@ -25,9 +25,14 @@ struct irdat { internstr name; }; +enum symflags { + SLOCAL = 1, + SFUNC = 2, +}; struct xcon { - bool issym, isdat, isfunc, deref; + bool issym, isdat, deref; uchar cls; + uchar flag; union { internstr sym; int dat; @@ -255,7 +260,7 @@ union ref mkfltcon(enum irclass, double); #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) -union ref mksymref(internstr, bool isfunc); +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); struct instr mkalloca(uint siz, uint align); -- cgit v1.2.3