]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-115480: Type and constant propagation for int BINARY_OPs (GH-115478)
authorKen Jin <kenjin@python.org>
Thu, 15 Feb 2024 06:02:18 +0000 (14:02 +0800)
committerGitHub <noreply@github.com>
Thu, 15 Feb 2024 06:02:18 +0000 (14:02 +0800)
Python/optimizer_analysis.c
Python/tier2_redundancy_eliminator_bytecodes.c
Python/tier2_redundancy_eliminator_cases.c.h

index 49974520de924da4266d685525d6a3fa5d02ea00..d73bc310345f415e7f3bc79f7c5457b170bc1072 100644 (file)
@@ -341,6 +341,18 @@ sym_new_const(_Py_UOpsAbstractInterpContext *ctx, PyObject *const_val)
     return temp;
 }
 
+static inline bool
+is_const(_Py_UOpsSymType *sym)
+{
+    return sym->const_val != NULL;
+}
+
+static inline PyObject *
+get_const(_Py_UOpsSymType *sym)
+{
+    return sym->const_val;
+}
+
 static _Py_UOpsSymType*
 sym_new_null(_Py_UOpsAbstractInterpContext *ctx)
 {
index 3272b187f20d0eb3b31a3b75e7496f0c2f90b700..39ea0eef6276326753940ed431c4e7de973ef4ec 100644 (file)
@@ -81,12 +81,62 @@ dummy_func(void) {
 
 
     op(_BINARY_OP_ADD_INT, (left, right -- res)) {
-        // TODO constant propagation
-        (void)left;
-        (void)right;
-        res = sym_new_known_type(ctx, &PyLong_Type);
-        if (res == NULL) {
-            goto out_of_space;
+        if (is_const(left) && is_const(right)) {
+            assert(PyLong_CheckExact(get_const(left)));
+            assert(PyLong_CheckExact(get_const(right)));
+            PyObject *temp = _PyLong_Add((PyLongObject *)get_const(left),
+                                         (PyLongObject *)get_const(right));
+            if (temp == NULL) {
+                goto error;
+            }
+            res = sym_new_const(ctx, temp);
+            // TODO replace opcode with constant propagated one and add tests!
+        }
+        else {
+            res = sym_new_known_type(ctx, &PyLong_Type);
+            if (res == NULL) {
+                goto out_of_space;
+            }
+        }
+    }
+
+    op(_BINARY_OP_SUBTRACT_INT, (left, right -- res)) {
+        if (is_const(left) && is_const(right)) {
+            assert(PyLong_CheckExact(get_const(left)));
+            assert(PyLong_CheckExact(get_const(right)));
+            PyObject *temp = _PyLong_Subtract((PyLongObject *)get_const(left),
+                                              (PyLongObject *)get_const(right));
+            if (temp == NULL) {
+                goto error;
+            }
+            res = sym_new_const(ctx, temp);
+            // TODO replace opcode with constant propagated one and add tests!
+        }
+        else {
+            res = sym_new_known_type(ctx, &PyLong_Type);
+            if (res == NULL) {
+                goto out_of_space;
+            }
+        }
+    }
+
+    op(_BINARY_OP_MULTIPLY_INT, (left, right -- res)) {
+        if (is_const(left) && is_const(right)) {
+            assert(PyLong_CheckExact(get_const(left)));
+            assert(PyLong_CheckExact(get_const(right)));
+            PyObject *temp = _PyLong_Multiply((PyLongObject *)get_const(left),
+                                              (PyLongObject *)get_const(right));
+            if (temp == NULL) {
+                goto error;
+            }
+            res = sym_new_const(ctx, temp);
+            // TODO replace opcode with constant propagated one and add tests!
+        }
+        else {
+            res = sym_new_known_type(ctx, &PyLong_Type);
+            if (res == NULL) {
+                goto out_of_space;
+            }
         }
     }
 
index c2b7bbaf1c4481080af0a11f614a7784152e8444..a9617f51ef46158409945386da6746418f3ae57d 100644 (file)
         }
 
         case _BINARY_OP_MULTIPLY_INT: {
+            _Py_UOpsSymType *right;
+            _Py_UOpsSymType *left;
             _Py_UOpsSymType *res;
-            res = sym_new_unknown(ctx);
-            if (res == NULL) goto out_of_space;
+            right = stack_pointer[-1];
+            left = stack_pointer[-2];
+            if (is_const(left) && is_const(right)) {
+                assert(PyLong_CheckExact(get_const(left)));
+                assert(PyLong_CheckExact(get_const(right)));
+                PyObject *temp = _PyLong_Multiply((PyLongObject *)get_const(left),
+                    (PyLongObject *)get_const(right));
+                if (temp == NULL) {
+                    goto error;
+                }
+                res = sym_new_const(ctx, temp);
+                // TODO replace opcode with constant propagated one and add tests!
+            }
+            else {
+                res = sym_new_known_type(ctx, &PyLong_Type);
+                if (res == NULL) {
+                    goto out_of_space;
+                }
+            }
             stack_pointer[-2] = res;
             stack_pointer += -1;
             break;
             _Py_UOpsSymType *res;
             right = stack_pointer[-1];
             left = stack_pointer[-2];
-            // TODO constant propagation
-            (void)left;
-            (void)right;
-            res = sym_new_known_type(ctx, &PyLong_Type);
-            if (res == NULL) {
-                goto out_of_space;
+            if (is_const(left) && is_const(right)) {
+                assert(PyLong_CheckExact(get_const(left)));
+                assert(PyLong_CheckExact(get_const(right)));
+                PyObject *temp = _PyLong_Add((PyLongObject *)get_const(left),
+                    (PyLongObject *)get_const(right));
+                if (temp == NULL) {
+                    goto error;
+                }
+                res = sym_new_const(ctx, temp);
+                // TODO replace opcode with constant propagated one and add tests!
+            }
+            else {
+                res = sym_new_known_type(ctx, &PyLong_Type);
+                if (res == NULL) {
+                    goto out_of_space;
+                }
             }
             stack_pointer[-2] = res;
             stack_pointer += -1;
         }
 
         case _BINARY_OP_SUBTRACT_INT: {
+            _Py_UOpsSymType *right;
+            _Py_UOpsSymType *left;
             _Py_UOpsSymType *res;
-            res = sym_new_unknown(ctx);
-            if (res == NULL) goto out_of_space;
+            right = stack_pointer[-1];
+            left = stack_pointer[-2];
+            if (is_const(left) && is_const(right)) {
+                assert(PyLong_CheckExact(get_const(left)));
+                assert(PyLong_CheckExact(get_const(right)));
+                PyObject *temp = _PyLong_Subtract((PyLongObject *)get_const(left),
+                    (PyLongObject *)get_const(right));
+                if (temp == NULL) {
+                    goto error;
+                }
+                res = sym_new_const(ctx, temp);
+                // TODO replace opcode with constant propagated one and add tests!
+            }
+            else {
+                res = sym_new_known_type(ctx, &PyLong_Type);
+                if (res == NULL) {
+                    goto out_of_space;
+                }
+            }
             stack_pointer[-2] = res;
             stack_pointer += -1;
             break;