aboutsummaryrefslogtreecommitdiffhomepage
path: root/ir/ir.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-12-20 17:59:40 +0100
committerlemon <lsof@mailbox.org>2025-12-20 19:31:50 +0100
commite6fbab42185f4fb4e3a3b1e3e93eaa5d3d81b7c7 (patch)
treedba8dd1a91f532dd104dc1299b32e79babacb499 /ir/ir.c
parenta5009ae762541c29e9a123bf70877261db4ff628 (diff)
backend: unify pass memory allocation strategies
It was all over the place for temporary data structures used by individual passes. Now there is an arena specifically for that, which is nicer.
Diffstat (limited to 'ir/ir.c')
-rw-r--r--ir/ir.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/ir/ir.c b/ir/ir.c
index 5f1797c..35a36b4 100644
--- a/ir/ir.c
+++ b/ir/ir.c
@@ -45,6 +45,8 @@ irinit(struct function *fn)
static union ref *phisbuf[64];
static struct irdat datsbuf[64];
+ assert(fn->arena && !fn->passarena);
+
ninstr = 0;
instrfreelist = -1;
vinit(&calltab, callsbuf, countof(callsbuf));
@@ -629,6 +631,9 @@ void
irfini(struct function *fn)
{
extern int nerror;
+ static union { char m[sizeof(struct arena) + (4<<10)]; struct arena *_align; } amem;
+ struct arena *passarena = (void *)&amem.m;
+ fn->passarena = &passarena;
if (nerror) {
freefn(fn);
return;
@@ -638,10 +643,12 @@ irfini(struct function *fn)
lowerintrin(fn);
if (ccopt.o > OPT0) {
mem2reg(fn);
+ freearena(fn->passarena);
copyopt(fn);
}
if (ccopt.o >= OPT1) {
simpl(fn);
+ freearena(fn->passarena);
}
if (ccopt.dbg.o) {
bfmt(ccopt.dbgout, "<< Before isel >>\n");
@@ -649,9 +656,11 @@ irfini(struct function *fn)
}
mctarg->isel(fn);
regalloc(fn);
+ freearena(fn->passarena);
if (!ccopt.dbg.any)
mctarg->emit(fn);
+ freearena(fn->passarena);
freefn(fn);
}