From adf244459ef6946c2050764906357a4ec4010b3f Mon Sep 17 00:00:00 2001 From: lemon Date: Sun, 22 Mar 2026 11:20:14 +0100 Subject: mem2reg: improve on f9e3a52eaa Move the alloca to the beginning of the block and do a 2nd pass on those odd cases. --- src/ir_mem2reg.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/ir_mem2reg.c') diff --git a/src/ir_mem2reg.c b/src/ir_mem2reg.c index 043ac9b..b3e6e73 100644 --- a/src/ir_mem2reg.c +++ b/src/ir_mem2reg.c @@ -241,7 +241,10 @@ mem2reg(Function *fn) sortrpo(fn); Block *blk = fn->entry; + bool again = 0, neveragain = 0; +Again: do { + if (!neveragain || blk == fn->entry) for (int i = 0; i < blk->ins.n; ++i) { enum irclass k = 0; int sz = 0; @@ -257,10 +260,16 @@ mem2reg(Function *fn) do { if (use->u == USERJUMP) goto Skip; Instr *m = &instrtab[use->u]; - if (use->blk->id < sb.lastvisit) { - /* alloca appears after some of its uses; happens rarely, only + if (use->blk->id < blk->id) { + assert(!neveragain); + /* alloca appears after some of its uses; happens rarely, like * generated with code with gotos into loops. breaks this algo * due to reprocessing sealed blocks */ + /* move to entry block and reprocess later */ + vpush(&fn->entry->ins, var); + extern int allocinstr(void); + instrtab[blk->ins.p[i] = allocinstr()] = (Instr){Onop}; + again = 1; goto Skip; } if (oisload(m->op) && (!sz || sz == loadsz(m->op))) { @@ -305,6 +314,13 @@ mem2reg(Function *fn) ++sb.lastvisit; tryseal(&sb, blk); } while ((blk = blk->lnext) != fn->entry); + if (again) { + memset(sb.sealed, 0, BSSIZE(fn->nblk) * sizeof *sb.sealed); + neveragain = 1; + sb.lastvisit = 0; + again = 0; + goto Again; + } do { /* remove phis marked for deletion */ -- cgit v1.2.3