diff options
| author | 2026-03-23 23:38:53 +0100 | |
|---|---|---|
| committer | 2026-03-23 23:43:52 +0100 | |
| commit | 62d995124c0cc2eaeec79e18edc3e044f3e524c9 (patch) | |
| tree | 4c79a80efca09f8050109aa0440ec75351d72c17 /src/obj.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/obj.c')
| -rw-r--r-- | src/obj.c | 16 |
1 files changed, 14 insertions, 2 deletions
@@ -89,9 +89,13 @@ objnewdat(internstr name, enum section sec, bool globl, uint siz, uint align) return off; } +static pmap_of(uchar) needed_fns; + void -objreloc(internstr sym, enum relockind reloc, enum section section, uint off, s64int addend) +objreloc(internstr sym, int symflags, enum relockind reloc, enum section section, uint off, s64int addend) { + if ((symflags & (SLOCAL|SFUNC)) == (SLOCAL|SFUNC)) + pmap_set(&needed_fns, sym, 1); switch (mctarg->objkind) { case OBJELF: elfreloc(sym, reloc, section, off, addend); @@ -99,9 +103,17 @@ objreloc(internstr sym, enum relockind reloc, enum section section, uint off, s6 } } +bool +fnisneeded(internstr name) +{ + return pmap_get(&needed_fns, name) != NULL; +} + void -objfini(void) +objfini(bool emit) { + emitxinlfns(/*all*/!emit); + if (!emit) return; static char buf[1<<12]; WriteBuf out = FDBUF(buf, sizeof buf, open(objout.outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666)); if (out.fd < 0) fatal(NULL, "could not open %'s for writing: %s", objout.outfile, strerror(errno)); |