aboutsummaryrefslogtreecommitdiffhomepage
path: root/ir
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
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')
-rw-r--r--ir/abi0.c5
-rw-r--r--ir/intrin.c2
-rw-r--r--ir/ir.c9
-rw-r--r--ir/ir.h2
-rw-r--r--ir/mem2reg.c29
-rw-r--r--ir/regalloc.c2
-rw-r--r--ir/simpl.c3
7 files changed, 21 insertions, 31 deletions
diff --git a/ir/abi0.c b/ir/abi0.c
index 1547722..bd8e297 100644
--- a/ir/abi0.c
+++ b/ir/abi0.c
@@ -246,13 +246,11 @@ patcharg(struct block *blk, int *icall, struct call *call,
return 1;
}
}
-
-static struct abiarg abiargsbuf[32];
-
void
abi0_call(struct function *fn, struct instr *ins, struct block *blk, int *curi)
{
union ref retmem;
+ struct abiarg abiargsbuf[32];
struct abiargsvec abiargs = {VINIT(abiargsbuf, countof(abiargsbuf))};
bool sretarghidden = 0;
int ni, nf, ns, vararg, nret = 0;
@@ -361,6 +359,7 @@ abi0_call(struct function *fn, struct instr *ins, struct block *blk, int *curi)
void
abi0(struct function *fn)
{
+ struct abiarg abiargsbuf[32];
uint nparam = typedata[fn->fnty.dat].nmemb;
const union type *paramty = typedata[fn->fnty.dat].param;
struct abiargsvec abiargs = {VINIT(abiargsbuf, countof(abiargsbuf))};
diff --git a/ir/intrin.c b/ir/intrin.c
index 53e29fc..d31f9bb 100644
--- a/ir/intrin.c
+++ b/ir/intrin.c
@@ -49,7 +49,7 @@ void
lowerintrin(struct function *fn)
{
struct block *blk = fn->entry;
- static struct arg argsbuf[64];
+ struct arg argsbuf[32];
vec_of(struct arg) args = VINIT(argsbuf, countof(argsbuf));
do {
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);
}
diff --git a/ir/ir.h b/ir/ir.h
index ad22eb9..6e8ae88 100644
--- a/ir/ir.h
+++ b/ir/ir.h
@@ -162,7 +162,7 @@ enum {
FNDOM = 1<<3,
};
struct function {
- struct arena **arena;
+ struct arena **arena, **passarena;
internstr name;
struct block *entry, *curblk;
struct use *use;
diff --git a/ir/mem2reg.c b/ir/mem2reg.c
index f9ad245..a1a4132 100644
--- a/ir/mem2reg.c
+++ b/ir/mem2reg.c
@@ -23,6 +23,7 @@ static const uchar load2ext[] = {
/* Implements algorithm in 'Simple and Efficient Construction of Static Single Assignment' (Braun et al) */
struct ssabuilder {
+ struct arena **arena;
imap_of(union ref *) curdefs; /* map of var to (map of block to def of var) */
struct bitset *sealed, /* set of sealed blocks */
*marked; /* blocks marked, for 'Marker Algorithm' in the paper */
@@ -98,7 +99,7 @@ writevar(struct ssabuilder *sb, int var, struct block *blk, union ref val)
{
union ref **pcurdefs;
if (!(pcurdefs = imap_get(&sb->curdefs, var))) {
- pcurdefs = imap_set(&sb->curdefs, var, xcalloc(sb->nblk * sizeof(union ref)));
+ pcurdefs = imap_set(&sb->curdefs, var, allocz(sb->arena, sb->nblk * sizeof(union ref), 0));
}
if (val.t == RTMP) assert(instrtab[val.i].op != Onop);
(*pcurdefs)[blk->id] = val;
@@ -222,25 +223,15 @@ cmpuse(const void *a, const void *b)
void
mem2reg(struct function *fn)
{
- static struct bitset bsbuf[2][4];
- struct ssabuilder sb = { .nblk = fn->nblk };
- struct block *blk;
+ struct ssabuilder sb = { fn->passarena, .nblk = fn->nblk };
FREQUIRE(FNUSE);
- if (fn->nblk <= BSNBIT * countof(bsbuf[0])) {
- sb.sealed = bsbuf[0];
- sb.marked = bsbuf[1];
- memset(bsbuf[0], 0, BSSIZE(fn->nblk) * sizeof *bsbuf[0]);
- memset(bsbuf[1], 0, BSSIZE(fn->nblk) * sizeof *bsbuf[1]);
- } else {
- sb.sealed = xcalloc(BSSIZE(fn->nblk) * sizeof *sb.sealed);
- sb.marked = xcalloc(BSSIZE(fn->nblk) * sizeof *sb.marked);
- }
-
+ sb.sealed = allocz(sb.arena, BSSIZE(fn->nblk) * sizeof *sb.sealed, 0);
+ sb.marked = allocz(sb.arena, BSSIZE(fn->nblk) * sizeof *sb.sealed, 0);
sortrpo(fn);
- blk = fn->entry;
+ struct block *blk = fn->entry;
do {
for (int i = 0; i < blk->ins.n; ++i) {
struct use *use, *uend;
@@ -326,14 +317,6 @@ mem2reg(struct function *fn)
delphi(blk, i--);
} while ((blk = blk->lnext) != fn->entry);
- if (sb.sealed != bsbuf[0]) {
- free(sb.sealed);
- free(sb.marked);
- }
-
- for (int i = 0; i < sb.curdefs.mb.N; ++i)
- if (bstest(sb.curdefs.mb.bs, i))
- free(sb.curdefs.v[i]);
imap_free(&sb.curdefs);
if (ccopt.dbg.m) {
bfmt(ccopt.dbgout, "<< After mem2reg >>\n");
diff --git a/ir/regalloc.c b/ir/regalloc.c
index 9c1f232..e8eccfb 100644
--- a/ir/regalloc.c
+++ b/ir/regalloc.c
@@ -1274,7 +1274,7 @@ void
regalloc(struct function *fn)
{
static union ref *stkslotrefsbuf[64];
- struct rega ra = {fn, .arena = fn->arena};
+ struct rega ra = {fn, .arena = fn->passarena};
struct block *blk, *last;
/* setup */
diff --git a/ir/simpl.c b/ir/simpl.c
index fb89c07..7e6cfd0 100644
--- a/ir/simpl.c
+++ b/ir/simpl.c
@@ -70,7 +70,7 @@ simpl(struct function *fn)
FREQUIRE(FNUSE);
int inschange = 0,
blkchange = 0;
- struct block **jmpfinal = xcalloc(fn->nblk * sizeof *jmpfinal);
+ struct block **jmpfinal = allocz(fn->passarena, fn->nblk * sizeof *jmpfinal, 0);
struct block *blk = fn->entry;
do {
@@ -140,7 +140,6 @@ simpl(struct function *fn)
} while ((blk = blk->lnext) != fn->entry);
fillpreds(fn);
}
- free(jmpfinal);
}
/* vim:set ts=3 sw=3 expandtab: */