aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-10-22 09:11:35 +0200
committerlemon <lsof@mailbox.org>2025-10-22 09:11:35 +0200
commitf5714c5c553e9816eef4cfddef128ba2706fb118 (patch)
tree0e394fb111f81e5db72c6b88f65f5a6f2c08f528
parentaa9ba3a897327e7a88fbd1235eb21e2fb8d962d3 (diff)
regalloc fix devirt
-rw-r--r--ir/regalloc.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/ir/regalloc.c b/ir/regalloc.c
index 1e23a8a..b9f5517 100644
--- a/ir/regalloc.c
+++ b/ir/regalloc.c
@@ -156,6 +156,7 @@ struct interval {
struct intervals {
int count; /* number of actual intervals */
+ int ntemps; /* size of temps */
struct interval *temps; /* map of tmp -> interval */
struct fixinterval {
struct fixinterval *next;
@@ -533,6 +534,7 @@ buildintervals(struct rega *ra)
for (int i = 0; i < ra->fn->nblk; ++i)
livein[i] = allocz(ra->arena, bssize * sizeof *livein[i], 0);
ra->intervals.temps = allocz(ra->arena, ninstr * sizeof *ra->intervals.temps, 0);
+ ra->intervals.ntemps = ninstr;
numberinstrs(ra->fn);
/* visit blocks in reverse, to build lifetime intervals */
@@ -1010,11 +1012,11 @@ devirt(struct rega *ra, struct block *blk)
if (nspill > 0) assert(ins->op != Ocall);
/* devirtualize destination */
- alloc = temp < ra->intervals.count && (it = &ra->intervals.temps[temp]) && it->nrange ? &it->alloc : NULL;
+ alloc = temp < ra->intervals.ntemps && (it = &ra->intervals.temps[temp]) && it->nrange ? &it->alloc : NULL;
if (alloc && alloc->t == ASTACK) {
int store = Ostore1 + ilog2(cls2siz[insrescls(*ins)]);
/* t was spilled, gen store */
- if (ins->op == Ocopy) {
+ if (ins->op == Ocopy && ins->l.t != RADDR) {
ins->op = store;
ins->r = ins->l;
addstkslotref(temp, alloc->a*8);
@@ -1027,7 +1029,7 @@ devirt(struct rega *ra, struct block *blk)
alloc->a*8);
}
}
- if (!ins->reg && insrescls(*ins) && ins->op != Omove && !ins->keep) {
+ if (!ins->reg && insrescls(*ins) && ins->op != Omove && !ins->keep && !in_range(ins->op, Ostore1, Ostore8)) {
/* dead */
Nop:
ins->op = Onop;