mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
GH-125837: Split LOAD_CONST
into three. (GH-125972)
* Add LOAD_CONST_IMMORTAL opcode * Add LOAD_SMALL_INT opcode * Remove RETURN_CONST opcode
This commit is contained in:
parent
67f5c5bd6f
commit
faa3272fb8
33 changed files with 706 additions and 538 deletions
|
@ -283,7 +283,7 @@ dump_instr(cfg_instr *i)
|
|||
static inline int
|
||||
basicblock_returns(const basicblock *b) {
|
||||
cfg_instr *last = basicblock_last_instr(b);
|
||||
return last && (last->i_opcode == RETURN_VALUE || last->i_opcode == RETURN_CONST);
|
||||
return last && last->i_opcode == RETURN_VALUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -515,22 +515,6 @@ no_redundant_jumps(cfg_builder *g) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
all_exits_have_lineno(basicblock *entryblock) {
|
||||
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
|
||||
for (int i = 0; i < b->b_iused; i++) {
|
||||
cfg_instr *instr = &b->b_instr[i];
|
||||
if (instr->i_opcode == RETURN_VALUE) {
|
||||
if (instr->i_loc.lineno < 0) {
|
||||
assert(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***** CFG preprocessing (jump targets and exceptions) *****/
|
||||
|
@ -1131,7 +1115,7 @@ remove_redundant_nops_and_pairs(basicblock *entryblock)
|
|||
int opcode = instr->i_opcode;
|
||||
bool is_redundant_pair = false;
|
||||
if (opcode == POP_TOP) {
|
||||
if (prev_opcode == LOAD_CONST) {
|
||||
if (prev_opcode == LOAD_CONST || prev_opcode == LOAD_SMALL_INT) {
|
||||
is_redundant_pair = true;
|
||||
}
|
||||
else if (prev_opcode == COPY && prev_oparg == 1) {
|
||||
|
@ -1280,14 +1264,23 @@ jump_thread(basicblock *bb, cfg_instr *inst, cfg_instr *target, int opcode)
|
|||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
loads_const(int opcode)
|
||||
{
|
||||
return OPCODE_HAS_CONST(opcode) || opcode == LOAD_SMALL_INT;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
get_const_value(int opcode, int oparg, PyObject *co_consts)
|
||||
{
|
||||
PyObject *constant = NULL;
|
||||
assert(OPCODE_HAS_CONST(opcode));
|
||||
assert(loads_const(opcode));
|
||||
if (opcode == LOAD_CONST) {
|
||||
constant = PyList_GET_ITEM(co_consts, oparg);
|
||||
}
|
||||
if (opcode == LOAD_SMALL_INT) {
|
||||
return PyLong_FromLong(oparg);
|
||||
}
|
||||
|
||||
if (constant == NULL) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
|
@ -1345,7 +1338,7 @@ fold_tuple_on_constants(PyObject *const_cache,
|
|||
assert(inst[n].i_oparg == n);
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (!OPCODE_HAS_CONST(inst[i].i_opcode)) {
|
||||
if (!loads_const(inst[i].i_opcode)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -1583,7 +1576,7 @@ basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb, PyObject *
|
|||
oparg = inst->i_oparg;
|
||||
}
|
||||
assert(!IS_ASSEMBLER_OPCODE(opcode));
|
||||
if (opcode != LOAD_CONST) {
|
||||
if (opcode != LOAD_CONST && opcode != LOAD_SMALL_INT) {
|
||||
continue;
|
||||
}
|
||||
int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0;
|
||||
|
@ -1662,12 +1655,6 @@ basicblock_optimize_load_const(PyObject *const_cache, basicblock *bb, PyObject *
|
|||
: POP_JUMP_IF_NONE;
|
||||
break;
|
||||
}
|
||||
case RETURN_VALUE:
|
||||
{
|
||||
INSTR_SET_OP0(inst, NOP);
|
||||
INSTR_SET_OP1(&bb->b_instr[++i], RETURN_CONST, oparg);
|
||||
break;
|
||||
}
|
||||
case TO_BOOL:
|
||||
{
|
||||
PyObject *cnt = get_const_value(opcode, oparg, consts);
|
||||
|
@ -2120,7 +2107,8 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts)
|
|||
/* mark used consts */
|
||||
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
|
||||
for (int i = 0; i < b->b_iused; i++) {
|
||||
if (OPCODE_HAS_CONST(b->b_instr[i].i_opcode)) {
|
||||
int opcode = b->b_instr[i].i_opcode;
|
||||
if (OPCODE_HAS_CONST(opcode)) {
|
||||
int index = b->b_instr[i].i_oparg;
|
||||
index_map[index] = index;
|
||||
}
|
||||
|
@ -2173,7 +2161,8 @@ remove_unused_consts(basicblock *entryblock, PyObject *consts)
|
|||
|
||||
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
|
||||
for (int i = 0; i < b->b_iused; i++) {
|
||||
if (OPCODE_HAS_CONST(b->b_instr[i].i_opcode)) {
|
||||
int opcode = b->b_instr[i].i_opcode;
|
||||
if (OPCODE_HAS_CONST(opcode)) {
|
||||
int index = b->b_instr[i].i_oparg;
|
||||
assert(reverse_index_map[index] >= 0);
|
||||
assert(reverse_index_map[index] < n_used_consts);
|
||||
|
@ -2594,8 +2583,9 @@ _PyCfg_OptimizeCodeUnit(cfg_builder *g, PyObject *consts, PyObject *const_cache,
|
|||
RETURN_IF_ERROR(insert_superinstructions(g));
|
||||
|
||||
RETURN_IF_ERROR(push_cold_blocks_to_end(g));
|
||||
assert(all_exits_have_lineno(g->g_entryblock));
|
||||
RETURN_IF_ERROR(resolve_line_numbers(g, firstlineno));
|
||||
// temporarily remove assert. See https://github.com/python/cpython/issues/125845
|
||||
// assert(all_exits_have_lineno(g->g_entryblock));
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue