From 4fc6339f04958150c538bf97bf721f58e0084ffb Mon Sep 17 00:00:00 2001 From: lemon Date: Thu, 23 Oct 2025 19:30:45 +0200 Subject: ir bugfixes --- ir/cfg.c | 5 ++++- ir/ir.c | 21 ++++++++++++++++++++- ir/ir.h | 1 + ir/regalloc.c | 4 ++-- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/ir/cfg.c b/ir/cfg.c index d9aa409..df428d1 100644 --- a/ir/cfg.c +++ b/ir/cfg.c @@ -24,8 +24,11 @@ sortrpo(struct function *fn) fn->entry->id = 0; porec(&rpo, fn->entry); ndead = rpo - rpobuf; - for (struct block *blk = fn->entry; ndead > 0; blk = blk->lnext) { + for (struct block *blk = fn->entry->lprev, *next; ndead > 0; blk = next) { + next = blk->lprev; if (!wasvisited(blk)) { + for (int i = 0; i < blk->npred; ++i) + assert(!wasvisited(blkpred(blk, i))); blk->lnext = blk->lprev = NULL; freeblk(fn, blk); --ndead; diff --git a/ir/ir.c b/ir/ir.c index 967870f..586b9b8 100644 --- a/ir/ir.c +++ b/ir/ir.c @@ -228,7 +228,7 @@ delpred(struct block *blk, struct block *p) return; } } - assert(0&&"blk not in p"); + //assert(0&&"blk not in p"); } struct block * @@ -245,6 +245,25 @@ freeblk(struct function *fn, struct block *blk) { if (blk->npred > 1) xbfree(blk->_pred); + + for (int i = 0; i < blk->phi.n; ++i) { + int ui = blk->phi.p[i]; + union ref *r = phitab.p[instrtab[ui].l.i]; + for (int j = 0; j < blk->npred; ++j) { + deluse(blk, ui, *r); + } + } + for (int i = 0; i < blk->ins.n; ++i) { + int ui = blk->ins.p[i]; + struct instr *ins = &instrtab[ui]; + if (ins->l.t == RTMP) deluse(blk, ui, ins->l); + if (ins->r.t == RTMP) deluse(blk, ui, ins->r); + } + for (int i = 0; i < 2; ++i) { + if (blk->jmp.arg[i].t == RTMP) deluse(blk, USERJUMP, blk->jmp.arg[i]); + } + if (blk->s1) delpred(blk->s1, blk); + if (blk->s2) delpred(blk->s2, blk); vfree(&blk->phi); vfree(&blk->ins); if (blk->lnext) blk->lnext->lprev = blk->lprev; diff --git a/ir/ir.h b/ir/ir.h index 2c8a55d..a49432d 100644 --- a/ir/ir.h +++ b/ir/ir.h @@ -236,6 +236,7 @@ void adduse(struct block *ublk, int ui, union ref r); union ref insertinstr(struct block *, int idx, struct instr); union ref insertphi(struct block *, enum irclass cls); void replcuses(union ref from, union ref to); +bool deluse(struct block *ublk, int ui, union ref r); void deluses(int ins); void delinstr(struct block *, int idx); void delphi(struct block *, int idx); diff --git a/ir/regalloc.c b/ir/regalloc.c index f73a3d1..ca84eb7 100644 --- a/ir/regalloc.c +++ b/ir/regalloc.c @@ -1031,12 +1031,12 @@ devirt(struct rega *ra, struct block *blk) } else { bool dosave = 0; int reg = kisint(insrescls(*ins)) ? mctarg->gprscratch : mctarg->fprscratch; - assert(nspill < 2); if (nspill > 0) { for (reg = kisflt(cls) ? mctarg->fpr0 : mctarg->gpr0;; ++reg) { for (int j = 0; j < nargref; ++j) - if (argref[j]->t == RREG && argref[j]->i == reg) continue; + if (argref[j]->t == RREG && argref[j]->i == reg) goto NotThis; break; + NotThis:; } /* if not the designated scratch register, we need to save+restore */ if ((dosave = rstest(fn->regusage, reg) || rstest(mctarg->rcallee, reg))) { -- cgit v1.2.3