aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python/flowgraph.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/flowgraph.c')
-rw-r--r--Python/flowgraph.c50
1 files changed, 20 insertions, 30 deletions
diff --git a/Python/flowgraph.c b/Python/flowgraph.c
index 388862912d6..54181319500 100644
--- a/Python/flowgraph.c
+++ b/Python/flowgraph.c
@@ -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;
}