diff options
| author | 2025-12-04 19:07:08 +0100 | |
|---|---|---|
| committer | 2025-12-04 19:07:08 +0100 | |
| commit | c7ef47c324ecd1e3213c7d93067680a822600f21 (patch) | |
| tree | 994a75dd2c3667f09b289afff3cb6846a2a56155 | |
| parent | 8a960c718d301b3a08e3513a88ebd617148311fb (diff) | |
regalloc: kill dead defs of physical regs
| -rw-r--r-- | ir/regalloc.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/ir/regalloc.c b/ir/regalloc.c index 6706905..65a37e1 100644 --- a/ir/regalloc.c +++ b/ir/regalloc.c @@ -542,18 +542,20 @@ usereg(struct rega *ra, int reg, struct block *blk, int pos) ra->intervals.fixed = fxit; } -static void +static bool defreg(struct rega *ra, int reg, int pos) { - if (rstest(mctarg->rglob, reg)) return; + if (rstest(mctarg->rglob, reg)) return 1; for (struct fixinterval *fxit = ra->intervals.fixed; fxit; fxit = fxit->next) { if (fxit->rs == 1<<reg) { - assert(fxit->range.from <= pos); - fxit->range.from = pos; - //DBG(">>>def REG %s range %d-%d\n", mctarg->rnames[reg], fxit->range.from, fxit->range.to); - return; + if (fxit->range.from <= pos) { + fxit->range.from = pos; + //DBG(">>>def REG %s range %d-%d\n", mctarg->rnames[reg], fxit->range.from, fxit->range.to); + return 1; + } + break; } } - assert(0&&"def reg not used"); + return 0; } /* lifetime interval construction: https://c9x.me/compile/bib/Wimmer10a.pdf */ @@ -630,7 +632,13 @@ buildintervals(struct rega *ra) assert(ins->l.t == RREG); if (ins->l.bits == ins->r.bits) /* special case `move Rx,Rx`: clobber reg, not a real use */ usereg(ra, ins->l.i, blk, pos); - defreg(ra, ins->l.i, pos); + if (!defreg(ra, ins->l.i, pos)) { + /* dead register use. for example if + * move RCX, %1 + * %2 = shl 1, RCX + * and %2 is dead, the move to RCX can be killed */ + *ins = mkinstr(Onop,0,); + } if (ins->l.bits == ins->r.bits) continue; } else if (ins->op == Ocall) { |