From b94fe89c9ddfcb85dcddebfd218fa7f00b8e6608 Mon Sep 17 00:00:00 2001 From: lemon Date: Mon, 26 Jun 2023 00:29:07 +0200 Subject: backend: fix mem2reg & regalloc they were broken, especially for unstructured control flow. most significant fix is to register allocator for temporaries that are used before the first definition in the source order, e.g.: @1: %x = add %y, 1 b @3 @2 %y = ... b @1 it's legal for %x to use %y there (assuming @2 dominates @1) but from the point of view of the register allocator %y is defined and freed and then used again, which broke things. the fix is to introduce phis for this situation: @1: %y.1 = phi @2 %y %x = add %y.1, 1 b @3 @2 %y = ... b @1 then regalloc phi handling code makes it work --- irdump.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'irdump.c') diff --git a/irdump.c b/irdump.c index 3d95843..21b5f09 100644 --- a/irdump.c +++ b/irdump.c @@ -196,10 +196,9 @@ dumpblk(struct function *fn, struct block *blk) for (i = 0; i < blk->phi.n; ++i) { struct instr *phi = &instrtab[blk->phi.p[i]]; union ref *refs = phitab.p[phi->l.i]; - assert(phi->op == Ophi); efmt(" %s ", clsname[phi->cls]); - if (!phi->reg) efmt("%%%d = phi ", blk->phi.p[i]); - else efmt("(%%%d)%s = phi ", phi - instrtab, mctarg->rnames[phi->reg-1]); + if (!phi->reg) efmt("%%%d = %s ", blk->phi.p[i], opnames[phi->op]); + else efmt("(%%%d)%s = %s ", phi - instrtab, mctarg->rnames[phi->reg-1], opnames[phi->op]); for (int i = 0; i < blk->npred; ++i) { if (i) efmt(", "); efmt("@%d ", blkpred(blk, i)->id); -- cgit v1.2.3