diff options
| author | 2026-03-23 23:38:53 +0100 | |
|---|---|---|
| committer | 2026-03-23 23:43:52 +0100 | |
| commit | 62d995124c0cc2eaeec79e18edc3e044f3e524c9 (patch) | |
| tree | 4c79a80efca09f8050109aa0440ec75351d72c17 /src/c.c | |
| parent | 8630aeb8b43c507cd00f5b091ddcee4def464f4d (diff) | |
IR: emit inline function standalone bodies lazily
If a function is stashed for inlining and inlined in all of its
callsites or unused, it never ends up in the object file. If any symbol
reference to it is emitted, then it must be de-inlined (rematerialized),
and this is done near the end before emitting the actual object file.
Diffstat (limited to 'src/c.c')
| -rw-r--r-- | src/c.c | 17 |
1 files changed, 12 insertions, 5 deletions
@@ -1387,6 +1387,7 @@ typedef struct InitParser { internstr sym; s64int addend; uint off; + uchar flag; } *drel; }; }; @@ -1428,14 +1429,17 @@ dumpini(InitParser *ip) #endif static s64int /* -> returns addend */ -expr2reloc(internstr *psym, const Expr *ex) +expr2reloc(internstr *psym, enum symflags *sf, const Expr *ex) { if (ex->t == ESSYMREF) { *psym = ex->ssym.sym; + *sf = (SLOCAL &- ex->ssym.local) | (SFUNC &- ex->ssym.func); return ex->ssym.off; } else if (ex->t == ESTRLIT || ex->t == EINIT) { if (ex->t == ESTRLIT) assert(ex->ty.t == TYARRAY); - *psym = xcon2sym(expraddr(NULL, ex).i); + Ref r = expraddr(NULL, ex); + *psym = xcon2sym(r.i); + *sf = contab.p[r.i].flag; return 0; } fatal(&ex->span, "internal bug: non static reloc?"); @@ -1506,10 +1510,11 @@ iniwrite(CComp *cm, InitParser *ip, uint off, uint bitsiz, uint bitoff, Type ty, memcpy(p, ex->s.p, n); } else { internstr sym; - s64int addend = expr2reloc(&sym, ex); + enum symflags sf; + s64int addend = expr2reloc(&sym, &sf, ex); if (!ip->dyn) { assert(ip->sec != Srodata || rodatarelocok()); - objreloc(sym, targ_64bit ? REL_ABS64 : REL_ABS32, + objreloc(sym, sf, targ_64bit ? REL_ABS64 : REL_ABS32, ip->sec, ip->off + off, addend); } else { InitReloc *rel = alloc(ip->arena, sizeof *rel, 0); @@ -1517,6 +1522,7 @@ iniwrite(CComp *cm, InitParser *ip, uint off, uint bitsiz, uint bitoff, Type ty, rel->sym = sym; rel->off = off; rel->addend = addend; + rel->flag = sf; ip->drel = rel; } } @@ -1886,7 +1892,8 @@ initializer(CComp *cm, Type *ty, enum evalmode ev, bool globl, memcpy(p + off, ip->ddat.p, ip->ddat.n); memset(p + off + ip->ddat.n, 0, siz - ip->ddat.n); for (InitReloc *rel = ip->drel; rel; rel = rel->link) { - objreloc(rel->sym, targ_64bit ? REL_ABS64 : REL_ABS32, sec, off + rel->off, rel->addend); + objreloc(rel->sym, rel->flag, targ_64bit ? REL_ABS64 : REL_ABS32, + sec, off + rel->off, rel->addend); } } vfree(&ip->ddat); |