diff options
| -rw-r--r-- | ir/cfg.c | 5 | ||||
| -rw-r--r-- | ir/ir.c | 21 | ||||
| -rw-r--r-- | ir/ir.h | 1 | ||||
| -rw-r--r-- | ir/regalloc.c | 4 |
4 files changed, 27 insertions, 4 deletions
@@ -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; @@ -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; @@ -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))) { |