Skip to content

Commit

Permalink
simplify instr_sequence_to_cfg
Browse files Browse the repository at this point in the history
  • Loading branch information
iritkatriel committed Apr 2, 2024
1 parent f05f342 commit 3681be6
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Include/internal/pycore_instruction_sequence.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ typedef struct {
_Py_SourceLocation i_loc;
_PyExceptHandlerInfo i_except_handler_info;

/* Used by the assembler */
/* Temporary fields, used by the assembler and in instr_sequence_to_cfg */
int i_target;
int i_offset;
} _PyInstruction;
Expand Down
43 changes: 12 additions & 31 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,62 +197,43 @@ _PyCompile_EnsureArrayLargeEnough(int idx, void **array, int *alloc,

static cfg_builder*
instr_sequence_to_cfg(instr_sequence *seq) {
if (_PyInstructionSequence_ApplyLabelMap(seq) < 0) {
return NULL;
}
cfg_builder *g = _PyCfgBuilder_New();
if (g == NULL) {
return NULL;
}

/* There can be more than one label for the same offset. The
* offset2lbl maping selects one of them which we use consistently.
*/

int *offset2lbl = PyMem_Malloc(seq->s_used * sizeof(int));
if (offset2lbl == NULL) {
PyErr_NoMemory();
goto error;
}
for (int i = 0; i < seq->s_used; i++) {
offset2lbl[i] = -1;
seq->s_instrs[i].i_target = 0;
}
for (int lbl=0; lbl < seq->s_labelmap_size; lbl++) {
int offset = seq->s_labelmap[lbl];
if (offset >= 0) {
assert(offset < seq->s_used);
offset2lbl[offset] = lbl;
for (int i = 0; i < seq->s_used; i++) {
instruction *instr = &seq->s_instrs[i];
if (HAS_TARGET(instr->i_opcode)) {
assert(instr->i_oparg >= 0 && instr->i_oparg < seq->s_used);
seq->s_instrs[instr->i_oparg].i_target = 1;
}
}

for (int i = 0; i < seq->s_used; i++) {
int lbl = offset2lbl[i];
if (lbl >= 0) {
assert (lbl < seq->s_labelmap_size);
jump_target_label lbl_ = {lbl};
instruction *instr = &seq->s_instrs[i];
if (instr->i_target) {
jump_target_label lbl_ = {i};
if (_PyCfgBuilder_UseLabel(g, lbl_) < 0) {
goto error;
}
}
instruction *instr = &seq->s_instrs[i];
int opcode = instr->i_opcode;
int oparg = instr->i_oparg;
if (HAS_TARGET(opcode)) {
int offset = seq->s_labelmap[oparg];
assert(offset >= 0 && offset < seq->s_used);
int lbl = offset2lbl[offset];
assert(lbl >= 0 && lbl < seq->s_labelmap_size);
oparg = lbl;
}
if (_PyCfgBuilder_Addop(g, opcode, oparg, instr->i_loc) < 0) {
goto error;
}
}
if (_PyCfgBuilder_CheckSize(g) < 0) {
goto error;
}
PyMem_Free(offset2lbl);
return g;
error:
_PyCfgBuilder_Free(g);
PyMem_Free(offset2lbl);
return NULL;
}

Expand Down
4 changes: 4 additions & 0 deletions Python/instruction_sequence.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ _PyInstructionSequence_UseLabel(instr_sequence *seq, int lbl)
int
_PyInstructionSequence_ApplyLabelMap(instr_sequence *instrs)
{
if (instrs->s_labelmap == NULL) {
/* Already applied - nothing to do */
return SUCCESS;
}
/* Replace labels by offsets in the code */
for (int i=0; i < instrs->s_used; i++) {
instruction *instr = &instrs->s_instrs[i];
Expand Down

0 comments on commit 3681be6

Please sign in to comment.