aboutsummaryrefslogtreecommitdiffhomepage
path: root/irdump.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2023-06-26 00:29:07 +0200
committerlemon <lsof@mailbox.org>2023-06-26 00:29:07 +0200
commitb94fe89c9ddfcb85dcddebfd218fa7f00b8e6608 (patch)
tree153c345c5811343bb0f8f5190ead67f9f70b0d97 /irdump.c
parentbdb0276b534b817afb0b79f8e63196eed5d8bd7f (diff)
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
Diffstat (limited to 'irdump.c')
-rw-r--r--irdump.c5
1 files changed, 2 insertions, 3 deletions
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);