aboutsummaryrefslogtreecommitdiffhomepage
path: root/ir
diff options
context:
space:
mode:
author lemon<lsof@mailbox.org>2025-10-23 19:30:45 +0200
committer lemon<lsof@mailbox.org>2025-10-23 19:30:51 +0200
commit4fc6339f04958150c538bf97bf721f58e0084ffb (patch)
treef66fe5203552287f0386c6459d1f0a4bce4bf22f /ir
parented989e2a0855e175442b0f5e73bb3fa4833efecd (diff)
ir bugfixes
Diffstat (limited to 'ir')
-rw-r--r--ir/cfg.c5
-rw-r--r--ir/ir.c21
-rw-r--r--ir/ir.h1
-rw-r--r--ir/regalloc.c4
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))) {