@@ -140,16 +140,17 @@ struct location {
140
140
static struct location NO_LOCATION = {-1 , -1 , -1 , -1 };
141
141
142
142
typedef struct jump_target_label_ {
143
+ int id ;
143
144
struct basicblock_ * block ;
144
145
} jump_target_label ;
145
146
146
- static struct jump_target_label_ NO_LABEL = {NULL };
147
+ static struct jump_target_label_ NO_LABEL = {-1 , NULL };
147
148
148
- #define SAME_LABEL (L1 , L2 ) ((L1).block == (L2).block )
149
+ #define SAME_LABEL (L1 , L2 ) ((L1).id == (L2).id )
149
150
#define IS_LABEL (L ) (!SAME_LABEL((L), (NO_LABEL)))
150
151
151
152
#define NEW_JUMP_TARGET_LABEL (C , NAME ) \
152
- jump_target_label NAME = {cfg_builder_new_block(CFG_BUILDER(C))}; \
153
+ jump_target_label NAME = {cfg_new_label_id(CFG_BUILDER(C)), cfg_builder_new_block(CFG_BUILDER(C))}; \
153
154
if (!IS_LABEL(NAME)) { \
154
155
return 0; \
155
156
}
@@ -255,6 +256,8 @@ typedef struct basicblock_ {
255
256
reverse order that the block are allocated. b_list points to the next
256
257
block, not to be confused with b_next, which is next by control flow. */
257
258
struct basicblock_ * b_list ;
259
+ /* The label of this block if it is a jump target, -1 otherwise */
260
+ int b_label ;
258
261
/* Exception stack at start of block, used by assembler to create the exception handling table */
259
262
ExceptStack * b_exceptstack ;
260
263
/* pointer to an array of instructions, initially NULL */
@@ -356,6 +359,8 @@ typedef struct cfg_builder_ {
356
359
basicblock * curblock ;
357
360
/* label for the next instruction to be placed */
358
361
jump_target_label g_current_label ;
362
+ /* next free label id */
363
+ int g_next_free_label ;
359
364
} cfg_builder ;
360
365
361
366
/* The following items change on entry and exit of code blocks.
@@ -862,6 +867,11 @@ compiler_set_qualname(struct compiler *c)
862
867
return 1 ;
863
868
}
864
869
870
+ static int
871
+ cfg_new_label_id (cfg_builder * g )
872
+ {
873
+ return g -> g_next_free_label ++ ;
874
+ }
865
875
866
876
/* Allocate a new block and return a pointer to it.
867
877
Returns NULL on error.
@@ -877,6 +887,7 @@ cfg_builder_new_block(cfg_builder *g)
877
887
/* Extend the singly linked list of blocks with new block. */
878
888
b -> b_list = g -> block_list ;
879
889
g -> block_list = b ;
890
+ b -> b_label = -1 ;
880
891
return b ;
881
892
}
882
893
@@ -1314,6 +1325,7 @@ cfg_builder_maybe_start_new_block(cfg_builder *g)
1314
1325
basicblock * b ;
1315
1326
if (IS_LABEL (g -> g_current_label )) {
1316
1327
b = g -> g_current_label .block ;
1328
+ b -> b_label = g -> g_current_label .id ;
1317
1329
g -> g_current_label = NO_LABEL ;
1318
1330
}
1319
1331
else {
@@ -7398,7 +7410,7 @@ push_cold_blocks_to_end(cfg_builder *g, int code_flags) {
7398
7410
if (explicit_jump == NULL ) {
7399
7411
return -1 ;
7400
7412
}
7401
- jump_target_label next_label = {b -> b_next };
7413
+ jump_target_label next_label = {b -> b_next -> b_label , b -> b_next };
7402
7414
basicblock_addop (explicit_jump , JUMP , 0 , next_label , NO_LOCATION );
7403
7415
explicit_jump -> b_cold = 1 ;
7404
7416
explicit_jump -> b_next = b -> b_next ;
@@ -8228,8 +8240,8 @@ static void
8228
8240
dump_basicblock (const basicblock * b )
8229
8241
{
8230
8242
const char * b_return = basicblock_returns (b ) ? "return " : "" ;
8231
- fprintf (stderr , "[%d %d %d %p] used: %d, depth: %d, offset: %d %s\n" ,
8232
- b -> b_cold , b -> b_warm , BB_NO_FALLTHROUGH (b ), b , b -> b_iused ,
8243
+ fprintf (stderr , "%d: [%d %d %d %p] used: %d, depth: %d, offset: %d %s\n" ,
8244
+ b -> b_label , b -> b_cold , b -> b_warm , BB_NO_FALLTHROUGH (b ), b , b -> b_iused ,
8233
8245
b -> b_startdepth , b -> b_offset , b_return );
8234
8246
if (b -> b_instr ) {
8235
8247
int i ;
@@ -9424,15 +9436,34 @@ propagate_line_numbers(basicblock *entryblock) {
9424
9436
static int
9425
9437
calculate_jump_targets (basicblock * entryblock )
9426
9438
{
9439
+ int max_label = -1 ;
9440
+ for (basicblock * b = entryblock ; b != NULL ; b = b -> b_next ) {
9441
+ if (b -> b_label > max_label ) {
9442
+ max_label = b -> b_label ;
9443
+ }
9444
+ }
9445
+ size_t mapsize = sizeof (basicblock * ) * (max_label + 1 );
9446
+ basicblock * * label2block = (basicblock * * )PyMem_Malloc (mapsize );
9447
+ if (!label2block ) {
9448
+ PyErr_NoMemory ();
9449
+ return -1 ;
9450
+ }
9451
+ memset (label2block , 0 , mapsize );
9452
+ for (basicblock * b = entryblock ; b != NULL ; b = b -> b_next ) {
9453
+ if (b -> b_label >= 0 ) {
9454
+ label2block [b -> b_label ] = b ;
9455
+ }
9456
+ }
9427
9457
for (basicblock * b = entryblock ; b != NULL ; b = b -> b_next ) {
9428
9458
for (int i = 0 ; i < b -> b_iused ; i ++ ) {
9429
9459
struct instr * instr = & b -> b_instr [i ];
9430
9460
assert (instr -> i_target == NULL );
9431
- instr -> i_target = instr -> i_target_label .block ;
9432
- instr -> i_target_label = NO_LABEL ;
9461
+ instr -> i_target = label2block [instr -> i_target_label .id ];
9433
9462
if (is_jump (instr ) || is_block_push (instr )) {
9434
9463
assert (instr -> i_target != NULL );
9464
+ assert (instr -> i_target -> b_label == instr -> i_target_label .id );
9435
9465
}
9466
+ instr -> i_target_label = NO_LABEL ;
9436
9467
}
9437
9468
}
9438
9469
return 0 ;
0 commit comments