diff --git a/Include/internal/pycore_jit.h b/Include/internal/pycore_jit.h index 4d6cc35a7a3de7..8a88cbf607ba4b 100644 --- a/Include/internal/pycore_jit.h +++ b/Include/internal/pycore_jit.h @@ -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 diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py index 39ad07ff79be31..3eb650bf3e6942 100644 --- a/Lib/test/test_generated_cases.py +++ b/Lib/test/test_generated_cases.py @@ -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 @@ def test_array_error_if(self): """ 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)) { diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 5f39ed11b57e5c..56e3408652a6a0 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -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() diff --git a/Objects/codeobject.c b/Objects/codeobject.c index c55ab6b9b28e9e..635da094e37a29 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -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() diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 66546080b1f5fe..cdd4d5bdd46b43 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -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) = diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index ff9f33b6db0187..42a3d6d4be9ba4 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -2285,10 +2285,12 @@ } 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; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 558b0b48ceaa71..9ce2b633d5e506 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -6982,7 +6982,7 @@ _PyStackRef class_st; _PyStackRef self_st; _PyStackRef attr; - _PyStackRef null = PyStackRef_NULL; + _PyStackRef *null; /* Skip 1 cache entry */ // _LOAD_SUPER_ATTR { @@ -7078,10 +7078,12 @@ } // _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(); @@ -7840,7 +7842,7 @@ 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 { @@ -7876,9 +7878,11 @@ } // _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(); @@ -7897,7 +7901,7 @@ 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 { @@ -7943,9 +7947,11 @@ } // _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(); @@ -8022,7 +8028,7 @@ 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 { @@ -8078,9 +8084,11 @@ /* 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(); @@ -8270,7 +8278,7 @@ 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 { @@ -8321,9 +8329,11 @@ /* 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(); @@ -8552,7 +8562,7 @@ 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 { @@ -8599,9 +8609,11 @@ /* 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(); @@ -8620,7 +8632,7 @@ 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 { @@ -8700,9 +8712,11 @@ /* 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(); @@ -9080,7 +9094,7 @@ _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); @@ -9114,9 +9128,11 @@ } // _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(); @@ -9134,7 +9150,7 @@ 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 { @@ -9191,10 +9207,12 @@ } // _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(); @@ -9212,7 +9230,7 @@ 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 { @@ -9256,10 +9274,12 @@ } // _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(); @@ -9387,7 +9407,7 @@ _PyStackRef class_st; _PyStackRef self_st; _PyStackRef attr; - _PyStackRef null = PyStackRef_NULL; + _PyStackRef *null; // _SPECIALIZE_LOAD_SUPER_ATTR { class_st = stack_pointer[-2]; @@ -9499,10 +9519,12 @@ } // _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(); diff --git a/Python/jit.c b/Python/jit.c index 95b5a1b52b8b65..1f4873ee63a88f 100644 --- a/Python/jit.c +++ b/Python/jit.c @@ -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: //////////////////////////////////////////////////// diff --git a/Python/optimizer.c b/Python/optimizer.c index 6fc5eabdf8b44e..e2fe0f6cff7464 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -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 @@ -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); } diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 67bf8d11b3f9ac..017a2eeca0741e 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -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" diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index ea7c39bd01ea07..cfa0a733cda21d 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -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; diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 3f315901a5beb8..fc70ee31a80002 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -921,11 +921,15 @@ } 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; diff --git a/Python/optimizer_symbols.c b/Python/optimizer_symbols.c index 8445546ffdf716..c50f98cb99b396 100644 --- a/Python/optimizer_symbols.c +++ b/Python/optimizer_symbols.c @@ -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 diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 8fe58c320a33b2..ed21fce335c99d 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -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() diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index e0ef198c1646c2..ac2cfb7b50be40 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -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 @@ def size(self) -> int: 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]) diff --git a/Tools/cases_generator/generators_common.py b/Tools/cases_generator/generators_common.py index 8e6bc5a8995dc9..fc0b468266078d 100644 --- a/Tools/cases_generator/generators_common.py +++ b/Tools/cases_generator/generators_common.py @@ -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: diff --git a/Tools/cases_generator/lexer.py b/Tools/cases_generator/lexer.py index 6afca750be9b19..b4bcd73fdbfe52 100644 --- a/Tools/cases_generator/lexer.py +++ b/Tools/cases_generator/lexer.py @@ -227,7 +227,6 @@ def choice(*opts: str) -> str: "register", "replaced", "pure", - "split", "replicate", "tier1", "tier2", diff --git a/Tools/cases_generator/optimizer_generator.py b/Tools/cases_generator/optimizer_generator.py index b265847a26c971..15be7608e93937 100644 --- a/Tools/cases_generator/optimizer_generator.py +++ b/Tools/cases_generator/optimizer_generator.py @@ -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( diff --git a/Tools/cases_generator/parsing.py b/Tools/cases_generator/parsing.py index 011f34de288871..84aed49d491e01 100644 --- a/Tools/cases_generator/parsing.py +++ b/Tools/cases_generator/parsing.py @@ -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 @@ def stack_effect(self) -> StackEffect | None: 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 diff --git a/Tools/cases_generator/stack.py b/Tools/cases_generator/stack.py index 51c4c810e20714..70fa8abe513953 100644 --- a/Tools/cases_generator/stack.py +++ b/Tools/cases_generator/stack.py @@ -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 @@ def size(self) -> str: 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 @@ def pop(self, var: StackItem) -> tuple[str, Local]: 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 @@ def _do_emit( ) -> 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 @@ def close_named(close: str, name: str, overwrite: str) -> None: 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 @@ def close_variable(var: Local, overwrite: str) -> None: 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() diff --git a/Tools/cases_generator/tier1_generator.py b/Tools/cases_generator/tier1_generator.py index 0f0addb3d99589..ee375681b50f0b 100644 --- a/Tools/cases_generator/tier1_generator.py +++ b/Tools/cases_generator/tier1_generator.py @@ -40,10 +40,7 @@ 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: diff --git a/Tools/cases_generator/tier2_generator.py b/Tools/cases_generator/tier2_generator.py index d378815f6af391..572c636e84c0ca 100644 --- a/Tools/cases_generator/tier2_generator.py +++ b/Tools/cases_generator/tier2_generator.py @@ -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() diff --git a/Tools/jit/template.c b/Tools/jit/template.c index 0b7d077d78ce7d..adc08f3cc5f2a5 100644 --- a/Tools/jit/template.c +++ b/Tools/jit/template.c @@ -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" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy