Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Cleanup
  • Loading branch information
brandtbucher committed Jun 23, 2023
commit d31407825cac7b01443449db0636e6b1af6dbb5d
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ Parser/token.c generated
Programs/test_frozenmain.h generated
Python/Python-ast.c generated
Python/generated_cases.c.h generated
Python/opcode_metadata.h generated
Python/opcode_targets.h generated
Python/stdlib_module_names.h generated
Tools/peg_generator/pegen/grammar_parser.py generated
Expand Down
41 changes: 10 additions & 31 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,12 +285,7 @@ dummy_func(

inst(UNARY_NOT, (value -- res)) {
assert(PyBool_Check(value));
if (Py_IsFalse(value)) {
res = Py_True;
}
else {
res = Py_False;
}
res = Py_IsFalse(value) ? Py_True : Py_False;
}

family(to_bool, INLINE_CACHE_ENTRIES_TO_BOOL) = {
Expand All @@ -317,12 +312,7 @@ dummy_func(
int err = PyObject_IsTrue(value);
DECREF_INPUTS();
ERROR_IF(err < 0, error);
if (err == 0) {
res = Py_False;
}
else {
res = Py_True;
}
res = err ? Py_True : Py_False;
}

inst(TO_BOOL_BOOL, (unused/1, unused/2, value -- value)) {
Expand All @@ -347,12 +337,7 @@ dummy_func(
inst(TO_BOOL_LIST, (unused/1, unused/2, value -- res)) {
DEOPT_IF(!PyList_CheckExact(value), TO_BOOL);
STAT_INC(TO_BOOL, hit);
if (!Py_SIZE(value)) {
res = Py_False;
}
else {
res = Py_True;
}
res = Py_SIZE(value) ? Py_True : Py_False;
DECREF_INPUTS();
}

Expand Down Expand Up @@ -3600,23 +3585,17 @@ dummy_func(

inst(INSTRUMENTED_POP_JUMP_IF_TRUE, ( -- )) {
PyObject *cond = POP();
int err = PyObject_IsTrue(cond); // XXX
Py_DECREF(cond);
ERROR_IF(err < 0, error);
_Py_CODEUNIT *here = next_instr-1;
assert(err == 0 || err == 1);
int offset = err*oparg;
assert(PyBool_Check(cond));
_Py_CODEUNIT *here = next_instr - 1;
int offset = Py_IsTrue(cond) * oparg;
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
}

inst(INSTRUMENTED_POP_JUMP_IF_FALSE, ( -- )) {
PyObject *cond = POP();
int err = PyObject_IsTrue(cond); // XXX
Py_DECREF(cond);
ERROR_IF(err < 0, error);
_Py_CODEUNIT *here = next_instr-1;
assert(err == 0 || err == 1);
int offset = (1-err)*oparg;
assert(PyBool_Check(cond));
_Py_CODEUNIT *here = next_instr - 1;
int offset = Py_IsFalse(cond) * oparg;
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
}

Expand All @@ -3643,7 +3622,7 @@ dummy_func(
}
else {
Py_DECREF(value);
offset = oparg;
offset = oparg;
}
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
}
Expand Down
137 changes: 81 additions & 56 deletions Python/flowgraph.c
Original file line number Diff line number Diff line change
Expand Up @@ -1447,6 +1447,54 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
}
break;
case IS_OP:
// Fold to POP_JUMP_IF_NONE:
// - LOAD_CONST(None) IS_OP(0) POP_JUMP_IF_TRUE
// - LOAD_CONST(None) IS_OP(1) POP_JUMP_IF_FALSE
// - LOAD_CONST(None) IS_OP(0) TO_BOOL POP_JUMP_IF_TRUE
// - LOAD_CONST(None) IS_OP(1) TO_BOOL POP_JUMP_IF_FALSE
// Fold to POP_JUMP_IF_NOT_NONE:
// - LOAD_CONST(None) IS_OP(0) POP_JUMP_IF_FALSE
// - LOAD_CONST(None) IS_OP(1) POP_JUMP_IF_TRUE
// - LOAD_CONST(None) IS_OP(0) TO_BOOL POP_JUMP_IF_FALSE
// - LOAD_CONST(None) IS_OP(1) TO_BOOL POP_JUMP_IF_TRUE
cnt = get_const_value(opcode, oparg, consts);
if (cnt == NULL) {
goto error;
}
if (!Py_IsNone(cnt)) {
break;
}
Py_DECREF(cnt);
if (bb->b_iused <= i + 2) {
break;
}
cfg_instr *is_instr = &bb->b_instr[i + 1];
cfg_instr *jump_instr = &bb->b_instr[i + 2];
// Get rid of TO_BOOL regardless:
if (jump_instr->i_opcode == TO_BOOL) {
INSTR_SET_OP0(jump_instr, NOP);
if (bb->b_iused <= i + 3) {
break;
}
jump_instr = &bb->b_instr[i + 3];
}
bool invert = is_instr->i_oparg;
if (jump_instr->i_opcode == POP_JUMP_IF_FALSE) {
invert = !invert;
}
else if (jump_instr->i_opcode != POP_JUMP_IF_TRUE) {
break;
}
INSTR_SET_OP0(inst, NOP);
INSTR_SET_OP0(is_instr, NOP);
jump_instr->i_opcode = invert ? POP_JUMP_IF_NOT_NONE
: 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:
cnt = get_const_value(opcode, oparg, consts);
if (cnt == NULL) {
Expand All @@ -1465,65 +1513,9 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
INSTR_SET_OP0(inst, NOP);
INSTR_SET_OP1(&bb->b_instr[i + 1], LOAD_CONST, index);
break;
case IS_OP:
cnt = get_const_value(opcode, oparg, consts);
if (cnt == NULL) {
goto error;
}
int to_bool = i + 2 < bb->b_iused && bb->b_instr[i + 2].i_opcode == TO_BOOL;
int jump_op = i + to_bool + 2 < bb->b_iused ? bb->b_instr[i + to_bool + 2].i_opcode : 0;
if (Py_IsNone(cnt) && (jump_op == POP_JUMP_IF_FALSE || jump_op == POP_JUMP_IF_TRUE)) {
unsigned char nextarg = bb->b_instr[i+1].i_oparg;
INSTR_SET_OP0(inst, NOP);
INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
if (to_bool) {
INSTR_SET_OP0(&bb->b_instr[i + 2], NOP);
}
bb->b_instr[i + to_bool + 2].i_opcode = nextarg ^ (jump_op == POP_JUMP_IF_FALSE) ?
POP_JUMP_IF_NOT_NONE : POP_JUMP_IF_NONE;
}
Py_DECREF(cnt);
break;
case RETURN_VALUE:
INSTR_SET_OP0(inst, NOP);
INSTR_SET_OP1(&bb->b_instr[++i], RETURN_CONST, oparg);
break;
}
break;
}
case COMPARE_OP:
if (nextop == TO_BOOL) {
INSTR_SET_OP0(inst, NOP);
INSTR_SET_OP1(&bb->b_instr[i + 1], COMPARE_OP, oparg | 16);
continue;
}
break;
case TO_BOOL:
if (nextop == TO_BOOL) {
INSTR_SET_OP0(inst, NOP);
continue;
}
break;
case UNARY_NOT:
if (nextop == TO_BOOL) {
INSTR_SET_OP0(inst, NOP);
INSTR_SET_OP0(&bb->b_instr[i + 1], UNARY_NOT);
continue;
}
if (nextop == UNARY_NOT) {
INSTR_SET_OP0(inst, NOP);
INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
continue;
}
break;
case IS_OP:
case CONTAINS_OP:
if (nextop == TO_BOOL) {
INSTR_SET_OP0(inst, NOP);
INSTR_SET_OP1(&bb->b_instr[i + 1], opcode, oparg);
continue;
}
break;
/* Try to fold tuples of constants.
Skip over BUILD_TUPLE(1) UNPACK_SEQUENCE(1).
Replace BUILD_TUPLE(2) UNPACK_SEQUENCE(2) with SWAP(2).
Expand Down Expand Up @@ -1606,6 +1598,39 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
inst[1].i_oparg |= 1;
}
break;
case COMPARE_OP:
if (nextop == TO_BOOL) {
INSTR_SET_OP0(inst, NOP);
INSTR_SET_OP1(&bb->b_instr[i + 1], COMPARE_OP, oparg | 16);
continue;
}
break;
case CONTAINS_OP:
case IS_OP:
if (nextop == TO_BOOL) {
INSTR_SET_OP0(inst, NOP);
INSTR_SET_OP1(&bb->b_instr[i + 1], opcode, oparg);
continue;
}
break;
case TO_BOOL:
if (nextop == TO_BOOL) {
INSTR_SET_OP0(inst, NOP);
continue;
}
break;
case UNARY_NOT:
if (nextop == TO_BOOL) {
INSTR_SET_OP0(inst, NOP);
INSTR_SET_OP0(&bb->b_instr[i + 1], UNARY_NOT);
continue;
}
if (nextop == UNARY_NOT) {
Comment thread
brandtbucher marked this conversation as resolved.
INSTR_SET_OP0(inst, NOP);
INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
continue;
}
break;
default:
/* All OPCODE_HAS_CONST opcodes should be handled with LOAD_CONST */
assert (!OPCODE_HAS_CONST(inst->i_opcode));
Expand Down
Loading