aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2025-04-02 21:15:13 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2025-04-02 21:15:13 +0300
commitb6642566af5ca9a21b7ce36ce9a996ff73f52da1 (patch)
tree06492ee38dea6f64433770a970ffb904e158df03
parent6c2e51a3f8695cb95d6a4a6859d3f934e28c8f9f (diff)
downloadejit-b6642566af5ca9a21b7ce36ce9a996ff73f52da1.tar.gz
ejit-b6642566af5ca9a21b7ce36ce9a996ff73f52da1.zip
fix regalloc
+ Had some small issues with ending lifetimes a bit too late
-rw-r--r--src/common.h1
-rw-r--r--src/compile/compile.c32
2 files changed, 15 insertions, 18 deletions
diff --git a/src/common.h b/src/common.h
index c690f8f..661220b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -289,6 +289,7 @@ struct ejit_func {
void *arena;
void *direct_call;
+ void *extern_call;
size_t size;
size_t prio;
size_t max_args;
diff --git a/src/compile/compile.c b/src/compile/compile.c
index 22da25a..dac8dfd 100644
--- a/src/compile/compile.c
+++ b/src/compile/compile.c
@@ -2465,39 +2465,35 @@ static void calculate_alive(struct alive *alive, size_t idx,
size_t prio, size_t start, size_t end, size_t *rno,
void *regs, int (*dead)(void *regs, size_t idx, size_t start))
{
- /* single-shot */
+ /* single-shot registers go in the special reserved slot */
if (end <= start + 1) {
*rno = 0;
+
struct alive_slot *a = alive_at(alive, 0);
a->cost += prio;
return;
}
+ /* kill registers whose lifetime has ended */
long max_cost_idx = -1;
size_t max_cost = 0;
long counter = 0;
foreach_vec(ai, *alive) {
- struct alive_slot *a = alive_at(alive, ai);
+ /* skip oneshot */
+ if (ai == 0)
+ goto next;
- /* skip reserved slot */
- if (idx == 0) {
- counter++;
- continue;
- }
+ struct alive_slot *a = alive_at(alive, ai);
+ if (a->r >= 0 && dead(regs, a->r, start))
+ a->r = -1; /* gravestone */
if (a->r < 0 && a->cost > max_cost) {
max_cost = a->cost;
max_cost_idx = counter;
}
+next:
counter++;
-
- /* skip gravestones */
- if (a->r < 0)
- continue;
-
- if (dead(regs, a->r, start))
- a->r = -1; /* gravestone */
}
/* there's a suitable slot for us */
@@ -2522,7 +2518,7 @@ static void calculate_alive(struct alive *alive, size_t idx,
static int gpr_dead(void *regs, size_t idx, size_t start)
{
struct gpr_stats *gprs = regs;
- return gpr_stats_at(gprs, idx)->end < start;
+ return gpr_stats_at(gprs, idx)->end <= start;
}
static void linear_gpr_alloc(struct ejit_func *f)
@@ -2542,7 +2538,7 @@ static void assign_gprs(struct ejit_func *f)
struct alive alive = alive_create(gpr_stats_len(&f->gpr));
/* special oneshot register class */
- struct alive_slot a = {.r = 0, .cost = 0, .idx = 0};
+ struct alive_slot a = {.r = -1, .cost = 0, .idx = 0};
alive_append(&alive, a);
foreach_vec(gi, f->gpr) {
@@ -2575,7 +2571,7 @@ static void assign_gprs(struct ejit_func *f)
static int fpr_dead(void *regs, size_t idx, size_t start)
{
struct fpr_stats *fprs = regs;
- return fpr_stats_at(fprs, idx)->end < start;
+ return fpr_stats_at(fprs, idx)->end <= start;
}
static void linear_fpr_alloc(struct ejit_func *f)
@@ -2594,7 +2590,7 @@ static void assign_fprs(struct ejit_func *f)
struct alive alive = alive_create(fpr_stats_len(&f->fpr));
/* special oneshot register class */
- struct alive_slot a = {.r = 0, .cost = 0, .idx = 0};
+ struct alive_slot a = {.r = -1, .cost = 0, .idx = 0};
alive_append(&alive, a);
foreach_vec(fi, f->fpr) {