]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-131498: Remove conditional stack effects (GH-131499)
authorMark Shannon <mark@hotpy.org>
Thu, 20 Mar 2025 15:39:38 +0000 (15:39 +0000)
committerGitHub <noreply@github.com>
Thu, 20 Mar 2025 15:39:38 +0000 (15:39 +0000)
* Adds some missing #includes

23 files changed:
Include/internal/pycore_jit.h
Lib/test/test_generated_cases.py
Modules/_testinternalcapi.c
Objects/codeobject.c
Python/bytecodes.c
Python/executor_cases.c.h
Python/generated_cases.c.h
Python/jit.c
Python/optimizer.c
Python/optimizer_analysis.c
Python/optimizer_bytecodes.c
Python/optimizer_cases.c.h
Python/optimizer_symbols.c
Python/pylifecycle.c
Tools/cases_generator/analyzer.py
Tools/cases_generator/generators_common.py
Tools/cases_generator/lexer.py
Tools/cases_generator/optimizer_generator.py
Tools/cases_generator/parsing.py
Tools/cases_generator/stack.py
Tools/cases_generator/tier1_generator.py
Tools/cases_generator/tier2_generator.py
Tools/jit/template.c

index 4d6cc35a7a3de7446fbf1bee7f1ce2cefa7bb596..8a88cbf607ba4bcc8a8beff9ea98238ded4b6d66 100644 (file)
@@ -5,6 +5,10 @@
 extern "C" {
 #endif
 
+#include "pycore_interp.h"
+#include "pycore_optimizer.h"
+#include "pycore_stackref.h"
+
 #ifndef Py_BUILD_CORE
 #  error "this header requires Py_BUILD_CORE define"
 #endif
index 39ad07ff79be31fbdd08a342d6b4a40c8a557b86..3eb650bf3e694249a891629483e7a65de9da85e4 100644 (file)
@@ -59,14 +59,14 @@ class TestEffects(unittest.TestCase):
     def test_effect_sizes(self):
         stack = Stack()
         inputs = [
-            x := StackItem("x", None, "", "1"),
-            y := StackItem("y", None, "", "oparg"),
-            z := StackItem("z", None, "", "oparg*2"),
+            x := StackItem("x", None, "1"),
+            y := StackItem("y", None, "oparg"),
+            z := StackItem("z", None, "oparg*2"),
         ]
         outputs = [
-            StackItem("x", None, "", "1"),
-            StackItem("b", None, "", "oparg*4"),
-            StackItem("c", None, "", "1"),
+            StackItem("x", None, "1"),
+            StackItem("b", None, "oparg*4"),
+            StackItem("c", None, "1"),
         ]
         stack.pop(z)
         stack.pop(y)
@@ -903,98 +903,6 @@ class TestGeneratedCases(unittest.TestCase):
     """
         self.run_cases_test(input, output)
 
-    def test_cond_effect(self):
-        input = """
-        inst(OP, (aa, input if ((oparg & 1) == 1), cc -- xx, output if (oparg & 2), zz)) {
-            output = SPAM(oparg, aa, cc, input);
-            INPUTS_DEAD();
-            xx = 0;
-            zz = 0;
-        }
-    """
-        output = """
-        TARGET(OP) {
-            #if Py_TAIL_CALL_INTERP
-            int opcode = OP;
-            (void)(opcode);
-            #endif
-            frame->instr_ptr = next_instr;
-            next_instr += 1;
-            INSTRUCTION_STATS(OP);
-            _PyStackRef aa;
-            _PyStackRef input = PyStackRef_NULL;
-            _PyStackRef cc;
-            _PyStackRef xx;
-            _PyStackRef output = PyStackRef_NULL;
-            _PyStackRef zz;
-            cc = stack_pointer[-1];
-            if ((oparg & 1) == 1) { input = stack_pointer[-1 - (((oparg & 1) == 1) ? 1 : 0)]; }
-            aa = stack_pointer[-2 - (((oparg & 1) == 1) ? 1 : 0)];
-            output = SPAM(oparg, aa, cc, input);
-            xx = 0;
-            zz = 0;
-            stack_pointer[-2 - (((oparg & 1) == 1) ? 1 : 0)] = xx;
-            if (oparg & 2) stack_pointer[-1 - (((oparg & 1) == 1) ? 1 : 0)] = output;
-            stack_pointer[-1 - (((oparg & 1) == 1) ? 1 : 0) + ((oparg & 2) ? 1 : 0)] = zz;
-            stack_pointer += -(((oparg & 1) == 1) ? 1 : 0) + ((oparg & 2) ? 1 : 0);
-            assert(WITHIN_STACK_BOUNDS());
-            DISPATCH();
-        }
-    """
-        self.run_cases_test(input, output)
-
-    def test_macro_cond_effect(self):
-        input = """
-        op(A, (left, middle, right --)) {
-            USE(left, middle, right);
-            INPUTS_DEAD();
-        }
-        op(B, (-- deep, extra if (oparg), res)) {
-            deep = -1;
-            res = 0;
-            extra = 1;
-            INPUTS_DEAD();
-        }
-        macro(M) = A + B;
-    """
-        output = """
-        TARGET(M) {
-            #if Py_TAIL_CALL_INTERP
-            int opcode = M;
-            (void)(opcode);
-            #endif
-            frame->instr_ptr = next_instr;
-            next_instr += 1;
-            INSTRUCTION_STATS(M);
-            _PyStackRef left;
-            _PyStackRef middle;
-            _PyStackRef right;
-            _PyStackRef deep;
-            _PyStackRef extra = PyStackRef_NULL;
-            _PyStackRef res;
-            // A
-            {
-                right = stack_pointer[-1];
-                middle = stack_pointer[-2];
-                left = stack_pointer[-3];
-                USE(left, middle, right);
-            }
-            // B
-            {
-                deep = -1;
-                res = 0;
-                extra = 1;
-            }
-            stack_pointer[-3] = deep;
-            if (oparg) stack_pointer[-2] = extra;
-            stack_pointer[-2 + ((oparg) ? 1 : 0)] = res;
-            stack_pointer += -1 + ((oparg) ? 1 : 0);
-            assert(WITHIN_STACK_BOUNDS());
-            DISPATCH();
-        }
-    """
-        self.run_cases_test(input, output)
-
     def test_macro_push_push(self):
         input = """
         op(A, (-- val1)) {
index 5f39ed11b57e5c82ae8f58c8f4984cc004581ea6..56e3408652a6a07b799f8a99e056249988efea2d 100644 (file)
@@ -28,6 +28,7 @@
 #include "pycore_instruction_sequence.h"  // _PyInstructionSequence_New()
 #include "pycore_interpframe.h"   // _PyFrame_GetFunction()
 #include "pycore_object.h"        // _PyObject_IsFreed()
+#include "pycore_optimizer.h"     // _Py_Executor_DependsOn
 #include "pycore_pathconfig.h"    // _PyPathConfig_ClearGlobal()
 #include "pycore_pyerrors.h"      // _PyErr_ChainExceptions1()
 #include "pycore_pylifecycle.h"   // _PyInterpreterConfig_InitFromDict()
index c55ab6b9b28e9e3974b6ccdf19653722e9d78269..635da094e37a295ed2892ab27bd80c7482b6dd2c 100644 (file)
@@ -9,6 +9,7 @@
 #include "pycore_interpframe.h"   // FRAME_SPECIALS_SIZE
 #include "pycore_opcode_metadata.h" // _PyOpcode_Caches
 #include "pycore_opcode_utils.h"  // RESUME_AT_FUNC_START
+#include "pycore_optimizer.h"     // _Py_ExecutorDetach
 #include "pycore_pymem.h"         // _PyMem_FreeDelayed()
 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
 #include "pycore_setobject.h"     // _PySet_NextEntry()
index 66546080b1f5fec64dd14daf4fd7e11791a859ca..cdd4d5bdd46b436ea28ed79fc9d33c628d916e74 100644 (file)
@@ -59,7 +59,6 @@
 #define guard
 #define override
 #define specializing
-#define split
 #define replicate(TIMES)
 #define tier1
 #define no_save_ip
@@ -1686,8 +1685,10 @@ dummy_func(
             ERROR_IF(PyStackRef_IsNull(*res), error);
         }
 
-        op(_PUSH_NULL_CONDITIONAL, ( -- null if (oparg & 1))) {
-            null = PyStackRef_NULL;
+        op(_PUSH_NULL_CONDITIONAL, ( -- null[oparg & 1])) {
+            if (oparg & 1) {
+                null[0] = PyStackRef_NULL;
+            }
         }
 
         macro(LOAD_GLOBAL) =
index ff9f33b6db018777a2036039841c8ab85adcf5fb..42a3d6d4be9ba4f92b97109dbb77bf6064fa69f6 100644 (file)
         }
 
         case _PUSH_NULL_CONDITIONAL: {
-            _PyStackRef null = PyStackRef_NULL;
+            _PyStackRef *null;
             oparg = CURRENT_OPARG();
-            null = PyStackRef_NULL;
-            if (oparg & 1) stack_pointer[0] = null;
+            null = &stack_pointer[0];
+            if (oparg & 1) {
+                null[0] = PyStackRef_NULL;
+            }
             stack_pointer += (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             break;
index 558b0b48ceaa71f8dbfc223d0943651f0f68e337..9ce2b633d5e506a605e904331c1f3c8035fea991 100644 (file)
             _PyStackRef class_st;
             _PyStackRef self_st;
             _PyStackRef attr;
-            _PyStackRef null = PyStackRef_NULL;
+            _PyStackRef *null;
             /* Skip 1 cache entry */
             // _LOAD_SUPER_ATTR
             {
             }
             // _PUSH_NULL_CONDITIONAL
             {
-                null = PyStackRef_NULL;
+                null = &stack_pointer[1];
+                if (oparg & 1) {
+                    null[0] = PyStackRef_NULL;
+                }
             }
             stack_pointer[0] = attr;
-            if (oparg & 1) stack_pointer[1] = null;
             stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
             static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
             _PyStackRef owner;
             _PyStackRef attr;
-            _PyStackRef null = PyStackRef_NULL;
+            _PyStackRef *null;
             /* Skip 1 cache entry */
             // _CHECK_ATTR_CLASS
             {
             }
             // _PUSH_NULL_CONDITIONAL
             {
-                null = PyStackRef_NULL;
+                null = &stack_pointer[0];
+                if (oparg & 1) {
+                    null[0] = PyStackRef_NULL;
+                }
             }
-            if (oparg & 1) stack_pointer[0] = null;
             stack_pointer += (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
             static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
             _PyStackRef owner;
             _PyStackRef attr;
-            _PyStackRef null = PyStackRef_NULL;
+            _PyStackRef *null;
             /* Skip 1 cache entry */
             // _CHECK_ATTR_CLASS
             {
             }
             // _PUSH_NULL_CONDITIONAL
             {
-                null = PyStackRef_NULL;
+                null = &stack_pointer[0];
+                if (oparg & 1) {
+                    null[0] = PyStackRef_NULL;
+                }
             }
-            if (oparg & 1) stack_pointer[0] = null;
             stack_pointer += (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
             static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
             _PyStackRef owner;
             _PyStackRef attr;
-            _PyStackRef null = PyStackRef_NULL;
+            _PyStackRef *null;
             /* Skip 1 cache entry */
             // _GUARD_TYPE_VERSION
             {
             /* Skip 5 cache entries */
             // _PUSH_NULL_CONDITIONAL
             {
-                null = PyStackRef_NULL;
+                null = &stack_pointer[0];
+                if (oparg & 1) {
+                    null[0] = PyStackRef_NULL;
+                }
             }
-            if (oparg & 1) stack_pointer[0] = null;
             stack_pointer += (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
             static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
             _PyStackRef owner;
             _PyStackRef attr;
-            _PyStackRef null = PyStackRef_NULL;
+            _PyStackRef *null;
             /* Skip 1 cache entry */
             // _LOAD_ATTR_MODULE
             {
             /* Skip 5 cache entries */
             // _PUSH_NULL_CONDITIONAL
             {
-                null = PyStackRef_NULL;
+                null = &stack_pointer[0];
+                if (oparg & 1) {
+                    null[0] = PyStackRef_NULL;
+                }
             }
-            if (oparg & 1) stack_pointer[0] = null;
             stack_pointer += (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
             static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
             _PyStackRef owner;
             _PyStackRef attr;
-            _PyStackRef null = PyStackRef_NULL;
+            _PyStackRef *null;
             /* Skip 1 cache entry */
             // _GUARD_TYPE_VERSION
             {
             /* Skip 5 cache entries */
             // _PUSH_NULL_CONDITIONAL
             {
-                null = PyStackRef_NULL;
+                null = &stack_pointer[0];
+                if (oparg & 1) {
+                    null[0] = PyStackRef_NULL;
+                }
             }
-            if (oparg & 1) stack_pointer[0] = null;
             stack_pointer += (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
             static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
             _PyStackRef owner;
             _PyStackRef attr;
-            _PyStackRef null = PyStackRef_NULL;
+            _PyStackRef *null;
             /* Skip 1 cache entry */
             // _GUARD_TYPE_VERSION
             {
             /* Skip 5 cache entries */
             // _PUSH_NULL_CONDITIONAL
             {
-                null = PyStackRef_NULL;
+                null = &stack_pointer[0];
+                if (oparg & 1) {
+                    null[0] = PyStackRef_NULL;
+                }
             }
-            if (oparg & 1) stack_pointer[0] = null;
             stack_pointer += (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
             _Py_CODEUNIT* const this_instr = next_instr - 5;
             (void)this_instr;
             _PyStackRef *res;
-            _PyStackRef null = PyStackRef_NULL;
+            _PyStackRef *null;
             // _SPECIALIZE_LOAD_GLOBAL
             {
                 uint16_t counter = read_u16(&this_instr[1].cache);
             }
             // _PUSH_NULL_CONDITIONAL
             {
-                null = PyStackRef_NULL;
+                null = &stack_pointer[1];
+                if (oparg & 1) {
+                    null[0] = PyStackRef_NULL;
+                }
             }
-            if (oparg & 1) stack_pointer[1] = null;
             stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
             INSTRUCTION_STATS(LOAD_GLOBAL_BUILTIN);
             static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size");
             _PyStackRef res;
-            _PyStackRef null = PyStackRef_NULL;
+            _PyStackRef *null;
             /* Skip 1 cache entry */
             // _GUARD_GLOBALS_VERSION
             {
             }
             // _PUSH_NULL_CONDITIONAL
             {
-                null = PyStackRef_NULL;
+                null = &stack_pointer[1];
+                if (oparg & 1) {
+                    null[0] = PyStackRef_NULL;
+                }
             }
             stack_pointer[0] = res;
-            if (oparg & 1) stack_pointer[1] = null;
             stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
             INSTRUCTION_STATS(LOAD_GLOBAL_MODULE);
             static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size");
             _PyStackRef res;
-            _PyStackRef null = PyStackRef_NULL;
+            _PyStackRef *null;
             /* Skip 1 cache entry */
             // _NOP
             {
             }
             // _PUSH_NULL_CONDITIONAL
             {
-                null = PyStackRef_NULL;
+                null = &stack_pointer[1];
+                if (oparg & 1) {
+                    null[0] = PyStackRef_NULL;
+                }
             }
             stack_pointer[0] = res;
-            if (oparg & 1) stack_pointer[1] = null;
             stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
             _PyStackRef class_st;
             _PyStackRef self_st;
             _PyStackRef attr;
-            _PyStackRef null = PyStackRef_NULL;
+            _PyStackRef *null;
             // _SPECIALIZE_LOAD_SUPER_ATTR
             {
                 class_st = stack_pointer[-2];
             }
             // _PUSH_NULL_CONDITIONAL
             {
-                null = PyStackRef_NULL;
+                null = &stack_pointer[1];
+                if (oparg & 1) {
+                    null[0] = PyStackRef_NULL;
+                }
             }
             stack_pointer[0] = attr;
-            if (oparg & 1) stack_pointer[1] = null;
             stack_pointer += 1 + (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             DISPATCH();
index 95b5a1b52b8b65fa4e088e862be1008e7d458336..1f4873ee63a88f19211140eae0c5bcb8023ca505 100644 (file)
@@ -8,7 +8,11 @@
 #include "pycore_ceval.h"
 #include "pycore_critical_section.h"
 #include "pycore_dict.h"
+#include "pycore_floatobject.h"
+#include "pycore_frame.h"
+#include "pycore_interpframe.h"
 #include "pycore_intrinsics.h"
+#include "pycore_list.h"
 #include "pycore_long.h"
 #include "pycore_opcode_metadata.h"
 #include "pycore_opcode_utils.h"
@@ -16,6 +20,9 @@
 #include "pycore_pyerrors.h"
 #include "pycore_setobject.h"
 #include "pycore_sliceobject.h"
+#include "pycore_tuple.h"
+#include "pycore_unicodeobject.h"
+
 #include "pycore_jit.h"
 
 // Memory management stuff: ////////////////////////////////////////////////////
index 6fc5eabdf8b44e1876794ea3c4f81b4720b04295..e2fe0f6cff7464edca7564903254711291cae1af 100644 (file)
@@ -6,11 +6,15 @@
 #include "pycore_interp.h"
 #include "pycore_backoff.h"
 #include "pycore_bitutils.h"        // _Py_popcount32()
+#include "pycore_code.h"            // _Py_GetBaseCodeUnit
+#include "pycore_interpframe.h"
 #include "pycore_object.h"          // _PyObject_GC_UNTRACK()
 #include "pycore_opcode_metadata.h" // _PyOpcode_OpName[]
 #include "pycore_opcode_utils.h"  // MAX_REAL_OPCODE
 #include "pycore_optimizer.h"     // _Py_uop_analyze_and_optimize()
 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
+#include "pycore_tuple.h" // _PyTuple_FromArraySteal
+#include "pycore_unicodeobject.h" // _PyUnicode_FromASCII
 #include "pycore_uop_ids.h"
 #include "pycore_jit.h"
 #include <stdbool.h>
@@ -1226,11 +1230,7 @@ uop_optimize(
     for (int pc = 0; pc < length; pc++) {
         int opcode = buffer[pc].opcode;
         int oparg = buffer[pc].oparg;
-        if (_PyUop_Flags[opcode] & HAS_OPARG_AND_1_FLAG) {
-            buffer[pc].opcode = opcode + 1 + (oparg & 1);
-            assert(strncmp(_PyOpcode_uop_name[buffer[pc].opcode], _PyOpcode_uop_name[opcode], strlen(_PyOpcode_uop_name[opcode])) == 0);
-        }
-        else if (oparg < _PyUop_Replication[opcode]) {
+        if (oparg < _PyUop_Replication[opcode]) {
             buffer[pc].opcode = opcode + oparg + 1;
             assert(strncmp(_PyOpcode_uop_name[buffer[pc].opcode], _PyOpcode_uop_name[opcode], strlen(_PyOpcode_uop_name[opcode])) == 0);
         }
index 67bf8d11b3f9ac0cc4833741ef1b52df28b6e0c4..017a2eeca0741e1160eff4fc835defbf04899c52 100644 (file)
@@ -21,6 +21,7 @@
 #include "pycore_uop_metadata.h"
 #include "pycore_dict.h"
 #include "pycore_long.h"
+#include "pycore_interpframe.h"  // _PyFrame_GetCode
 #include "pycore_optimizer.h"
 #include "pycore_object.h"
 #include "pycore_dict.h"
index ea7c39bd01ea07da5976175e7a02abf274f6865c..cfa0a733cda21d24b98cc11f00f4459558dce1ba 100644 (file)
@@ -546,10 +546,14 @@ dummy_func(void) {
         }
     }
 
-    op (_PUSH_NULL_CONDITIONAL, ( -- null if (oparg & 1))) {
-        int opcode = (oparg & 1) ? _PUSH_NULL : _NOP;
-        REPLACE_OP(this_instr, opcode, 0, 0);
-        null = sym_new_null(ctx);
+    op (_PUSH_NULL_CONDITIONAL, ( -- null[oparg & 1])) {
+        if (oparg & 1) {
+            REPLACE_OP(this_instr, _PUSH_NULL, 0, 0);
+            null[0] = sym_new_null(ctx);
+        }
+        else {
+            REPLACE_OP(this_instr, _NOP, 0, 0);
+        }
     }
 
     op(_LOAD_ATTR, (owner -- attr, self_or_null[oparg&1])) {
@@ -765,7 +769,7 @@ dummy_func(void) {
         Py_UNREACHABLE();
     }
 
-    op(_PUSH_FRAME, (new_frame: _Py_UOpsAbstractFrame * -- unused if (0))) {
+    op(_PUSH_FRAME, (new_frame: _Py_UOpsAbstractFrame * -- )) {
         SYNC_SP();
         ctx->frame->stack_pointer = stack_pointer;
         ctx->frame = new_frame;
index 3f315901a5beb833120433ccdb75de35ed1eac79..fc70ee31a80002c5c92ecf9b06f016abbdf1884d 100644 (file)
         }
 
         case _PUSH_NULL_CONDITIONAL: {
-            JitOptSymbol *null = NULL;
-            int opcode = (oparg & 1) ? _PUSH_NULL : _NOP;
-            REPLACE_OP(this_instr, opcode, 0, 0);
-            null = sym_new_null(ctx);
-            if (oparg & 1) stack_pointer[0] = null;
+            JitOptSymbol **null;
+            null = &stack_pointer[0];
+            if (oparg & 1) {
+                REPLACE_OP(this_instr, _PUSH_NULL, 0, 0);
+                null[0] = sym_new_null(ctx);
+            }
+            else {
+                REPLACE_OP(this_instr, _NOP, 0, 0);
+            }
             stack_pointer += (oparg & 1);
             assert(WITHIN_STACK_BOUNDS());
             break;
index 8445546ffdf71620ad6a2c996247fbc59eac267a..c50f98cb99b39663bc7b69507b7a5832755a5a78 100644 (file)
@@ -6,6 +6,7 @@
 #include "pycore_frame.h"
 #include "pycore_long.h"
 #include "pycore_optimizer.h"
+#include "pycore_stats.h"
 #include "pycore_tuple.h"         // _PyTuple_FromArray()
 
 #include <stdbool.h>
index 8fe58c320a33b2fa92647b6684adfab2ed308c54..ed21fce335c99d0d82a42c57697c133f9025eaf9 100644 (file)
@@ -18,6 +18,7 @@
 #include "pycore_long.h"          // _PyLong_InitTypes()
 #include "pycore_object.h"        // _PyDebug_PrintTotalRefs()
 #include "pycore_obmalloc.h"      // _PyMem_init_obmalloc()
+#include "pycore_optimizer.h"     // _Py_Executors_InvalidateAll
 #include "pycore_pathconfig.h"    // _PyPathConfig_UpdateGlobal()
 #include "pycore_pyerrors.h"      // _PyErr_Occurred()
 #include "pycore_pylifecycle.h"   // _PyErr_Print()
index e0ef198c1646c22b9cf3b769a53548e0864db8eb..ac2cfb7b50be405f50fd567e61a1e1be70c43961 100644 (file)
@@ -33,7 +33,6 @@ class Properties:
     pure: bool
     uses_opcode: bool
     tier: int | None = None
-    oparg_and_1: bool = False
     const_oparg: int = -1
     needs_prev: bool = False
     no_save_ip: bool = False
@@ -136,16 +135,14 @@ class Flush:
 class StackItem:
     name: str
     type: str | None
-    condition: str | None
     size: str
     peek: bool = False
     used: bool = False
 
     def __str__(self) -> str:
-        cond = f" if ({self.condition})" if self.condition else ""
         size = f"[{self.size}]" if self.size else ""
         type = "" if self.type is None else f"{self.type} "
-        return f"{type}{self.name}{size}{cond} {self.peek}"
+        return f"{type}{self.name}{size} {self.peek}"
 
     def is_array(self) -> bool:
         return self.size != ""
@@ -348,10 +345,7 @@ def override_error(
 def convert_stack_item(
     item: parser.StackEffect, replace_op_arg_1: str | None
 ) -> StackItem:
-    cond = item.cond
-    if replace_op_arg_1 and OPARG_AND_1.match(item.cond):
-        cond = replace_op_arg_1
-    return StackItem(item.name, item.type, cond, item.size)
+    return StackItem(item.name, item.type, item.size)
 
 def check_unused(stack: list[StackItem], input_names: dict[str, lexer.Token]) -> None:
     "Unused items cannot be on the stack above used, non-peek items"
@@ -815,33 +809,12 @@ def stack_effect_only_peeks(instr: parser.InstDef) -> bool:
         return False
     if len(stack_inputs) == 0:
         return False
-    if any(s.cond for s in stack_inputs) or any(s.cond for s in instr.outputs):
-        return False
     return all(
         (s.name == other.name and s.type == other.type and s.size == other.size)
         for s, other in zip(stack_inputs, instr.outputs)
     )
 
 
-OPARG_AND_1 = re.compile("\\(*oparg *& *1")
-
-
-def effect_depends_on_oparg_1(op: parser.InstDef) -> bool:
-    for effect in op.inputs:
-        if isinstance(effect, parser.CacheEffect):
-            continue
-        if not effect.cond:
-            continue
-        if OPARG_AND_1.match(effect.cond):
-            return True
-    for effect in op.outputs:
-        if not effect.cond:
-            continue
-        if OPARG_AND_1.match(effect.cond):
-            return True
-    return False
-
-
 def compute_properties(op: parser.CodeDef) -> Properties:
     escaping_calls = find_escaping_api_calls(op)
     has_free = (
@@ -908,29 +881,6 @@ def make_uop(
         body=op.block.tokens,
         properties=compute_properties(op),
     )
-    if effect_depends_on_oparg_1(op) and "split" in op.annotations:
-        result.properties.oparg_and_1 = True
-        for bit in ("0", "1"):
-            name_x = name + "_" + bit
-            properties = compute_properties(op)
-            if properties.oparg:
-                # May not need oparg anymore
-                properties.oparg = any(
-                    token.text == "oparg" for token in op.block.tokens
-                )
-            rep = Uop(
-                name=name_x,
-                context=op.context,
-                annotations=op.annotations,
-                stack=analyze_stack(op, bit),
-                caches=analyze_caches(inputs),
-                deferred_refs=analyze_deferred_refs(op),
-                output_stores=find_stores_outputs(op),
-                body=op.block.tokens,
-                properties=properties,
-            )
-            rep.replicates = result
-            uops[name_x] = rep
     for anno in op.annotations:
         if anno.startswith("replicate"):
             result.replicated = int(anno[10:-1])
index 8e6bc5a8995dc9c9b425220ff166ed573755bca0..fc0b468266078d1e151befe8d6991f86682e79c1 100644 (file)
@@ -648,8 +648,6 @@ def cflags(p: Properties) -> str:
         flags.append("HAS_PURE_FLAG")
     if p.no_save_ip:
         flags.append("HAS_NO_SAVE_IP_FLAG")
-    if p.oparg_and_1:
-        flags.append("HAS_OPARG_AND_1_FLAG")
     if flags:
         return " | ".join(flags)
     else:
index 6afca750be9b1950794da1b332b439c3e87cb936..b4bcd73fdbfe520beee0d44db2e14d76ebf92fc4 100644 (file)
@@ -227,7 +227,6 @@ annotations = {
     "register",
     "replaced",
     "pure",
-    "split",
     "replicate",
     "tier1",
     "tier2",
index b265847a26c971d9da4e6c1d9d00a0375664c285..15be7608e939371d0bf35ec6d95e8b44ded280cf 100644 (file)
@@ -48,19 +48,13 @@ def declare_variables(uop: Uop, out: CWriter, skip_inputs: bool) -> None:
         for var in reversed(uop.stack.inputs):
             if var.used and var.name not in variables:
                 variables.add(var.name)
-                if var.condition:
-                    out.emit(f"{type_name(var)}{var.name} = NULL;\n")
-                else:
-                    out.emit(f"{type_name(var)}{var.name};\n")
+                out.emit(f"{type_name(var)}{var.name};\n")
     for var in uop.stack.outputs:
         if var.peek:
             continue
         if var.name not in variables:
             variables.add(var.name)
-            if var.condition:
-                out.emit(f"{type_name(var)}{var.name} = NULL;\n")
-            else:
-                out.emit(f"{type_name(var)}{var.name};\n")
+            out.emit(f"{type_name(var)}{var.name};\n")
 
 
 def decref_inputs(
index 011f34de288871021385b68c1bdf579efa880a6c..84aed49d491e015ee254b9f0a7ba610cbe488dc4 100644 (file)
@@ -77,12 +77,11 @@ class Block(Node):
 class StackEffect(Node):
     name: str = field(compare=False)  # __eq__ only uses type, cond, size
     type: str = ""  # Optional `:type`
-    cond: str = ""  # Optional `if (cond)`
     size: str = ""  # Optional `[size]`
     # Note: size cannot be combined with type or cond
 
     def __repr__(self) -> str:
-        items = [self.name, self.type, self.cond, self.size]
+        items = [self.name, self.type, self.size]
         while items and items[-1] == "":
             del items[-1]
         return f"StackEffect({', '.join(repr(item) for item in items)})"
@@ -299,22 +298,15 @@ class Parser(PLexer):
                 type_text = self.require(lx.IDENTIFIER).text.strip()
                 if self.expect(lx.TIMES):
                     type_text += " *"
-            cond_text = ""
-            if self.expect(lx.IF):
-                self.require(lx.LPAREN)
-                if not (cond := self.expression()):
-                    raise self.make_syntax_error("Expected condition")
-                self.require(lx.RPAREN)
-                cond_text = cond.text.strip()
             size_text = ""
             if self.expect(lx.LBRACKET):
-                if type_text or cond_text:
+                if type_text:
                     raise self.make_syntax_error("Unexpected [")
                 if not (size := self.expression()):
                     raise self.make_syntax_error("Expected expression")
                 self.require(lx.RBRACKET)
                 size_text = size.text.strip()
-            return StackEffect(tkn.text, type_text, cond_text, size_text)
+            return StackEffect(tkn.text, type_text, size_text)
         return None
 
     @contextual
index 51c4c810e2071434d2eaa8fda786e4a9435ef5da..70fa8abe513953a69bb026c626e355ba9e763db0 100644 (file)
@@ -23,17 +23,7 @@ def maybe_parenthesize(sym: str) -> str:
 
 
 def var_size(var: StackItem) -> str:
-    if var.condition:
-        # Special case simplifications
-        if var.condition == "0":
-            return "0"
-        elif var.condition == "1":
-            return var.get_size()
-        elif var.condition == "oparg & 1" and not var.size:
-            return f"({var.condition})"
-        else:
-            return f"(({var.condition}) ? {var.get_size()} : 0)"
-    elif var.size:
+    if var.size:
         return var.size
     else:
         return "1"
@@ -89,10 +79,6 @@ class Local:
     def name(self) -> str:
         return self.item.name
 
-    @property
-    def condition(self) -> str | None:
-        return self.item.condition
-
     def is_array(self) -> bool:
         return self.item.is_array()
 
@@ -275,15 +261,7 @@ class Stack:
         cast = f"({var.type})" if (not indirect and var.type) else ""
         bits = ".bits" if cast and self.extract_bits else ""
         assign = f"{var.name} = {cast}{indirect}stack_pointer[{self.base_offset.to_c()}]{bits};"
-        if var.condition:
-            if var.condition == "1":
-                assign = f"{assign}\n"
-            elif var.condition == "0":
-                return "", Local.unused(var)
-            else:
-                assign = f"if ({var.condition}) {{ {assign} }}\n"
-        else:
-            assign = f"{assign}\n"
+        assign = f"{assign}\n"
         return assign, Local.from_memory(var)
 
     def push(self, var: Local) -> None:
@@ -303,10 +281,6 @@ class Stack:
     ) -> None:
         cast = f"({cast_type})" if var.type else ""
         bits = ".bits" if cast and extract_bits else ""
-        if var.condition == "0":
-            return
-        if var.condition and var.condition != "1":
-            out.emit(f"if ({var.condition}) ")
         out.emit(f"stack_pointer[{base_offset.to_c()}]{bits} = {cast}{var.name};\n")
 
     def _adjust_stack_pointer(self, out: CWriter, number: str) -> None:
@@ -655,7 +629,7 @@ class Storage:
         def close_variable(var: Local, overwrite: str) -> None:
             nonlocal tmp_defined
             close = "PyStackRef_CLOSE"
-            if "null" in var.name or var.condition and var.condition != "1":
+            if "null" in var.name:
                 close = "PyStackRef_XCLOSE"
             if var.size:
                 if var.size == "1":
@@ -668,8 +642,6 @@ class Storage:
                     close_named(close, f"{var.name}[_i]", overwrite)
                     out.emit("}\n")
             else:
-                if var.condition and var.condition == "0":
-                    return
                 close_named(close, var.name, overwrite)
 
         self.clear_dead_inputs()
index 0f0addb3d9958936430bf71d2ccd40118ead6cf4..ee375681b50f0bed1fe12cdd48526f4a5aef3ecc 100644 (file)
@@ -40,10 +40,7 @@ LABEL_END_MARKER = "/* END LABELS */"
 def declare_variable(var: StackItem, out: CWriter) -> None:
     type, null = type_and_null(var)
     space = " " if type[-1].isalnum() else ""
-    if var.condition:
-        out.emit(f"{type}{space}{var.name} = {null};\n")
-    else:
-        out.emit(f"{type}{space}{var.name};\n")
+    out.emit(f"{type}{space}{var.name};\n")
 
 
 def declare_variables(inst: Instruction, out: CWriter) -> None:
index d378815f6af3911fd192acdaa695531e4f9a928d..572c636e84c0ca5a114694e06a3320579900abca 100644 (file)
@@ -41,14 +41,7 @@ def declare_variable(
     required.remove(var.name)
     type, null = type_and_null(var)
     space = " " if type[-1].isalnum() else ""
-    if var.condition:
-        out.emit(f"{type}{space}{var.name} = {null};\n")
-        if uop.replicates:
-            # Replicas may not use all their conditional variables
-            # So avoid a compiler warning with a fake use
-            out.emit(f"(void){var.name};\n")
-    else:
-        out.emit(f"{type}{space}{var.name};\n")
+    out.emit(f"{type}{space}{var.name};\n")
 
 
 def declare_variables(uop: Uop, out: CWriter) -> None:
@@ -189,9 +182,6 @@ def generate_tier2(
     for name, uop in analysis.uops.items():
         if uop.properties.tier == 1:
             continue
-        if uop.properties.oparg_and_1:
-            out.emit(f"/* {uop.name} is split on (oparg & 1) */\n\n")
-            continue
         if uop.is_super():
             continue
         why_not_viable = uop.why_not_viable()
index 0b7d077d78ce7d3eac761ff8bde0040a42df5dfc..adc08f3cc5f2a5af5749b52f953c24832fcdc46d 100644 (file)
@@ -4,10 +4,16 @@
 #include "pycore_call.h"
 #include "pycore_ceval.h"
 #include "pycore_cell.h"
+#include "pycore_code.h"
 #include "pycore_dict.h"
+#include "pycore_floatobject.h"
 #include "pycore_emscripten_signal.h"
+#include "pycore_frame.h"
+#include "pycore_genobject.h"
+#include "pycore_interpframe.h"
 #include "pycore_intrinsics.h"
 #include "pycore_jit.h"
+#include "pycore_list.h"
 #include "pycore_long.h"
 #include "pycore_opcode_metadata.h"
 #include "pycore_opcode_utils.h"
@@ -18,6 +24,8 @@
 #include "pycore_sliceobject.h"
 #include "pycore_descrobject.h"
 #include "pycore_stackref.h"
+#include "pycore_tuple.h"
+#include "pycore_unicodeobject.h"
 
 #include "ceval_macros.h"