summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_generated_cases.py114
-rw-r--r--Python/executor_cases.c.h26
-rw-r--r--Python/generated_cases.c.h30
-rw-r--r--Tools/cases_generator/analyzer.py3
-rw-r--r--Tools/cases_generator/cwriter.py15
-rw-r--r--Tools/cases_generator/generators_common.py6
-rw-r--r--Tools/cases_generator/stack.py2
-rw-r--r--Tools/cases_generator/tier1_generator.py8
8 files changed, 116 insertions, 88 deletions
diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py
index de96a87..74cebbe 100644
--- a/Lib/test/test_generated_cases.py
+++ b/Lib/test/test_generated_cases.py
@@ -32,6 +32,7 @@ with test_tools.imports_under_tool('cases_generator'):
import analysis
import formatting
from parsing import StackEffect
+ import tier1_generator
def handle_stderr():
@@ -108,13 +109,12 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
PyObject *value;
value = stack_pointer[-1];
spam();
- STACK_SHRINK(1);
+ stack_pointer += -1;
DISPATCH();
}
"""
@@ -182,8 +182,8 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
next_instr += 1;
INSTRUCTION_STATS(OP);
if (cond) goto label;
+ // Comment is ok
DISPATCH();
}
"""
@@ -347,8 +348,8 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
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 @@ class TestGeneratedCases(unittest.TestCase):
{
# 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 @@ class TestGeneratedCases(unittest.TestCase):
{
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/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 7cb60cb..7cc29c8 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 24f2672..b202d14 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();
}
diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py
index bcc1353..2147f6f 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 34e3985..67b1c9a 100644
--- a/Tools/cases_generator/cwriter.py
+++ b/Tools/cases_generator/cwriter.py
@@ -38,7 +38,8 @@ class CWriter:
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 @@ class CWriter:
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 e0674a7..1b565bf 100644
--- a/Tools/cases_generator/generators_common.py
+++ b/Tools/cases_generator/generators_common.py
@@ -22,8 +22,10 @@ DEFAULT_INPUT = (ROOT / "Python/bytecodes.c").absolute().as_posix()
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 c36a56e..0b31ce4 100644
--- a/Tools/cases_generator/stack.py
+++ b/Tools/cases_generator/stack.py
@@ -148,7 +148,7 @@ class Stack:
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 11885dc..bcfd2d8 100644
--- a/Tools/cases_generator/tier1_generator.py
+++ b/Tools/cases_generator/tier1_generator.py
@@ -181,6 +181,14 @@ arg_parser.add_argument(
"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: