Skip to content

Commit 262fb91

Browse files
authored
gh-117288: Allocate fewer label IDs in _PyCfg_ToInstructionSequence (#117290)
1 parent 74c8568 commit 262fb91

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

Include/internal/pycore_compile.h

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ int _PyCompile_InstructionSequence_UseLabel(_PyCompile_InstructionSequence *seq,
6666
int _PyCompile_InstructionSequence_Addop(_PyCompile_InstructionSequence *seq,
6767
int opcode, int oparg,
6868
_PyCompilerSrcLocation loc);
69+
int _PyCompile_InstructionSequence_ApplyLabelMap(_PyCompile_InstructionSequence *seq);
6970

7071
typedef struct {
7172
PyObject *u_name;

Python/assemble.c

+3
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,9 @@ _PyAssemble_MakeCodeObject(_PyCompile_CodeUnitMetadata *umd, PyObject *const_cac
736736
int nlocalsplus, int code_flags, PyObject *filename)
737737
{
738738

739+
if (_PyCompile_InstructionSequence_ApplyLabelMap(instrs) < 0) {
740+
return NULL;
741+
}
739742
if (resolve_unconditional_jumps(instrs) < 0) {
740743
return NULL;
741744
}

Python/compile.c

+30-4
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,28 @@ _PyCompile_InstructionSequence_UseLabel(instr_sequence *seq, int lbl)
235235
return SUCCESS;
236236
}
237237

238+
int
239+
_PyCompile_InstructionSequence_ApplyLabelMap(instr_sequence *instrs)
240+
{
241+
/* Replace labels by offsets in the code */
242+
for (int i=0; i < instrs->s_used; i++) {
243+
instruction *instr = &instrs->s_instrs[i];
244+
if (HAS_TARGET(instr->i_opcode)) {
245+
assert(instr->i_oparg < instrs->s_labelmap_size);
246+
instr->i_oparg = instrs->s_labelmap[instr->i_oparg];
247+
}
248+
_PyCompile_ExceptHandlerInfo *hi = &instr->i_except_handler_info;
249+
if (hi->h_label >= 0) {
250+
assert(hi->h_label < instrs->s_labelmap_size);
251+
hi->h_label = instrs->s_labelmap[hi->h_label];
252+
}
253+
}
254+
/* Clear label map so it's never used again */
255+
PyMem_Free(instrs->s_labelmap);
256+
instrs->s_labelmap = NULL;
257+
instrs->s_labelmap_size = 0;
258+
return SUCCESS;
259+
}
238260

239261
#define MAX_OPCODE 511
240262

@@ -7824,11 +7846,8 @@ instr_sequence_to_instructions(instr_sequence *seq)
78247846
for (int i = 0; i < seq->s_used; i++) {
78257847
instruction *instr = &seq->s_instrs[i];
78267848
location loc = instr->i_loc;
7827-
int arg = HAS_TARGET(instr->i_opcode) ?
7828-
seq->s_labelmap[instr->i_oparg] : instr->i_oparg;
7829-
78307849
PyObject *inst_tuple = Py_BuildValue(
7831-
"(iiiiii)", instr->i_opcode, arg,
7850+
"(iiiiii)", instr->i_opcode, instr->i_oparg,
78327851
loc.lineno, loc.end_lineno,
78337852
loc.col_offset, loc.end_col_offset);
78347853
if (inst_tuple == NULL) {
@@ -7855,6 +7874,9 @@ cfg_to_instructions(cfg_builder *g)
78557874
if (_PyCfg_ToInstructionSequence(g, &seq) < 0) {
78567875
return NULL;
78577876
}
7877+
if (_PyCompile_InstructionSequence_ApplyLabelMap(&seq) < 0) {
7878+
return NULL;
7879+
}
78587880
PyObject *res = instr_sequence_to_instructions(&seq);
78597881
instr_sequence_fini(&seq);
78607882
return res;
@@ -8026,6 +8048,10 @@ _PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags,
80268048
goto finally;
80278049
}
80288050

8051+
if (_PyCompile_InstructionSequence_ApplyLabelMap(INSTR_SEQUENCE(c)) < 0) {
8052+
return NULL;
8053+
}
8054+
80298055
PyObject *insts = instr_sequence_to_instructions(INSTR_SEQUENCE(c));
80308056
if (insts == NULL) {
80318057
goto finally;

Python/flowgraph.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -2717,13 +2717,14 @@ _PyCfg_ToInstructionSequence(cfg_builder *g, _PyCompile_InstructionSequence *seq
27172717
int lbl = 0;
27182718
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
27192719
b->b_label = (jump_target_label){lbl};
2720-
lbl += b->b_iused;
2720+
lbl += 1;
27212721
}
27222722
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
27232723
RETURN_IF_ERROR(_PyCompile_InstructionSequence_UseLabel(seq, b->b_label.id));
27242724
for (int i = 0; i < b->b_iused; i++) {
27252725
cfg_instr *instr = &b->b_instr[i];
2726-
if (OPCODE_HAS_JUMP(instr->i_opcode) || is_block_push(instr)) {
2726+
if (HAS_TARGET(instr->i_opcode)) {
2727+
/* Set oparg to the label id (it will later be mapped to an offset) */
27272728
instr->i_oparg = instr->i_target->b_label.id;
27282729
}
27292730
RETURN_IF_ERROR(

0 commit comments

Comments
 (0)