@@ -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-
168162static 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