mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
gh-132732: Automatically constant evaluate pure operations (GH-132733)
This adds a "macro" to the optimizer DSL called "REPLACE_OPCODE_IF_EVALUATES_PURE", which allows automatically constant evaluating a bytecode body if certain inputs have no side effects upon evaluations (such as ints, strings, and floats). Co-authored-by: Tomas R. <tomas.roun8@gmail.com>
This commit is contained in:
parent
c45f4f3ebe
commit
695ab61351
10 changed files with 706 additions and 122 deletions
|
|
@ -181,6 +181,7 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_BINARY_OP, (lhs, rhs -- res)) {
|
||||
REPLACE_OPCODE_IF_EVALUATES_PURE(lhs, rhs);
|
||||
bool lhs_int = sym_matches_type(lhs, &PyLong_Type);
|
||||
bool rhs_int = sym_matches_type(rhs, &PyLong_Type);
|
||||
bool lhs_float = sym_matches_type(lhs, &PyFloat_Type);
|
||||
|
|
@ -235,35 +236,23 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_BINARY_OP_ADD_INT, (left, right -- res)) {
|
||||
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
|
||||
res = sym_new_compact_int(ctx);
|
||||
}
|
||||
|
||||
op(_BINARY_OP_SUBTRACT_INT, (left, right -- res)) {
|
||||
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
|
||||
res = sym_new_compact_int(ctx);
|
||||
}
|
||||
|
||||
op(_BINARY_OP_MULTIPLY_INT, (left, right -- res)) {
|
||||
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
|
||||
res = sym_new_compact_int(ctx);
|
||||
}
|
||||
|
||||
op(_BINARY_OP_ADD_FLOAT, (left, right -- res)) {
|
||||
if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) {
|
||||
assert(PyFloat_CheckExact(sym_get_const(ctx, left)));
|
||||
assert(PyFloat_CheckExact(sym_get_const(ctx, right)));
|
||||
PyObject *temp = PyFloat_FromDouble(
|
||||
PyFloat_AS_DOUBLE(sym_get_const(ctx, left)) +
|
||||
PyFloat_AS_DOUBLE(sym_get_const(ctx, right)));
|
||||
if (temp == NULL) {
|
||||
goto error;
|
||||
}
|
||||
res = sym_new_const(ctx, temp);
|
||||
Py_DECREF(temp);
|
||||
// TODO gh-115506:
|
||||
// replace opcode with constant propagated one and update tests!
|
||||
}
|
||||
else {
|
||||
res = sym_new_type(ctx, &PyFloat_Type);
|
||||
}
|
||||
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
|
||||
res = sym_new_type(ctx, &PyFloat_Type);
|
||||
// TODO (gh-134584): Refactor this to use another uop
|
||||
if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) {
|
||||
REPLACE_OP(this_instr, op_without_decref_inputs[opcode], oparg, 0);
|
||||
|
|
@ -271,23 +260,8 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res)) {
|
||||
if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) {
|
||||
assert(PyFloat_CheckExact(sym_get_const(ctx, left)));
|
||||
assert(PyFloat_CheckExact(sym_get_const(ctx, right)));
|
||||
PyObject *temp = PyFloat_FromDouble(
|
||||
PyFloat_AS_DOUBLE(sym_get_const(ctx, left)) -
|
||||
PyFloat_AS_DOUBLE(sym_get_const(ctx, right)));
|
||||
if (temp == NULL) {
|
||||
goto error;
|
||||
}
|
||||
res = sym_new_const(ctx, temp);
|
||||
Py_DECREF(temp);
|
||||
// TODO gh-115506:
|
||||
// replace opcode with constant propagated one and update tests!
|
||||
}
|
||||
else {
|
||||
res = sym_new_type(ctx, &PyFloat_Type);
|
||||
}
|
||||
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
|
||||
res = sym_new_type(ctx, &PyFloat_Type);
|
||||
// TODO (gh-134584): Refactor this to use another uop
|
||||
if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) {
|
||||
REPLACE_OP(this_instr, op_without_decref_inputs[opcode], oparg, 0);
|
||||
|
|
@ -295,23 +269,8 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_BINARY_OP_MULTIPLY_FLOAT, (left, right -- res)) {
|
||||
if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) {
|
||||
assert(PyFloat_CheckExact(sym_get_const(ctx, left)));
|
||||
assert(PyFloat_CheckExact(sym_get_const(ctx, right)));
|
||||
PyObject *temp = PyFloat_FromDouble(
|
||||
PyFloat_AS_DOUBLE(sym_get_const(ctx, left)) *
|
||||
PyFloat_AS_DOUBLE(sym_get_const(ctx, right)));
|
||||
if (temp == NULL) {
|
||||
goto error;
|
||||
}
|
||||
res = sym_new_const(ctx, temp);
|
||||
Py_DECREF(temp);
|
||||
// TODO gh-115506:
|
||||
// replace opcode with constant propagated one and update tests!
|
||||
}
|
||||
else {
|
||||
res = sym_new_type(ctx, &PyFloat_Type);
|
||||
}
|
||||
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
|
||||
res = sym_new_type(ctx, &PyFloat_Type);
|
||||
// TODO (gh-134584): Refactor this to use another uop
|
||||
if (PyJitRef_IsBorrowed(left) && PyJitRef_IsBorrowed(right)) {
|
||||
REPLACE_OP(this_instr, op_without_decref_inputs[opcode], oparg, 0);
|
||||
|
|
@ -319,19 +278,8 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_BINARY_OP_ADD_UNICODE, (left, right -- res)) {
|
||||
if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) {
|
||||
assert(PyUnicode_CheckExact(sym_get_const(ctx, left)));
|
||||
assert(PyUnicode_CheckExact(sym_get_const(ctx, right)));
|
||||
PyObject *temp = PyUnicode_Concat(sym_get_const(ctx, left), sym_get_const(ctx, right));
|
||||
if (temp == NULL) {
|
||||
goto error;
|
||||
}
|
||||
res = sym_new_const(ctx, temp);
|
||||
Py_DECREF(temp);
|
||||
}
|
||||
else {
|
||||
res = sym_new_type(ctx, &PyUnicode_Type);
|
||||
}
|
||||
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
|
||||
res = sym_new_type(ctx, &PyUnicode_Type);
|
||||
}
|
||||
|
||||
op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right -- )) {
|
||||
|
|
@ -443,6 +391,7 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_UNARY_NOT, (value -- res)) {
|
||||
REPLACE_OPCODE_IF_EVALUATES_PURE(value);
|
||||
sym_set_type(value, &PyBool_Type);
|
||||
res = sym_new_truthiness(ctx, value, false);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue