diff options
| author | 2025-12-14 12:15:59 +0100 | |
|---|---|---|
| committer | 2025-12-14 12:15:59 +0100 | |
| commit | d8b4e87af669c2b260686a5db67f7f02b4c164d9 (patch) | |
| tree | c46f03cc43462953dfb82df935bb7e2adcb098e4 /ir | |
| parent | 59ca5a8db396e3e9c395793d49e1cab05d2d3261 (diff) | |
various relocation related optimization
With 59ca5a8db, querying if a symbol is defined is cheap. If we're
compiling code that calls foo() and we defined foo() in this compilation
unit, we already know its offset within the .text section, so use it
instead of emitting a relocation for the linker to handle. Also, put
small literal data in the .text section instead of .rodata. This seems
to improve performance (cache locality?), and as a bonus, it will be
good for aarch64's instr encoding with smallish PC-relative offsets.
Diffstat (limited to 'ir')
| -rw-r--r-- | ir/ir.c | 10 |
1 files changed, 6 insertions, 4 deletions
@@ -147,7 +147,8 @@ mksymref(const char *s, bool isfunc) union ref mkdatref(const char *name, union type ctype, uint siz, uint align, const void *bytes, uint n, bool deref) { - struct irdat dat = { .ctype = ctype, .align = align, .siz = siz, .name = name, .section = Srodata }; + struct irdat dat = { .ctype = ctype, .align = align, .siz = siz, .name = name }; + dat.section = align >= 4 && align <= targ_primsizes[TYPTR] && siz <= 16 ? Stext : Srodata; assert(n <= siz && siz && align); if (!name) { @@ -155,14 +156,15 @@ mkdatref(const char *name, union type ctype, uint siz, uint align, const void *b char buf[32]; struct wbuf wbuf = MEMBUF(buf, sizeof buf); - bfmt(&wbuf, ".L.%d", dattab.n); + bfmt(&wbuf, ".L%c.%d", dat.section == Stext ? 'L' : 'D', dattab.n); ioputc(&wbuf, 0); assert(!wbuf.err); dat.name = name = intern(buf); } dat.off = objnewdat(name, dat.section, 0, siz, align); - memcpy(objout.rodata.p+dat.off, bytes, n); - memset(objout.rodata.p+dat.off+n, 0, siz - n); + uchar *p = (dat.section == Stext ? objout.textbegin : objout.rodata.p) + dat.off; + if (n) memcpy(p, bytes, n); + if (dat.section != Stext) memset(p+n, 0, siz - n); vpush(&dattab, dat); return mkref(RXCON, addcon(&(struct xcon){.isdat = 1, .deref = deref, .dat = dattab.n - 1})); } |