diff options
Diffstat (limited to 'Python/flowgraph.c')
-rw-r--r-- | Python/flowgraph.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/Python/flowgraph.c b/Python/flowgraph.c index f8039a4..2fd9a85 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -1586,6 +1586,56 @@ optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache) return SUCCESS; } +static void +make_super_instruction(cfg_instr *inst1, cfg_instr *inst2, int super_op) +{ + int32_t line1 = inst1->i_loc.lineno; + int32_t line2 = inst2->i_loc.lineno; + /* Skip if instructions are on different lines */ + if (line1 >= 0 && line2 >= 0 && line1 != line2) { + return; + } + if (inst1->i_oparg >= 16 || inst2->i_oparg >= 16) { + return; + } + INSTR_SET_OP1(inst1, super_op, (inst1->i_oparg << 4) | inst2->i_oparg); + INSTR_SET_OP0(inst2, NOP); +} + +static void +insert_superinstructions(cfg_builder *g) +{ + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *inst = &b->b_instr[i]; + int nextop = i+1 < b->b_iused ? b->b_instr[i+1].i_opcode : 0; + switch(inst->i_opcode) { + case LOAD_FAST: + if (nextop == LOAD_FAST) { + make_super_instruction(inst, &b->b_instr[i + 1], LOAD_FAST_LOAD_FAST); + } + break; + case STORE_FAST: + switch (nextop) { + case LOAD_FAST: + make_super_instruction(inst, &b->b_instr[i + 1], STORE_FAST_LOAD_FAST); + break; + case STORE_FAST: + make_super_instruction(inst, &b->b_instr[i + 1], STORE_FAST_STORE_FAST); + break; + } + break; + } + } + } + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + remove_redundant_nops(b); + } + eliminate_empty_basic_blocks(g); + assert(no_redundant_nops(g)); +} + // helper functions for add_checks_for_loads_of_unknown_variables static inline void maybe_push(basicblock *b, uint64_t unsafe_mask, basicblock ***sp) @@ -2181,6 +2231,7 @@ _PyCfg_OptimizeCodeUnit(cfg_builder *g, PyObject *consts, PyObject *const_cache, RETURN_IF_ERROR( add_checks_for_loads_of_uninitialized_variables( g->g_entryblock, nlocals, nparams)); + insert_superinstructions(g); RETURN_IF_ERROR(push_cold_blocks_to_end(g, code_flags)); RETURN_IF_ERROR(resolve_line_numbers(g, firstlineno)); |