diff options
| author | 2023-06-26 00:29:07 +0200 | |
|---|---|---|
| committer | 2023-06-26 00:29:07 +0200 | |
| commit | b94fe89c9ddfcb85dcddebfd218fa7f00b8e6608 (patch) | |
| tree | 153c345c5811343bb0f8f5190ead67f9f70b0d97 /irdump.c | |
| parent | bdb0276b534b817afb0b79f8e63196eed5d8bd7f (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.c | 5 |
1 files changed, 2 insertions, 3 deletions
@@ -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); |