Skip to content

Commit

Permalink
pythongh-93678: extract 'struct cfg' from the compiler so that the CF…
Browse files Browse the repository at this point in the history
…G can be manipulated directly
  • Loading branch information
iritkatriel committed Jul 26, 2022
1 parent a280869 commit d88ba72
Showing 1 changed file with 24 additions and 26 deletions.
50 changes: 24 additions & 26 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -9613,8 +9613,8 @@ unpack_instruction(PyObject *instr, int *label, int *opcode, int *oparg,
return 0;
}

static basicblock *
instructions_to_cfg(PyObject *instructions)
static int
instructions_to_cfg(PyObject *instructions, cfg_builder *g)
{
assert(PyList_Check(instructions));

Expand All @@ -9623,16 +9623,17 @@ instructions_to_cfg(PyObject *instructions)
basicblock **label2block = (basicblock **)PyMem_Malloc(sizeof(basicblock *) * max_labels);
if (!label2block) {
PyErr_NoMemory();
return -1;
}
memset(label2block, 0, sizeof(basicblock *) * max_labels);

basicblock *entryblock = new_basicblock();
if (entryblock == NULL) {
g->block_list = NULL;
basicblock *block = cfg_builder_new_block(g);
if (block == NULL) {
goto error;
}
basicblock *current_block = entryblock;
g->curblock = g->cfg_entryblock = block;

bool start_new_block = false;
for (Py_ssize_t i = 0; i < num_insts; i++) {
PyObject *instr_tuple = PyList_GET_ITEM(instructions, i);
int label, opcode, oparg, target;
Expand All @@ -9642,7 +9643,7 @@ instructions_to_cfg(PyObject *instructions)
}
if (label >= max_labels || target >= max_labels) {
PyErr_SetString(PyExc_ValueError, "label is out of range");
return NULL;
goto error;
}
basicblock *new_block = NULL;
if (label > 0 && label2block[label] != NULL) {
Expand All @@ -9652,44 +9653,37 @@ instructions_to_cfg(PyObject *instructions)
*/
assert(new_block->b_iused == 0);
}
else if (start_new_block || label > 0) {
new_block = new_basicblock();
else if (label > 0) {
new_block = cfg_builder_new_block(g);
if (new_block == NULL) {
goto error;
}
if (label > 0) {
assert(label < max_labels);
label2block[label] = new_block;
}
assert(label < max_labels);
label2block[label] = new_block;
}
if (new_block) {
current_block->b_next = new_block;
current_block = new_block;
start_new_block = false;
cfg_builder_use_next_block(g, new_block);
}
basicblock *target_block = NULL;
if (target > 0) {
target_block = label2block[target];
if (target_block == NULL) {
target_block = new_basicblock();
target_block = cfg_builder_new_block(g);
if (target_block == NULL) {
goto error;
}
label2block[target] = target_block;
}
}
if (!basicblock_addop(current_block, opcode, oparg, target_block, &loc)) {
if (!cfg_builder_addop(g, opcode, oparg, target_block, loc)) {
goto error;
}
if (IS_TERMINATOR_OPCODE(opcode)) {
start_new_block = true;
}
}
PyMem_Free(label2block);
return entryblock;
return 0;
error:
PyMem_Free(label2block);
return NULL;
return -1;
}

static PyObject *
Expand Down Expand Up @@ -9742,16 +9736,20 @@ _PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts)
if (const_cache == NULL) {
return NULL;
}
basicblock *entryblock = instructions_to_cfg(instructions);
if (optimize_cfg(entryblock, consts, const_cache)) {
cfg_builder g;
instructions_to_cfg(instructions, &g);

if (optimize_cfg(g.cfg_entryblock, consts, const_cache)) {
goto error;
}
PyObject *optimized_instructions = cfg_to_instructions(entryblock);
PyObject *optimized_instructions = cfg_to_instructions(g.cfg_entryblock);
if (optimized_instructions == NULL) {
goto error;
}
cfg_builder_free(&g);
return PyTuple_Pack(2, optimized_instructions, consts);
error:
cfg_builder_free(&g);
return NULL;
}

Expand Down

0 comments on commit d88ba72

Please sign in to comment.