From 8dc1a32c6191ac4b25f3615e1b96e1687f5f2fba Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 14 Dec 2023 05:10:32 +0000 Subject: [PATCH 1/6] Break up instructions with unused cache entries into component micro-ops --- Lib/test/test_generated_cases.py | 17 ++++++ Python/generated_cases.c.h | 71 ++++++++++++++++++++++++ Tools/cases_generator/analyzer.py | 30 +++++++--- Tools/cases_generator/parser.py | 1 + Tools/cases_generator/tier1_generator.py | 3 +- 5 files changed, 114 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py index de96a8764594ba..d65d87fb3aa2ea 100644 --- a/Lib/test/test_generated_cases.py +++ b/Lib/test/test_generated_cases.py @@ -466,6 +466,23 @@ def test_macro_instruction(self): """ self.run_cases_test(input, output) + def test_unused_cache(self): + input = """ + inst(OP, (unused/1 --)) { + body(); + } + """ + output = """ + TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 2; + INSTRUCTION_STATS(OP); + body(); + DISPATCH(); + } + """ + self.run_cases_test(input, output) + def test_pseudo_instruction_no_flags(self): input = """ pseudo(OP) = { diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 24f26722d7a745..8bd6495a881f56 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -452,6 +452,7 @@ PyObject *sub; PyObject *dict; PyObject *res; + /* Skip 1 cache entry */ sub = stack_pointer[-1]; dict = stack_pointer[-2]; DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR); @@ -476,6 +477,7 @@ static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 1, "incorrect cache size"); PyObject *sub; PyObject *container; + /* Skip 1 cache entry */ sub = stack_pointer[-1]; container = stack_pointer[-2]; DEOPT_IF(tstate->interp->eval_frame, BINARY_SUBSCR); @@ -509,6 +511,7 @@ PyObject *sub; PyObject *list; PyObject *res; + /* Skip 1 cache entry */ sub = stack_pointer[-1]; list = stack_pointer[-2]; DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); @@ -536,6 +539,7 @@ PyObject *sub; PyObject *str; PyObject *res; + /* Skip 1 cache entry */ sub = stack_pointer[-1]; str = stack_pointer[-2]; DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); @@ -563,6 +567,7 @@ PyObject *sub; PyObject *tuple; PyObject *res; + /* Skip 1 cache entry */ sub = stack_pointer[-1]; tuple = stack_pointer[-2]; DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); @@ -840,6 +845,8 @@ PyObject **args; PyObject *null; PyObject *callable; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1001,6 +1008,8 @@ PyObject *self_or_null; PyObject *callable; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1035,6 +1044,8 @@ PyObject *self_or_null; PyObject *callable; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1080,6 +1091,8 @@ PyObject *self_or_null; PyObject *callable; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1119,6 +1132,8 @@ PyObject *self_or_null; PyObject *callable; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1279,6 +1294,8 @@ PyObject *self_or_null; PyObject *callable; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1408,6 +1425,8 @@ PyObject *self_or_null; PyObject *callable; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1444,6 +1463,8 @@ PyObject **args; PyObject *self; PyObject *callable; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; self = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1475,6 +1496,8 @@ PyObject *self_or_null; PyObject *callable; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1517,6 +1540,8 @@ PyObject *self_or_null; PyObject *callable; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1559,6 +1584,8 @@ PyObject *self_or_null; PyObject *callable; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1603,6 +1630,8 @@ PyObject *self_or_null; PyObject *callable; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1728,6 +1757,7 @@ PyObject **args; PyObject *self_or_null; PyObject *callable; + /* Skip 1 cache entry */ args = &stack_pointer[-oparg]; self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1774,6 +1804,8 @@ PyObject *null; PyObject *callable; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1801,6 +1833,8 @@ PyObject *null; PyObject *callable; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1828,6 +1862,8 @@ PyObject *null; PyObject *callable; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; @@ -1982,6 +2018,7 @@ PyObject *right; PyObject *left; PyObject *res; + /* Skip 1 cache entry */ right = stack_pointer[-1]; left = stack_pointer[-2]; DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); @@ -2008,6 +2045,7 @@ PyObject *right; PyObject *left; PyObject *res; + /* Skip 1 cache entry */ right = stack_pointer[-1]; left = stack_pointer[-2]; DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP); @@ -2038,6 +2076,7 @@ PyObject *right; PyObject *left; PyObject *res; + /* Skip 1 cache entry */ right = stack_pointer[-1]; left = stack_pointer[-2]; DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); @@ -2469,6 +2508,7 @@ INSTRUCTION_STATS(FOR_ITER_GEN); static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); PyObject *iter; + /* Skip 1 cache entry */ iter = stack_pointer[-1]; DEOPT_IF(tstate->interp->eval_frame, FOR_ITER); PyGenObject *gen = (PyGenObject *)iter; @@ -2843,6 +2883,7 @@ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; next_instr += 4; INSTRUCTION_STATS(INSTRUMENTED_CALL); + /* Skip 3 cache entries */ int is_meth = PEEK(oparg + 1) != NULL; int total_args = oparg + is_meth; PyObject *function = PEEK(oparg + 2); @@ -2929,6 +2970,7 @@ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; next_instr += 2; INSTRUCTION_STATS(INSTRUMENTED_FOR_ITER); + /* Skip 1 cache entry */ _Py_CODEUNIT *target; PyObject *iter = TOP(); PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter); @@ -2976,6 +3018,7 @@ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; next_instr += 2; INSTRUCTION_STATS(INSTRUMENTED_JUMP_BACKWARD); + /* Skip 1 cache entry */ CHECK_EVAL_BREAKER(); INSTRUMENTED_JUMP(this_instr, next_instr - oparg, PY_MONITORING_EVENT_JUMP); DISPATCH(); @@ -2993,6 +3036,7 @@ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; next_instr += 2; INSTRUCTION_STATS(INSTRUMENTED_LOAD_SUPER_ATTR); + /* Skip 1 cache entry */ // cancel out the decrement that will happen in LOAD_SUPER_ATTR; we // don't want to specialize instrumented instructions INCREMENT_ADAPTIVE_COUNTER(this_instr[1].cache); @@ -3003,6 +3047,7 @@ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; next_instr += 2; INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_FALSE); + /* Skip 1 cache entry */ PyObject *cond = POP(); assert(PyBool_Check(cond)); int flag = Py_IsFalse(cond); @@ -3018,6 +3063,7 @@ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; next_instr += 2; INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_NONE); + /* Skip 1 cache entry */ PyObject *value = POP(); int flag = Py_IsNone(value); int offset; @@ -3039,6 +3085,7 @@ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; next_instr += 2; INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_NOT_NONE); + /* Skip 1 cache entry */ PyObject *value = POP(); int offset; int nflag = Py_IsNone(value); @@ -3060,6 +3107,7 @@ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; next_instr += 2; INSTRUCTION_STATS(INSTRUMENTED_POP_JUMP_IF_TRUE); + /* Skip 1 cache entry */ PyObject *cond = POP(); assert(PyBool_Check(cond)); int flag = Py_IsTrue(cond); @@ -3216,6 +3264,7 @@ _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; next_instr += 2; INSTRUCTION_STATS(JUMP_BACKWARD); + /* Skip 1 cache entry */ CHECK_EVAL_BREAKER(); assert(oparg <= INSTR_OFFSET()); JUMPBY(-oparg); @@ -3429,6 +3478,7 @@ INSTRUCTION_STATS(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN); static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); PyObject *owner; + /* Skip 1 cache entry */ owner = stack_pointer[-1]; uint32_t type_version = read_u32(&this_instr[2].cache); uint32_t func_version = read_u32(&this_instr[4].cache); @@ -3743,6 +3793,7 @@ INSTRUCTION_STATS(LOAD_ATTR_PROPERTY); static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); PyObject *owner; + /* Skip 1 cache entry */ owner = stack_pointer[-1]; uint32_t type_version = read_u32(&this_instr[2].cache); uint32_t func_version = read_u32(&this_instr[4].cache); @@ -4300,6 +4351,7 @@ PyObject *class; PyObject *global_super; PyObject *attr; + /* Skip 1 cache entry */ self = stack_pointer[-1]; class = stack_pointer[-2]; global_super = stack_pointer[-3]; @@ -4328,6 +4380,7 @@ PyObject *global_super; PyObject *attr; PyObject *self_or_null; + /* Skip 1 cache entry */ self = stack_pointer[-1]; class = stack_pointer[-2]; global_super = stack_pointer[-3]; @@ -4927,6 +4980,7 @@ static_assert(INLINE_CACHE_ENTRIES_SEND == 1, "incorrect cache size"); PyObject *v; PyObject *receiver; + /* Skip 1 cache entry */ v = stack_pointer[-1]; receiver = stack_pointer[-2]; DEOPT_IF(tstate->interp->eval_frame, SEND); @@ -5157,6 +5211,7 @@ static_assert(INLINE_CACHE_ENTRIES_STORE_ATTR == 4, "incorrect cache size"); PyObject *owner; PyObject *value; + /* Skip 1 cache entry */ owner = stack_pointer[-1]; value = stack_pointer[-2]; uint32_t type_version = read_u32(&this_instr[2].cache); @@ -5374,6 +5429,7 @@ PyObject *sub; PyObject *dict; PyObject *value; + /* Skip 1 cache entry */ sub = stack_pointer[-1]; dict = stack_pointer[-2]; value = stack_pointer[-3]; @@ -5394,6 +5450,7 @@ PyObject *sub; PyObject *list; PyObject *value; + /* Skip 1 cache entry */ sub = stack_pointer[-1]; list = stack_pointer[-2]; value = stack_pointer[-3]; @@ -5470,6 +5527,7 @@ static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); PyObject *value; PyObject *res; + /* Skip 1 cache entry */ value = stack_pointer[-1]; uint32_t version = read_u32(&this_instr[2].cache); // This one is a bit weird, because we expect *some* failures: @@ -5488,6 +5546,8 @@ INSTRUCTION_STATS(TO_BOOL_BOOL); static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); PyObject *value; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ value = stack_pointer[-1]; DEOPT_IF(!PyBool_Check(value), TO_BOOL); STAT_INC(TO_BOOL, hit); @@ -5501,6 +5561,8 @@ static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); PyObject *value; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ value = stack_pointer[-1]; DEOPT_IF(!PyLong_CheckExact(value), TO_BOOL); STAT_INC(TO_BOOL, hit); @@ -5523,6 +5585,8 @@ static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); PyObject *value; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ value = stack_pointer[-1]; DEOPT_IF(!PyList_CheckExact(value), TO_BOOL); STAT_INC(TO_BOOL, hit); @@ -5539,6 +5603,8 @@ static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); PyObject *value; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ value = stack_pointer[-1]; // This one is a bit weird, because we expect *some* failures: DEOPT_IF(!Py_IsNone(value), TO_BOOL); @@ -5555,6 +5621,8 @@ static_assert(INLINE_CACHE_ENTRIES_TO_BOOL == 3, "incorrect cache size"); PyObject *value; PyObject *res; + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ value = stack_pointer[-1]; DEOPT_IF(!PyUnicode_CheckExact(value), TO_BOOL); STAT_INC(TO_BOOL, hit); @@ -5669,6 +5737,7 @@ static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); PyObject *seq; PyObject **values; + /* Skip 1 cache entry */ seq = stack_pointer[-1]; values = &stack_pointer[-1]; DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); @@ -5690,6 +5759,7 @@ static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); PyObject *seq; PyObject **values; + /* Skip 1 cache entry */ seq = stack_pointer[-1]; values = &stack_pointer[-1]; DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); @@ -5711,6 +5781,7 @@ static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); PyObject *seq; PyObject **values; + /* Skip 1 cache entry */ seq = stack_pointer[-1]; values = &stack_pointer[-1]; DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index bcc13538e51d9b..25a1221f36f684 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -234,9 +234,9 @@ def analyze_stack(op: parser.InstDef) -> StackEffect: return StackEffect(inputs, outputs) -def analyze_caches(op: parser.InstDef) -> list[CacheEntry]: +def analyze_caches(inputs: list[parser.InputEffect]) -> list[CacheEntry]: caches: list[parser.CacheEffect] = [ - i for i in op.inputs if isinstance(i, parser.CacheEffect) + i for i in inputs if isinstance(i, parser.CacheEffect) ] return [CacheEntry(i.name, int(i.size)) for i in caches] @@ -314,13 +314,13 @@ def compute_properties(op: parser.InstDef) -> Properties: ) -def make_uop(name: str, op: parser.InstDef) -> Uop: +def make_uop(name: str, op: parser.InstDef, inputs: list[parser.InputEffect]) -> Uop: return Uop( name=name, context=op.context, annotations=op.annotations, stack=analyze_stack(op), - caches=analyze_caches(op), + caches=analyze_caches(inputs), body=op.block.tokens, properties=compute_properties(op), ) @@ -333,7 +333,7 @@ def add_op(op: parser.InstDef, uops: dict[str, Uop]) -> None: raise override_error( op.name, op.context, uops[op.name].context, op.tokens[0] ) - uops[op.name] = make_uop(op.name, op) + uops[op.name] = make_uop(op.name, op, op.inputs) def add_instruction( @@ -347,10 +347,26 @@ def desugar_inst( ) -> None: assert inst.kind == "inst" name = inst.name - uop = make_uop("_" + inst.name, inst) + + op_inputs: list[parser.InputEffect] = [] + parts: list[Part] = [] + uop_index = -1 + for input in inst.inputs: + if isinstance(input, parser.CacheEffect) and input.name == "unused": + parts.append(Skip(input.size)) + else: + op_inputs.append(input) + if uop_index < 0: + uop_index = len(parts) + parts.append(Skip(0)) + uop = make_uop("_" + inst.name, inst, op_inputs) uop.implicitly_created = True uops[inst.name] = uop - add_instruction(name, [uop], instructions) + if uop_index < 0: + parts.append(uop) + else: + parts[uop_index] = uop + add_instruction(name, parts, instructions) def add_macro( diff --git a/Tools/cases_generator/parser.py b/Tools/cases_generator/parser.py index 12173a61199700..fe4e8e476eadee 100644 --- a/Tools/cases_generator/parser.py +++ b/Tools/cases_generator/parser.py @@ -7,6 +7,7 @@ Context, CacheEffect, StackEffect, + InputEffect, OpName, AstNode, ) diff --git a/Tools/cases_generator/tier1_generator.py b/Tools/cases_generator/tier1_generator.py index 11885dca6fe1a2..f5f5c6945f5a43 100644 --- a/Tools/cases_generator/tier1_generator.py +++ b/Tools/cases_generator/tier1_generator.py @@ -151,7 +151,8 @@ def generate_tier1( stack = Stack() for part in inst.parts: # Only emit braces if more than one uop - offset = write_uop(part, out, offset, stack, inst, len(inst.parts) > 1) + insert_braces = len([p for p in inst.parts if isinstance(p, Uop)]) > 1 + offset = write_uop(part, out, offset, stack, inst, insert_braces) out.start_line() if not inst.parts[-1].properties.always_exits: stack.flush(out) From 182309ecbd8cb83d50472eb17b5663971d37265e Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 14 Dec 2023 05:26:51 +0000 Subject: [PATCH 2/6] Fix whitespace --- Tools/cases_generator/analyzer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index 25a1221f36f684..30da2c7d4e2055 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -347,7 +347,6 @@ def desugar_inst( ) -> None: assert inst.kind == "inst" name = inst.name - op_inputs: list[parser.InputEffect] = [] parts: list[Part] = [] uop_index = -1 From 6a0b2e085d1be1019a8fc04e18a8472dbb63a7e6 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 14 Dec 2023 09:22:23 +0000 Subject: [PATCH 3/6] Test new cases generator, not old one --- Lib/test/test_generated_cases.py | 119 ++++++++++++--------- Tools/cases_generator/analyzer.py | 3 +- Tools/cases_generator/generators_common.py | 6 +- Tools/cases_generator/tier1_generator.py | 8 ++ 4 files changed, 83 insertions(+), 53 deletions(-) diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py index d65d87fb3aa2ea..585ef55976b956 100644 --- a/Lib/test/test_generated_cases.py +++ b/Lib/test/test_generated_cases.py @@ -32,6 +32,7 @@ def skip_if_different_mount_drives(): import analysis import formatting from parsing import StackEffect + import tier1_generator def handle_stderr(): @@ -108,13 +109,12 @@ def run_cases_test(self, input: str, expected: str): temp_input.write(analysis.END_MARKER) temp_input.flush() - a = generate_cases.Generator([self.temp_input_filename]) with handle_stderr(): - a.parse() - a.analyze() - if a.errors: - raise RuntimeError(f"Found {a.errors} errors") - a.write_instructions(self.temp_output_filename, False) + tier1_generator.generate_tier1_from_files( + [self.temp_input_filename], + self.temp_output_filename, + False + ) with open(self.temp_output_filename) as temp_output: lines = temp_output.readlines() @@ -163,7 +163,7 @@ def test_inst_one_pop(self): PyObject *value; value = stack_pointer[-1]; spam(); - STACK_SHRINK(1); + stack_pointer += -1; DISPATCH(); } """ @@ -182,8 +182,8 @@ def test_inst_one_push(self): INSTRUCTION_STATS(OP); PyObject *res; spam(); - STACK_GROW(1); - stack_pointer[-1] = res; + stack_pointer[0] = res; + stack_pointer += 1; DISPATCH(); } """ @@ -227,8 +227,8 @@ def test_binary_op(self): right = stack_pointer[-1]; left = stack_pointer[-2]; spam(); - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } """ @@ -273,7 +273,6 @@ def test_predictions_and_eval_breaker(self): next_instr += 1; INSTRUCTION_STATS(OP1); PREDICTED(OP1); - static_assert(INLINE_CACHE_ENTRIES_OP1 == 0, "incorrect cache size"); PyObject *arg; PyObject *rest; arg = stack_pointer[-1]; @@ -285,6 +284,7 @@ def test_predictions_and_eval_breaker(self): frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(OP3); + static_assert(INLINE_CACHE_ENTRIES_OP1 == 0, "incorrect cache size"); PyObject *arg; PyObject *res; arg = stack_pointer[-1]; @@ -325,6 +325,7 @@ def test_error_if_plain_with_comment(self): next_instr += 1; INSTRUCTION_STATS(OP); if (cond) goto label; + // Comment is ok DISPATCH(); } """ @@ -347,8 +348,8 @@ def test_error_if_pop(self): right = stack_pointer[-1]; left = stack_pointer[-2]; if (cond) goto pop_2_label; - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } """ @@ -368,7 +369,7 @@ def test_cache_effect(self): value = stack_pointer[-1]; uint16_t counter = read_u16(&this_instr[1].cache); uint32_t extra = read_u32(&this_instr[2].cache); - STACK_SHRINK(1); + stack_pointer += -1; DISPATCH(); } """ @@ -411,26 +412,26 @@ def test_macro_instruction(self): INSTRUCTION_STATS(OP); PREDICTED(OP); _Py_CODEUNIT *this_instr = next_instr - 6; - static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size"); PyObject *right; PyObject *left; PyObject *arg2; PyObject *res; - // OP1 + // _OP1 right = stack_pointer[-1]; left = stack_pointer[-2]; { uint16_t counter = read_u16(&this_instr[1].cache); op1(left, right); } + /* Skip 2 cache entries */ // OP2 arg2 = stack_pointer[-3]; { uint32_t extra = read_u32(&this_instr[4].cache); res = op2(arg2, left, right); } - STACK_SHRINK(2); - stack_pointer[-1] = res; + stack_pointer[-3] = res; + stack_pointer += -2; DISPATCH(); } @@ -451,16 +452,18 @@ def test_macro_instruction(self): frame->instr_ptr = next_instr; next_instr += 6; INSTRUCTION_STATS(OP3); + static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size"); PyObject *right; PyObject *left; PyObject *arg2; PyObject *res; + /* Skip 5 cache entries */ right = stack_pointer[-1]; left = stack_pointer[-2]; arg2 = stack_pointer[-3]; res = op3(arg2, left, right); - STACK_SHRINK(2); - stack_pointer[-1] = res; + stack_pointer[-3] = res; + stack_pointer += -2; DISPATCH(); } """ @@ -477,6 +480,26 @@ def test_unused_cache(self): frame->instr_ptr = next_instr; next_instr += 2; INSTRUCTION_STATS(OP); + /* Skip 1 cache entry */ + body(); + DISPATCH(); + } + """ + self.run_cases_test(input, output) + + def test_unused_caches(self): + input = """ + inst(OP, (unused/1, unused/2 --)) { + body(); + } + """ + output = """ + TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(OP); + /* Skip 1 cache entry */ + /* Skip 2 cache entries */ body(); DISPATCH(); } @@ -536,11 +559,10 @@ def test_array_input(self): PyObject **values; PyObject *below; above = stack_pointer[-1]; - values = stack_pointer - 1 - oparg*2; + values = &stack_pointer[-1 - oparg*2]; below = stack_pointer[-2 - oparg*2]; spam(); - STACK_SHRINK(oparg*2); - STACK_SHRINK(2); + stack_pointer += -2 - oparg*2; DISPATCH(); } """ @@ -560,11 +582,11 @@ def test_array_output(self): PyObject *below; PyObject **values; PyObject *above; - values = stack_pointer - 1; + values = &stack_pointer[-1]; spam(values, oparg); - STACK_GROW(oparg*3); - stack_pointer[-2 - oparg*3] = below; - stack_pointer[-1] = above; + stack_pointer[-2] = below; + stack_pointer[-1 + oparg*3] = above; + stack_pointer += oparg*3; DISPATCH(); } """ @@ -583,10 +605,10 @@ def test_array_input_output(self): INSTRUCTION_STATS(OP); PyObject **values; PyObject *above; - values = stack_pointer - oparg; + values = &stack_pointer[-oparg]; spam(values, oparg); - STACK_GROW(1); - stack_pointer[-1] = above; + stack_pointer[0] = above; + stack_pointer += 1; DISPATCH(); } """ @@ -605,11 +627,10 @@ def test_array_error_if(self): INSTRUCTION_STATS(OP); PyObject **values; PyObject *extra; - values = stack_pointer - oparg; + values = &stack_pointer[-oparg]; extra = stack_pointer[-1 - oparg]; - if (oparg == 0) { STACK_SHRINK(oparg); goto pop_1_somewhere; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); + if (oparg == 0) { stack_pointer += -1 - oparg; goto somewhere; } + stack_pointer += -1 - oparg; DISPATCH(); } """ @@ -633,14 +654,13 @@ def test_cond_effect(self): PyObject *output = NULL; PyObject *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)]; + 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, input); - STACK_SHRINK((((oparg & 1) == 1) ? 1 : 0)); - STACK_GROW(((oparg & 2) ? 1 : 0)); - stack_pointer[-2 - (oparg & 2 ? 1 : 0)] = xx; - if (oparg & 2) { stack_pointer[-1 - (oparg & 2 ? 1 : 0)] = output; } - stack_pointer[-1] = zz; + 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)); DISPATCH(); } """ @@ -678,11 +698,10 @@ def test_macro_cond_effect(self): { # Body of B } - STACK_SHRINK(1); - STACK_GROW((oparg ? 1 : 0)); - stack_pointer[-2 - (oparg ? 1 : 0)] = deep; - if (oparg) { stack_pointer[-1 - (oparg ? 1 : 0)] = extra; } - stack_pointer[-1] = res; + stack_pointer[-3] = deep; + if (oparg) stack_pointer[-2] = extra; + stack_pointer[-2 + (((oparg) ? 1 : 0))] = res; + stack_pointer += -1 + (((oparg) ? 1 : 0)); DISPATCH(); } """ @@ -713,9 +732,9 @@ def test_macro_push_push(self): { val2 = spam(); } - STACK_GROW(2); - stack_pointer[-2] = val1; - stack_pointer[-1] = val2; + stack_pointer[0] = val1; + stack_pointer[1] = val2; + stack_pointer += 2; DISPATCH(); } """ diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index 30da2c7d4e2055..193ac7ee3c2a82 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -459,7 +459,8 @@ def analyze_forest(forest: list[parser.AstNode]) -> Analysis: if target.text in instructions: instructions[target.text].is_target = True # Hack - instructions["BINARY_OP_INPLACE_ADD_UNICODE"].family = families["BINARY_OP"] + if "BINARY_OP_INPLACE_ADD_UNICODE" in instructions: + instructions["BINARY_OP_INPLACE_ADD_UNICODE"].family = families["BINARY_OP"] return Analysis(instructions, uops, families, pseudos) diff --git a/Tools/cases_generator/generators_common.py b/Tools/cases_generator/generators_common.py index e0674a7343498d..1b565bff2c56f6 100644 --- a/Tools/cases_generator/generators_common.py +++ b/Tools/cases_generator/generators_common.py @@ -22,8 +22,10 @@ def root_relative_path(filename: str) -> str: - return Path(filename).absolute().relative_to(ROOT).as_posix() - + try: + return Path(filename).absolute().relative_to(ROOT).as_posix() + except ValueError: + return filename def write_header(generator: str, sources: list[str], outfile: TextIO) -> None: outfile.write( diff --git a/Tools/cases_generator/tier1_generator.py b/Tools/cases_generator/tier1_generator.py index f5f5c6945f5a43..49cede978d821a 100644 --- a/Tools/cases_generator/tier1_generator.py +++ b/Tools/cases_generator/tier1_generator.py @@ -182,6 +182,14 @@ def generate_tier1( "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)" ) + +def generate_tier1_from_files( + filenames: list[str], outfilename: str, lines: bool +) -> None: + data = analyze_files(filenames) + with open(outfilename, "w") as outfile: + generate_tier1(filenames, data, outfile, lines) + if __name__ == "__main__": args = arg_parser.parse_args() if len(args.input) == 0: From 2e8773b8af8109039411b1b0beaf47e8e27580c1 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 14 Dec 2023 09:22:23 +0000 Subject: [PATCH 4/6] Test new cases generator, not old one --- Lib/test/test_generated_cases.py | 114 ++++++++++++--------- Tools/cases_generator/analyzer.py | 3 +- Tools/cases_generator/cwriter.py | 15 +-- Tools/cases_generator/generators_common.py | 6 +- Tools/cases_generator/stack.py | 2 +- Tools/cases_generator/tier1_generator.py | 8 ++ 6 files changed, 88 insertions(+), 60 deletions(-) diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py index de96a8764594ba..74cebbe469d794 100644 --- a/Lib/test/test_generated_cases.py +++ b/Lib/test/test_generated_cases.py @@ -32,6 +32,7 @@ def skip_if_different_mount_drives(): import analysis import formatting from parsing import StackEffect + import tier1_generator def handle_stderr(): @@ -108,13 +109,12 @@ def run_cases_test(self, input: str, expected: str): temp_input.write(analysis.END_MARKER) temp_input.flush() - a = generate_cases.Generator([self.temp_input_filename]) with handle_stderr(): - a.parse() - a.analyze() - if a.errors: - raise RuntimeError(f"Found {a.errors} errors") - a.write_instructions(self.temp_output_filename, False) + tier1_generator.generate_tier1_from_files( + [self.temp_input_filename], + self.temp_output_filename, + False + ) with open(self.temp_output_filename) as temp_output: lines = temp_output.readlines() @@ -163,7 +163,7 @@ def test_inst_one_pop(self): PyObject *value; value = stack_pointer[-1]; spam(); - STACK_SHRINK(1); + stack_pointer += -1; DISPATCH(); } """ @@ -182,8 +182,8 @@ def test_inst_one_push(self): INSTRUCTION_STATS(OP); PyObject *res; spam(); - STACK_GROW(1); - stack_pointer[-1] = res; + stack_pointer[0] = res; + stack_pointer += 1; DISPATCH(); } """ @@ -227,8 +227,8 @@ def test_binary_op(self): right = stack_pointer[-1]; left = stack_pointer[-2]; spam(); - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } """ @@ -273,7 +273,6 @@ def test_predictions_and_eval_breaker(self): next_instr += 1; INSTRUCTION_STATS(OP1); PREDICTED(OP1); - static_assert(INLINE_CACHE_ENTRIES_OP1 == 0, "incorrect cache size"); PyObject *arg; PyObject *rest; arg = stack_pointer[-1]; @@ -285,6 +284,7 @@ def test_predictions_and_eval_breaker(self): frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(OP3); + static_assert(INLINE_CACHE_ENTRIES_OP1 == 0, "incorrect cache size"); PyObject *arg; PyObject *res; arg = stack_pointer[-1]; @@ -325,6 +325,7 @@ def test_error_if_plain_with_comment(self): next_instr += 1; INSTRUCTION_STATS(OP); if (cond) goto label; + // Comment is ok DISPATCH(); } """ @@ -347,8 +348,8 @@ def test_error_if_pop(self): right = stack_pointer[-1]; left = stack_pointer[-2]; if (cond) goto pop_2_label; - STACK_SHRINK(1); - stack_pointer[-1] = res; + stack_pointer[-2] = res; + stack_pointer += -1; DISPATCH(); } """ @@ -368,7 +369,7 @@ def test_cache_effect(self): value = stack_pointer[-1]; uint16_t counter = read_u16(&this_instr[1].cache); uint32_t extra = read_u32(&this_instr[2].cache); - STACK_SHRINK(1); + stack_pointer += -1; DISPATCH(); } """ @@ -411,26 +412,26 @@ def test_macro_instruction(self): INSTRUCTION_STATS(OP); PREDICTED(OP); _Py_CODEUNIT *this_instr = next_instr - 6; - static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size"); PyObject *right; PyObject *left; PyObject *arg2; PyObject *res; - // OP1 + // _OP1 right = stack_pointer[-1]; left = stack_pointer[-2]; { uint16_t counter = read_u16(&this_instr[1].cache); op1(left, right); } + /* Skip 2 cache entries */ // OP2 arg2 = stack_pointer[-3]; { uint32_t extra = read_u32(&this_instr[4].cache); res = op2(arg2, left, right); } - STACK_SHRINK(2); - stack_pointer[-1] = res; + stack_pointer[-3] = res; + stack_pointer += -2; DISPATCH(); } @@ -451,6 +452,7 @@ def test_macro_instruction(self): frame->instr_ptr = next_instr; next_instr += 6; INSTRUCTION_STATS(OP3); + static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size"); PyObject *right; PyObject *left; PyObject *arg2; @@ -459,8 +461,24 @@ def test_macro_instruction(self): left = stack_pointer[-2]; arg2 = stack_pointer[-3]; res = op3(arg2, left, right); - STACK_SHRINK(2); - stack_pointer[-1] = res; + stack_pointer[-3] = res; + stack_pointer += -2; + DISPATCH(); + } + """ + self.run_cases_test(input, output) + def test_unused_caches(self): + input = """ + inst(OP, (unused/1, unused/2 --)) { + body(); + } + """ + output = """ + TARGET(OP) { + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(OP); + body(); DISPATCH(); } """ @@ -519,11 +537,10 @@ def test_array_input(self): PyObject **values; PyObject *below; above = stack_pointer[-1]; - values = stack_pointer - 1 - oparg*2; + values = &stack_pointer[-1 - oparg*2]; below = stack_pointer[-2 - oparg*2]; spam(); - STACK_SHRINK(oparg*2); - STACK_SHRINK(2); + stack_pointer += -2 - oparg*2; DISPATCH(); } """ @@ -543,11 +560,11 @@ def test_array_output(self): PyObject *below; PyObject **values; PyObject *above; - values = stack_pointer - 1; + values = &stack_pointer[-1]; spam(values, oparg); - STACK_GROW(oparg*3); - stack_pointer[-2 - oparg*3] = below; - stack_pointer[-1] = above; + stack_pointer[-2] = below; + stack_pointer[-1 + oparg*3] = above; + stack_pointer += oparg*3; DISPATCH(); } """ @@ -566,10 +583,10 @@ def test_array_input_output(self): INSTRUCTION_STATS(OP); PyObject **values; PyObject *above; - values = stack_pointer - oparg; + values = &stack_pointer[-oparg]; spam(values, oparg); - STACK_GROW(1); - stack_pointer[-1] = above; + stack_pointer[0] = above; + stack_pointer += 1; DISPATCH(); } """ @@ -588,11 +605,10 @@ def test_array_error_if(self): INSTRUCTION_STATS(OP); PyObject **values; PyObject *extra; - values = stack_pointer - oparg; + values = &stack_pointer[-oparg]; extra = stack_pointer[-1 - oparg]; - if (oparg == 0) { STACK_SHRINK(oparg); goto pop_1_somewhere; } - STACK_SHRINK(oparg); - STACK_SHRINK(1); + if (oparg == 0) { stack_pointer += -1 - oparg; goto somewhere; } + stack_pointer += -1 - oparg; DISPATCH(); } """ @@ -616,14 +632,13 @@ def test_cond_effect(self): PyObject *output = NULL; PyObject *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)]; + 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, input); - STACK_SHRINK((((oparg & 1) == 1) ? 1 : 0)); - STACK_GROW(((oparg & 2) ? 1 : 0)); - stack_pointer[-2 - (oparg & 2 ? 1 : 0)] = xx; - if (oparg & 2) { stack_pointer[-1 - (oparg & 2 ? 1 : 0)] = output; } - stack_pointer[-1] = zz; + 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)); DISPATCH(); } """ @@ -661,11 +676,10 @@ def test_macro_cond_effect(self): { # Body of B } - STACK_SHRINK(1); - STACK_GROW((oparg ? 1 : 0)); - stack_pointer[-2 - (oparg ? 1 : 0)] = deep; - if (oparg) { stack_pointer[-1 - (oparg ? 1 : 0)] = extra; } - stack_pointer[-1] = res; + stack_pointer[-3] = deep; + if (oparg) stack_pointer[-2] = extra; + stack_pointer[-2 + (((oparg) ? 1 : 0))] = res; + stack_pointer += -1 + (((oparg) ? 1 : 0)); DISPATCH(); } """ @@ -696,9 +710,9 @@ def test_macro_push_push(self): { val2 = spam(); } - STACK_GROW(2); - stack_pointer[-2] = val1; - stack_pointer[-1] = val2; + stack_pointer[0] = val1; + stack_pointer[1] = val2; + stack_pointer += 2; DISPATCH(); } """ diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index bcc13538e51d9b..2147f6f25b8a6f 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -444,7 +444,8 @@ def analyze_forest(forest: list[parser.AstNode]) -> Analysis: if target.text in instructions: instructions[target.text].is_target = True # Hack - instructions["BINARY_OP_INPLACE_ADD_UNICODE"].family = families["BINARY_OP"] + if "BINARY_OP_INPLACE_ADD_UNICODE" in instructions: + instructions["BINARY_OP_INPLACE_ADD_UNICODE"].family = families["BINARY_OP"] return Analysis(instructions, uops, families, pseudos) diff --git a/Tools/cases_generator/cwriter.py b/Tools/cases_generator/cwriter.py index 34e39855a9b40a..67b1c9a169024c 100644 --- a/Tools/cases_generator/cwriter.py +++ b/Tools/cases_generator/cwriter.py @@ -38,7 +38,8 @@ def maybe_dedent(self, txt: str) -> None: parens = txt.count("(") - txt.count(")") if parens < 0: self.indents.pop() - elif "}" in txt or is_label(txt): + braces = txt.count("{") - txt.count("}") + if braces < 0 or is_label(txt): self.indents.pop() def maybe_indent(self, txt: str) -> None: @@ -50,11 +51,13 @@ def maybe_indent(self, txt: str) -> None: self.indents.append(offset) if is_label(txt): self.indents.append(self.indents[-1] + 4) - elif "{" in txt: - if 'extern "C"' in txt: - self.indents.append(self.indents[-1]) - else: - self.indents.append(self.indents[-1] + 4) + else: + braces = txt.count("{") - txt.count("}") + if braces > 0: + if 'extern "C"' in txt: + self.indents.append(self.indents[-1]) + else: + self.indents.append(self.indents[-1] + 4) def emit_text(self, txt: str) -> None: self.out.write(txt) diff --git a/Tools/cases_generator/generators_common.py b/Tools/cases_generator/generators_common.py index e0674a7343498d..1b565bff2c56f6 100644 --- a/Tools/cases_generator/generators_common.py +++ b/Tools/cases_generator/generators_common.py @@ -22,8 +22,10 @@ def root_relative_path(filename: str) -> str: - return Path(filename).absolute().relative_to(ROOT).as_posix() - + try: + return Path(filename).absolute().relative_to(ROOT).as_posix() + except ValueError: + return filename def write_header(generator: str, sources: list[str], outfile: TextIO) -> None: outfile.write( diff --git a/Tools/cases_generator/stack.py b/Tools/cases_generator/stack.py index c36a56ebf2d381..0b31ce4090f552 100644 --- a/Tools/cases_generator/stack.py +++ b/Tools/cases_generator/stack.py @@ -148,7 +148,7 @@ def flush(self, out: CWriter) -> None: cast = "(PyObject *)" if var.type else "" if var.name != "unused" and not var.is_array(): if var.condition: - out.emit(f" if ({var.condition}) ") + out.emit(f"if ({var.condition}) ") out.emit( f"stack_pointer[{self.base_offset.to_c()}] = {cast}{var.name};\n" ) diff --git a/Tools/cases_generator/tier1_generator.py b/Tools/cases_generator/tier1_generator.py index 11885dca6fe1a2..bcfd2d88ecd734 100644 --- a/Tools/cases_generator/tier1_generator.py +++ b/Tools/cases_generator/tier1_generator.py @@ -181,6 +181,14 @@ def generate_tier1( "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)" ) + +def generate_tier1_from_files( + filenames: list[str], outfilename: str, lines: bool +) -> None: + data = analyze_files(filenames) + with open(outfilename, "w") as outfile: + generate_tier1(filenames, data, outfile, lines) + if __name__ == "__main__": args = arg_parser.parse_args() if len(args.input) == 0: From ef7746f9b84f319f4024b51f5715acaaec85830b Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 14 Dec 2023 09:43:09 +0000 Subject: [PATCH 5/6] Update generated files --- Python/executor_cases.c.h | 26 +++++++++++++------------- Python/generated_cases.c.h | 30 +++++++++++++++--------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 7cb60cbc1dd3ff..7cc29c8e644d8d 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1126,7 +1126,7 @@ } null = NULL; stack_pointer[0] = res; - if (oparg & 1) stack_pointer[1] = null; + if (oparg & 1) stack_pointer[1] = null; stack_pointer += 1 + ((oparg & 1)); break; } @@ -1162,7 +1162,7 @@ STAT_INC(LOAD_GLOBAL, hit); null = NULL; stack_pointer[0] = res; - if (oparg & 1) stack_pointer[1] = null; + if (oparg & 1) stack_pointer[1] = null; stack_pointer += 1 + ((oparg & 1)); break; } @@ -1180,7 +1180,7 @@ STAT_INC(LOAD_GLOBAL, hit); null = NULL; stack_pointer[0] = res; - if (oparg & 1) stack_pointer[1] = null; + if (oparg & 1) stack_pointer[1] = null; stack_pointer += 1 + ((oparg & 1)); break; } @@ -1612,7 +1612,7 @@ if (attr == NULL) goto pop_1_error_tier_two; } stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = self_or_null; + if (oparg & 1) stack_pointer[0] = self_or_null; stack_pointer += ((oparg & 1)); break; } @@ -1652,7 +1652,7 @@ null = NULL; Py_DECREF(owner); stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = null; + if (oparg & 1) stack_pointer[0] = null; stack_pointer += ((oparg & 1)); break; } @@ -1686,7 +1686,7 @@ null = NULL; Py_DECREF(owner); stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = null; + if (oparg & 1) stack_pointer[0] = null; stack_pointer += ((oparg & 1)); break; } @@ -1730,7 +1730,7 @@ null = NULL; Py_DECREF(owner); stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = null; + if (oparg & 1) stack_pointer[0] = null; stack_pointer += ((oparg & 1)); break; } @@ -1750,7 +1750,7 @@ null = NULL; Py_DECREF(owner); stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = null; + if (oparg & 1) stack_pointer[0] = null; stack_pointer += ((oparg & 1)); break; } @@ -1778,7 +1778,7 @@ null = NULL; Py_DECREF(owner); stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = null; + if (oparg & 1) stack_pointer[0] = null; stack_pointer += ((oparg & 1)); break; } @@ -2467,7 +2467,7 @@ assert(_PyType_HasFeature(Py_TYPE(attr), Py_TPFLAGS_METHOD_DESCRIPTOR)); self = owner; stack_pointer[-1] = attr; - if (1) stack_pointer[0] = self; + if (1) stack_pointer[0] = self; stack_pointer += (((1) ? 1 : 0)); break; } @@ -2487,7 +2487,7 @@ attr = Py_NewRef(descr); self = owner; stack_pointer[-1] = attr; - if (1) stack_pointer[0] = self; + if (1) stack_pointer[0] = self; stack_pointer += (((1) ? 1 : 0)); break; } @@ -2550,7 +2550,7 @@ attr = Py_NewRef(descr); self = owner; stack_pointer[-1] = attr; - if (1) stack_pointer[0] = self; + if (1) stack_pointer[0] = self; stack_pointer += (((1) ? 1 : 0)); break; } @@ -3199,7 +3199,7 @@ PyObject *start; PyObject *slice; oparg = CURRENT_OPARG(); - if (oparg == 3) { step = stack_pointer[-(((oparg == 3) ? 1 : 0))]; } + if (oparg == 3) { step = stack_pointer[-(((oparg == 3) ? 1 : 0))]; } stop = stack_pointer[-1 - (((oparg == 3) ? 1 : 0))]; start = stack_pointer[-2 - (((oparg == 3) ? 1 : 0))]; slice = PySlice_New(start, stop, step); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 24f26722d7a745..b202d141b36f4f 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -678,7 +678,7 @@ PyObject *stop; PyObject *start; PyObject *slice; - if (oparg == 3) { step = stack_pointer[-(((oparg == 3) ? 1 : 0))]; } + if (oparg == 3) { step = stack_pointer[-(((oparg == 3) ? 1 : 0))]; } stop = stack_pointer[-1 - (((oparg == 3) ? 1 : 0))]; start = stack_pointer[-2 - (((oparg == 3) ? 1 : 0))]; slice = PySlice_New(start, stop, step); @@ -1161,7 +1161,7 @@ PyObject *callargs; PyObject *func; PyObject *result; - if (oparg & 1) { kwargs = stack_pointer[-((oparg & 1))]; } + if (oparg & 1) { kwargs = stack_pointer[-((oparg & 1))]; } callargs = stack_pointer[-1 - ((oparg & 1))]; func = stack_pointer[-3 - ((oparg & 1))]; // DICT_MERGE is called before this opcode if there are kwargs. @@ -3385,7 +3385,7 @@ } } stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = self_or_null; + if (oparg & 1) stack_pointer[0] = self_or_null; stack_pointer += ((oparg & 1)); DISPATCH(); } @@ -3418,7 +3418,7 @@ Py_DECREF(owner); } stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = null; + if (oparg & 1) stack_pointer[0] = null; stack_pointer += ((oparg & 1)); DISPATCH(); } @@ -3494,7 +3494,7 @@ } /* Skip 5 cache entries */ stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = null; + if (oparg & 1) stack_pointer[0] = null; stack_pointer += ((oparg & 1)); DISPATCH(); } @@ -3536,7 +3536,7 @@ self = owner; } stack_pointer[-1] = attr; - if (1) stack_pointer[0] = self; + if (1) stack_pointer[0] = self; stack_pointer += (((1) ? 1 : 0)); DISPATCH(); } @@ -3571,7 +3571,7 @@ self = owner; } stack_pointer[-1] = attr; - if (1) stack_pointer[0] = self; + if (1) stack_pointer[0] = self; stack_pointer += (((1) ? 1 : 0)); DISPATCH(); } @@ -3618,7 +3618,7 @@ self = owner; } stack_pointer[-1] = attr; - if (1) stack_pointer[0] = self; + if (1) stack_pointer[0] = self; stack_pointer += (((1) ? 1 : 0)); DISPATCH(); } @@ -3657,7 +3657,7 @@ } /* Skip 5 cache entries */ stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = null; + if (oparg & 1) stack_pointer[0] = null; stack_pointer += ((oparg & 1)); DISPATCH(); } @@ -3799,7 +3799,7 @@ } /* Skip 5 cache entries */ stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = null; + if (oparg & 1) stack_pointer[0] = null; stack_pointer += ((oparg & 1)); DISPATCH(); } @@ -3855,7 +3855,7 @@ } /* Skip 5 cache entries */ stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = null; + if (oparg & 1) stack_pointer[0] = null; stack_pointer += ((oparg & 1)); DISPATCH(); } @@ -4083,7 +4083,7 @@ null = NULL; } stack_pointer[0] = res; - if (oparg & 1) stack_pointer[1] = null; + if (oparg & 1) stack_pointer[1] = null; stack_pointer += 1 + ((oparg & 1)); DISPATCH(); } @@ -4124,7 +4124,7 @@ null = NULL; } stack_pointer[0] = res; - if (oparg & 1) stack_pointer[1] = null; + if (oparg & 1) stack_pointer[1] = null; stack_pointer += 1 + ((oparg & 1)); DISPATCH(); } @@ -4158,7 +4158,7 @@ null = NULL; } stack_pointer[0] = res; - if (oparg & 1) stack_pointer[1] = null; + if (oparg & 1) stack_pointer[1] = null; stack_pointer += 1 + ((oparg & 1)); DISPATCH(); } @@ -4286,7 +4286,7 @@ null = NULL; } stack_pointer[-3] = attr; - if (oparg & 1) stack_pointer[-2] = null; + if (oparg & 1) stack_pointer[-2] = null; stack_pointer += -2 + ((oparg & 1)); DISPATCH(); } From 97973dbe591cd72d1c5615810f9f86707d7ecf17 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 14 Dec 2023 10:23:56 +0000 Subject: [PATCH 6/6] Add comments --- Tools/cases_generator/analyzer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index 193ac7ee3c2a82..e077eb0a8ed203 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -350,6 +350,7 @@ def desugar_inst( op_inputs: list[parser.InputEffect] = [] parts: list[Part] = [] uop_index = -1 + # Move unused cache entries to the Instruction, removing them from the Uop. for input in inst.inputs: if isinstance(input, parser.CacheEffect) and input.name == "unused": parts.append(Skip(input.size)) @@ -357,6 +358,7 @@ def desugar_inst( op_inputs.append(input) if uop_index < 0: uop_index = len(parts) + # Place holder for the uop. parts.append(Skip(0)) uop = make_uop("_" + inst.name, inst, op_inputs) uop.implicitly_created = True