Skip to content

Commit 8d015fa

Browse files
authored
gh-102860: improve performance of compiler's instr_sequence_to_cfg (#102861)
1 parent d1b883b commit 8d015fa

File tree

1 file changed

+44
-6
lines changed

1 file changed

+44
-6
lines changed

Python/compile.c

+44-6
Original file line numberDiff line numberDiff line change
@@ -595,17 +595,52 @@ static int
595595
instr_sequence_to_cfg(instr_sequence *seq, cfg_builder *g) {
596596
memset(g, 0, sizeof(cfg_builder));
597597
RETURN_IF_ERROR(cfg_builder_init(g));
598-
/* Note: there can be more than one label for the same offset */
598+
599+
/* There can be more than one label for the same offset. The
600+
* offset2lbl maping selects one of them which we use consistently.
601+
*/
602+
603+
int *offset2lbl = PyMem_Malloc(seq->s_used * sizeof(int));
604+
if (offset2lbl == NULL) {
605+
PyErr_NoMemory();
606+
return ERROR;
607+
}
599608
for (int i = 0; i < seq->s_used; i++) {
600-
for (int j=0; j < seq->s_labelmap_size; j++) {
601-
if (seq->s_labelmap[j] == i) {
602-
jump_target_label lbl = {j};
603-
RETURN_IF_ERROR(cfg_builder_use_label(g, lbl));
609+
offset2lbl[i] = -1;
610+
}
611+
for (int lbl=0; lbl < seq->s_labelmap_size; lbl++) {
612+
int offset = seq->s_labelmap[lbl];
613+
if (offset >= 0) {
614+
assert(offset < seq->s_used);
615+
offset2lbl[offset] = lbl;
616+
}
617+
}
618+
619+
for (int i = 0; i < seq->s_used; i++) {
620+
int lbl = offset2lbl[i];
621+
if (lbl >= 0) {
622+
assert (lbl < seq->s_labelmap_size);
623+
jump_target_label lbl_ = {lbl};
624+
if (cfg_builder_use_label(g, lbl_) < 0) {
625+
goto error;
604626
}
605627
}
606628
instruction *instr = &seq->s_instrs[i];
607-
RETURN_IF_ERROR(cfg_builder_addop(g, instr->i_opcode, instr->i_oparg, instr->i_loc));
629+
int opcode = instr->i_opcode;
630+
int oparg = instr->i_oparg;
631+
if (HAS_TARGET(opcode)) {
632+
int offset = seq->s_labelmap[oparg];
633+
assert(offset >= 0 && offset < seq->s_used);
634+
int lbl = offset2lbl[offset];
635+
assert(lbl >= 0 && lbl < seq->s_labelmap_size);
636+
oparg = lbl;
637+
}
638+
if (cfg_builder_addop(g, opcode, oparg, instr->i_loc) < 0) {
639+
goto error;
640+
}
608641
}
642+
PyMem_Free(offset2lbl);
643+
609644
int nblocks = 0;
610645
for (basicblock *b = g->g_block_list; b != NULL; b = b->b_list) {
611646
nblocks++;
@@ -615,6 +650,9 @@ instr_sequence_to_cfg(instr_sequence *seq, cfg_builder *g) {
615650
return ERROR;
616651
}
617652
return SUCCESS;
653+
error:
654+
PyMem_Free(offset2lbl);
655+
return ERROR;
618656
}
619657

620658

0 commit comments

Comments
 (0)