Skip to content

Commit 558b04c

Browse files
committed
add id to jump_target_label and use it to calculate i_target
1 parent c2050f6 commit 558b04c

File tree

1 file changed

+39
-8
lines changed

1 file changed

+39
-8
lines changed

Python/compile.c

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,17 @@ struct location {
140140
static struct location NO_LOCATION = {-1, -1, -1, -1};
141141

142142
typedef struct jump_target_label_ {
143+
int id;
143144
struct basicblock_ *block;
144145
} jump_target_label;
145146

146-
static struct jump_target_label_ NO_LABEL = {NULL};
147+
static struct jump_target_label_ NO_LABEL = {-1, NULL};
147148

148-
#define SAME_LABEL(L1, L2) ((L1).block == (L2).block)
149+
#define SAME_LABEL(L1, L2) ((L1).id == (L2).id)
149150
#define IS_LABEL(L) (!SAME_LABEL((L), (NO_LABEL)))
150151

151152
#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))}; \
153154
if (!IS_LABEL(NAME)) { \
154155
return 0; \
155156
}
@@ -255,6 +256,8 @@ typedef struct basicblock_ {
255256
reverse order that the block are allocated. b_list points to the next
256257
block, not to be confused with b_next, which is next by control flow. */
257258
struct basicblock_ *b_list;
259+
/* The label of this block if it is a jump target, -1 otherwise */
260+
int b_label;
258261
/* Exception stack at start of block, used by assembler to create the exception handling table */
259262
ExceptStack *b_exceptstack;
260263
/* pointer to an array of instructions, initially NULL */
@@ -356,6 +359,8 @@ typedef struct cfg_builder_ {
356359
basicblock *curblock;
357360
/* label for the next instruction to be placed */
358361
jump_target_label g_current_label;
362+
/* next free label id */
363+
int g_next_free_label;
359364
} cfg_builder;
360365

361366
/* The following items change on entry and exit of code blocks.
@@ -862,6 +867,11 @@ compiler_set_qualname(struct compiler *c)
862867
return 1;
863868
}
864869

870+
static int
871+
cfg_new_label_id(cfg_builder *g)
872+
{
873+
return g->g_next_free_label++;
874+
}
865875

866876
/* Allocate a new block and return a pointer to it.
867877
Returns NULL on error.
@@ -877,6 +887,7 @@ cfg_builder_new_block(cfg_builder *g)
877887
/* Extend the singly linked list of blocks with new block. */
878888
b->b_list = g->block_list;
879889
g->block_list = b;
890+
b->b_label = -1;
880891
return b;
881892
}
882893

@@ -1314,6 +1325,7 @@ cfg_builder_maybe_start_new_block(cfg_builder *g)
13141325
basicblock *b;
13151326
if (IS_LABEL(g->g_current_label)) {
13161327
b = g->g_current_label.block;
1328+
b->b_label = g->g_current_label.id;
13171329
g->g_current_label = NO_LABEL;
13181330
}
13191331
else {
@@ -7398,7 +7410,7 @@ push_cold_blocks_to_end(cfg_builder *g, int code_flags) {
73987410
if (explicit_jump == NULL) {
73997411
return -1;
74007412
}
7401-
jump_target_label next_label = {b->b_next};
7413+
jump_target_label next_label = {b->b_next->b_label, b->b_next};
74027414
basicblock_addop(explicit_jump, JUMP, 0, next_label, NO_LOCATION);
74037415
explicit_jump->b_cold = 1;
74047416
explicit_jump->b_next = b->b_next;
@@ -8228,8 +8240,8 @@ static void
82288240
dump_basicblock(const basicblock *b)
82298241
{
82308242
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,
82338245
b->b_startdepth, b->b_offset, b_return);
82348246
if (b->b_instr) {
82358247
int i;
@@ -9424,15 +9436,34 @@ propagate_line_numbers(basicblock *entryblock) {
94249436
static int
94259437
calculate_jump_targets(basicblock *entryblock)
94269438
{
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+
}
94279457
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
94289458
for (int i = 0; i < b->b_iused; i++) {
94299459
struct instr *instr = &b->b_instr[i];
94309460
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];
94339462
if (is_jump(instr) || is_block_push(instr)) {
94349463
assert(instr->i_target != NULL);
9464+
assert(instr->i_target->b_label == instr->i_target_label.id);
94359465
}
9466+
instr->i_target_label = NO_LABEL;
94369467
}
94379468
}
94389469
return 0;

0 commit comments

Comments
 (0)