Skip to content

Commit 0a1b0e1

Browse files
committed
Decent pausing point, not working rn tho
1 parent 3e6ceca commit 0a1b0e1

File tree

8 files changed

+2055
-413
lines changed

8 files changed

+2055
-413
lines changed

cuik_c/driver/driver.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,8 @@ void cuik_step_free(Cuik_BuildStep* s) {
639639
}
640640

641641
bool cuik_driver_does_codegen(const Cuik_DriverArgs* args) {
642-
return !args->emit_ir && !args->test_preproc && !args->preprocess && !args->syntax_only && !args->ast;
642+
return false;
643+
// return !args->emit_ir && !args->test_preproc && !args->preprocess && !args->syntax_only && !args->ast;
643644
}
644645

645646
void cuikpp_dump_tokens(TokenStream* s) {

tb/codegen.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ struct VReg {
102102
// BRIGGS: when coalesced this number will go up
103103
int uses;
104104

105-
bool was_spilled : 1;
105+
int was_spilled : 2;
106106
bool was_reload : 1;
107107
};
108108

@@ -347,7 +347,12 @@ static double get_spill_cost(Ctx* restrict ctx, VReg* vreg) {
347347
return INFINITY;
348348
}
349349

350-
return vreg->spill_cost / vreg->area;
350+
double score = vreg->spill_cost / vreg->area;
351+
if (vreg->was_spilled == 2) {
352+
score += 1e6;
353+
}
354+
355+
return score;
351356
}
352357

353358
static int op_reg_at(Ctx* ctx, TB_Node* n, int class) {
@@ -572,6 +577,14 @@ static bool bits64_member(uint64_t* arr, size_t x) {
572577
return arr[x / 64] & (1ull << (x % 64));
573578
}
574579

580+
static bool is_spill_store(TB_Node* n) {
581+
if (n->type == TB_MACH_COPY) {
582+
TB_NodeMachCopy* cpy = TB_NODE_GET_EXTRA(n);
583+
return reg_mask_is_stack(cpy->def);
584+
}
585+
return false;
586+
}
587+
575588
static bool is_gcref_dt(TB_DataType dt) {
576589
return dt.type == TB_TAG_PTR && dt.elem_or_addrspace > 0;
577590
}

tb/codegen_impl.h

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -849,53 +849,45 @@ static void compile_function(TB_Function* restrict f, TB_CodegenRA ra, TB_Functi
849849
}
850850

851851
CUIK_TIMED_BLOCK("gather RA constraints") {
852-
#if TB_OPTDEBUG_REGALLOC
853-
printf("====== PRE-RA %-20s ======\n", ctx.f->super.name);
854-
#endif
852+
IF_OPT(REGALLOC) {
853+
printf("====== PRE-RA %-20s ======\n", ctx.f->super.name);
854+
}
855855

856856
FOR_N(i, 0, bb_count) {
857857
TB_BasicBlock* bb = &cfg.blocks[i];
858858

859-
#if TB_OPTDEBUG_REGALLOC
860-
printf("BB %zu (freq=%.4f)\n", i, bb->freq);
861-
#endif
862-
859+
TB_OPTDEBUG(REGALLOC)(printf("BB %zu (freq=%.4f)\n", i, bb->freq));
863860
aarray_for(j, bb->items) {
864861
TB_Node* n = bb->items[j];
865-
866-
#if TB_OPTDEBUG_REGALLOC
867-
printf(" "), tb_print_dumb_node(NULL, n), printf("\n");
868-
#endif
862+
TB_OPTDEBUG(REGALLOC)(printf(" "), tb_print_dumb_node(NULL, n), printf("\n"));
869863

870864
RegMask* def_mask = node_constraint(&ctx, n, ctx.ins);
871865
int vreg_id = try_create_vreg(&ctx, n, def_mask);
872866

873-
#if TB_OPTDEBUG_REGALLOC
874-
if (vreg_id > 0) {
875-
printf(" OUT = "), tb__print_regmask(&OUT_STREAM_DEFAULT, def_mask), printf(" \x1b[32m# VREG=%d\x1b[0m\n", vreg_id);
876-
}
867+
IF_OPT(REGALLOC) {
868+
if (vreg_id > 0) {
869+
printf(" OUT = "), tb__print_regmask(&OUT_STREAM_DEFAULT, def_mask), printf(" \x1b[32m# VREG=%d\x1b[0m\n", vreg_id);
870+
}
877871

878-
FOR_N(k, 1, n->input_count) {
879-
if (n->inputs[k]) {
880-
if (n->inputs[k]->type == TB_MACH_TEMP) {
881-
printf(" TMP[%zu] = ", k), tb__print_regmask(&OUT_STREAM_DEFAULT, ctx.ins[k]), printf(" %%%d\n", n->inputs[k]->gvn);
882-
} else if (ctx.ins[k] != &TB_REG_EMPTY) {
883-
printf(" IN[%zu] = ", k), tb__print_regmask(&OUT_STREAM_DEFAULT, ctx.ins[k]), printf(" %%%d\n", n->inputs[k]->gvn);
872+
FOR_N(k, 1, n->input_count) {
873+
if (n->inputs[k]) {
874+
if (n->inputs[k]->type == TB_MACH_TEMP) {
875+
printf(" TMP[%zu] = ", k), tb__print_regmask(&OUT_STREAM_DEFAULT, ctx.ins[k]), printf(" %%%d\n", n->inputs[k]->gvn);
876+
} else if (ctx.ins[k] != &TB_REG_EMPTY) {
877+
printf(" IN[%zu] = ", k), tb__print_regmask(&OUT_STREAM_DEFAULT, ctx.ins[k]), printf(" %%%d\n", n->inputs[k]->gvn);
878+
}
884879
}
885880
}
886-
}
887881

888-
int kill_count = node_constraint_kill(&ctx, n, ctx.ins);
889-
FOR_N(k, 0, kill_count) {
890-
printf(" KILL[%zu] = ", k), tb__print_regmask(&OUT_STREAM_DEFAULT, ctx.ins[k]), printf("\n");
882+
int kill_count = node_constraint_kill(&ctx, n, ctx.ins);
883+
FOR_N(k, 0, kill_count) {
884+
printf(" KILL[%zu] = ", k), tb__print_regmask(&OUT_STREAM_DEFAULT, ctx.ins[k]), printf("\n");
885+
}
891886
}
892-
#endif
893887
}
894888
}
895889

896-
#if TB_OPTDEBUG_REGALLOC
897-
printf("=======================================\n");
898-
#endif
890+
TB_OPTDEBUG(REGALLOC)(printf("=======================================\n"));
899891
}
900892

901893
CUIK_TIMED_BLOCK("regalloc") {
@@ -1267,7 +1259,7 @@ static void compile_function(TB_Function* restrict f, TB_CodegenRA ra, TB_Functi
12671259
#endif
12681260

12691261
#if TB_OPTDEBUG_STATS
1270-
printf("%f miss rate (%d misses, %d hits)\n", stats_miss / (float) (stats_miss + stats_hit), stats_miss, stats_hit));
1262+
printf("%f miss rate (%d misses, %d hits)\n", stats_miss / (float) (stats_miss + stats_hit), stats_miss, stats_hit);
12711263
#endif
12721264

12731265
tb_arena_clear(&f->tmp_arena);

tb/ra_split.c

Lines changed: 31 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ typedef struct {
2121
RegMask** reload_mask;
2222

2323
int* spill_vreg_id;
24+
int* was_spilled;
25+
2426
NL_Table spill_map;
2527
} RegSplitter;
2628

@@ -157,14 +159,6 @@ static bool has_immediate_use(TB_Node* n, TB_Node* of) {
157159
return false;
158160
}
159161

160-
static bool is_spill_store(TB_Node* n) {
161-
if (n->type == TB_MACH_COPY) {
162-
TB_NodeMachCopy* cpy = TB_NODE_GET_EXTRA(n);
163-
return reg_mask_is_stack(cpy->def);
164-
}
165-
return false;
166-
}
167-
168162
static TB_Node* insert_reload(Ctx* ctx, Rogers* ra, RegSplitter* splitter, TB_BasicBlock* bb, TB_Node** defs, TB_Node** bb_defs, int spill, uint64_t W, size_t* insert_pos) {
169163
TB_Function* f = ctx->f;
170164
size_t bb_id = bb - ctx->cfg.blocks;
@@ -358,18 +352,17 @@ static void* arena_zalloc(TB_Arena* arena, size_t size) {
358352
return ptr;
359353
}
360354

361-
static int bbb;
362-
static void tb__insert_splits(Ctx* ctx, Rogers* restrict ra) {
355+
static void tb__insert_splits(Ctx* ctx, Rogers* restrict ra, SplitDecision* splits, size_t num_spills) {
363356
TB_Arena* arena = ra->arena;
364357
TB_Function* f = ctx->f;
365358

366-
bbb++;
367-
tb_opt__REGSPLIT = bbb >= 10;
359+
// static int bbb;
360+
// bbb++;
361+
// tb_opt__REGSPLIT = bbb == 2; // bbb == 10 || bbb == 11;
368362

369363
TB_OPTDEBUG(REGSPLIT)(printf("== INSERT NODES ==\n"));
370364

371365
size_t old_node_count = f->node_count;
372-
size_t num_spills = dyn_array_length(ra->splits);
373366

374367
// we can only spill 64 vregs at once due to some bitsets i don't feel like changing
375368
TB_ASSERT(num_spills <= 64);
@@ -383,11 +376,12 @@ static void tb__insert_splits(Ctx* ctx, Rogers* restrict ra) {
383376
splitter.leaders = tb_arena_alloc(ra->arena, num_spills * sizeof(TB_Node*));
384377

385378
splitter.spill_vreg_id = tb_arena_alloc(ra->arena, num_spills * sizeof(int));
379+
splitter.was_spilled = tb_arena_alloc(ra->arena, num_spills * sizeof(int));
386380

387381
uint64_t was_spilled_before = 0;
388382
uint64_t class2vreg[MAX_REG_CLASSES] = { 0 };
389383
FOR_N(i, 0, num_spills) {
390-
uint32_t vreg_id = ra->splits[i].target;
384+
uint32_t vreg_id = splits[i].target;
391385

392386
VReg* to_spill = &ctx->vregs[vreg_id];
393387
int class = to_spill->mask->class;
@@ -398,8 +392,8 @@ static void tb__insert_splits(Ctx* ctx, Rogers* restrict ra) {
398392
// don't ever need "splitting"
399393
TB_ASSERT(!reg_mask_is_stack(to_spill->mask));
400394
splitter.reload_mask[i] = ctx->normie_mask[class];
401-
if (ra->splits[i].clobber) {
402-
RegMask* clobber = ra->splits[i].clobber;
395+
if (splits[i].clobber) {
396+
RegMask* clobber = splits[i].clobber;
403397
TB_ASSERT(ctx->num_regs[clobber->class] < 64);
404398

405399
uint64_t total_mask = UINT64_MAX >> (64 - ctx->num_regs[clobber->class]);
@@ -408,6 +402,7 @@ static void tb__insert_splits(Ctx* ctx, Rogers* restrict ra) {
408402
splitter.spill_mask[i] = ctx->mayspill_mask[class];
409403
}
410404
splitter.spill_vreg_id[i] = 0;
405+
splitter.was_spilled[i] = to_spill->was_spilled;
411406

412407
if (to_spill->was_spilled) {
413408
was_spilled_before |= 1ull << i;
@@ -495,15 +490,15 @@ static void tb__insert_splits(Ctx* ctx, Rogers* restrict ra) {
495490
IF_OPT(REGSPLIT) {
496491
printf("== TO BE SPILLED ==\n");
497492
FOR_N(i, 0, num_spills) {
498-
uint32_t vreg_id = ra->splits[i].target;
493+
uint32_t vreg_id = splits[i].target;
499494
double cost = rogers_get_spill_cost(ctx, ra, &ctx->vregs[vreg_id]);
500495

501496
printf(" V%-5u %f %lu", vreg_id, cost, ctx->vregs[vreg_id].area);
502497
if ((spill_aggro >> i) & 1) {
503498
printf(" (SPILL AGGRO)");
504499
}
505-
if ((was_spilled_before >> i) & 1) {
506-
printf(" (SPILLED BEFORE)");
500+
if (splitter.was_spilled[i]) {
501+
printf(" (SPILLED %d TIMES)", splitter.was_spilled[i]);
507502
}
508503
if ((splitter.remat_all >> i) & 1) {
509504
printf(" (REMAT HARD)");
@@ -519,13 +514,11 @@ static void tb__insert_splits(Ctx* ctx, Rogers* restrict ra) {
519514
ctx->print_pretty(ctx, n);
520515
printf(" (%d uses)\n", n->user_count);
521516

522-
/* if (n->gvn == 3194) {
523-
FOR_USERS(u, n) {
524-
printf("|| ");
525-
ctx->print_pretty(ctx, USERN(u));
526-
printf("\n");
527-
}
528-
} */
517+
/* FOR_USERS(u, n) {
518+
printf("|| ");
519+
ctx->print_pretty(ctx, USERN(u));
520+
printf("\n");
521+
}*/
529522
}
530523
}
531524
}
@@ -1148,20 +1141,18 @@ static void tb__insert_splits(Ctx* ctx, Rogers* restrict ra) {
11481141
TB_ASSERT(n->gvn < aarray_length(ctx->vreg_map));
11491142
ctx->vreg_map[n->gvn] = 0;
11501143

1151-
#if TB_OPTDEBUG_REGSPLIT
1152-
printf(" ");
1153-
ctx->print_pretty(ctx, n);
1154-
printf("\n");
1155-
#endif
1144+
IF_OPT(REGSPLIT) {
1145+
printf(" ");
1146+
ctx->print_pretty(ctx, n);
1147+
printf("\n");
1148+
}
11561149

11571150
// most of these nodes don't really have a bound set but whatever
11581151
nl_table_remove(&ra->coalesce_set, (void*) (uintptr_t) (n->gvn + 1));
11591152
i += 1;
11601153
}
11611154

1162-
#if TB_OPTDEBUG_REGSPLIT
1163-
printf("\n");
1164-
#endif
1155+
TB_OPTDEBUG(REGSPLIT)(printf("\n"));
11651156

11661157
// we can now aggressively coalesce nodes without
11671158
// worry... unless it's a copy node, we assume those
@@ -1201,8 +1192,12 @@ static void tb__insert_splits(Ctx* ctx, Rogers* restrict ra) {
12011192
TB_ASSERT(vreg_id == 0);
12021193

12031194
VReg* new_vreg = tb__set_node_vreg(ctx, n);
1204-
new_vreg->was_spilled = true;
12051195
ctx->vreg_map[leader] = new_vreg - ctx->vregs;
1196+
1197+
int spill = spill_map_get2(&splitter.spill_map, n);
1198+
if (spill >= 0) {
1199+
new_vreg->was_spilled = splitter.was_spilled[spill] + 1;
1200+
}
12061201
}
12071202

12081203
aarray_for(i, splitter.all_defs) {
@@ -1214,33 +1209,14 @@ static void tb__insert_splits(Ctx* ctx, Rogers* restrict ra) {
12141209
if (n->gvn == leader) {
12151210
VReg* vreg = &ctx->vregs[vreg_id];
12161211
vreg->reg_width = tb__reg_width_from_dt(mask->class, n->dt);
1217-
vreg->spill_bias = mask->may_spill ? -100.0f : 100.0f;
1218-
1219-
int spill = spill_map_get2(&splitter.spill_map, n);
1220-
TB_ASSERT(spill >= 0);
1221-
1222-
if (((was_spilled_before | spill_aggro) >> spill) & 1) {
1223-
vreg->spill_bias = 1e6;
1224-
}
1212+
vreg->spill_bias = mask->may_spill ? -100.0f : 0.0f;
12251213
}
12261214
mask = tb__reg_mask_meet(ctx, mask, ctx->vregs[vreg_id].mask);
12271215

1228-
/* if (vreg_id == 3148) {
1229-
printf("GGG V%d DEF%%%u ", vreg_id, n->gvn);
1230-
tb__print_regmask(&OUT_STREAM_DEFAULT, mask);
1231-
printf("\n");
1232-
} */
1233-
12341216
FOR_USERS(u, n) {
12351217
if (USERI(u) > 0 && USERI(u) < USERN(u)->input_count) {
12361218
RegMask* in_mask = constraint_in(ctx, USERN(u), USERI(u));
12371219
mask = tb__reg_mask_meet(ctx, mask, in_mask);
1238-
1239-
/* if (vreg_id == 3148) {
1240-
printf("GGG V%d USE%%%u:%d ", vreg_id, USERN(u)->gvn, USERI(u));
1241-
tb__print_regmask(&OUT_STREAM_DEFAULT, in_mask);
1242-
printf("\n");
1243-
} */
12441220
}
12451221
}
12461222

@@ -1324,9 +1300,5 @@ static void tb__insert_splits(Ctx* ctx, Rogers* restrict ra) {
13241300
nl_table_free(splitter.spill_map);
13251301
TB_OPTDEBUG(SERVER)(dbg_submit_event_sched(&ctx->cfg, f, "Post-split"));
13261302
TB_OPTDEBUG(REGSPLIT)(rogers_dump_sched(ctx, old_node_count));
1327-
1328-
if (bbb == 15) {
1329-
exit(0);
1330-
}
13311303
}
13321304

0 commit comments

Comments
 (0)