GH-111485: Test the new cases generator (GH-113252)
This commit is contained in:
parent
4a24bf9a13
commit
771903596b
@ -32,6 +32,7 @@ with test_tools.imports_under_tool('cases_generator'):
|
|||||||
import analysis
|
import analysis
|
||||||
import formatting
|
import formatting
|
||||||
from parsing import StackEffect
|
from parsing import StackEffect
|
||||||
|
import tier1_generator
|
||||||
|
|
||||||
|
|
||||||
def handle_stderr():
|
def handle_stderr():
|
||||||
@ -108,13 +109,12 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
temp_input.write(analysis.END_MARKER)
|
temp_input.write(analysis.END_MARKER)
|
||||||
temp_input.flush()
|
temp_input.flush()
|
||||||
|
|
||||||
a = generate_cases.Generator([self.temp_input_filename])
|
|
||||||
with handle_stderr():
|
with handle_stderr():
|
||||||
a.parse()
|
tier1_generator.generate_tier1_from_files(
|
||||||
a.analyze()
|
[self.temp_input_filename],
|
||||||
if a.errors:
|
self.temp_output_filename,
|
||||||
raise RuntimeError(f"Found {a.errors} errors")
|
False
|
||||||
a.write_instructions(self.temp_output_filename, False)
|
)
|
||||||
|
|
||||||
with open(self.temp_output_filename) as temp_output:
|
with open(self.temp_output_filename) as temp_output:
|
||||||
lines = temp_output.readlines()
|
lines = temp_output.readlines()
|
||||||
@ -163,7 +163,7 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
PyObject *value;
|
PyObject *value;
|
||||||
value = stack_pointer[-1];
|
value = stack_pointer[-1];
|
||||||
spam();
|
spam();
|
||||||
STACK_SHRINK(1);
|
stack_pointer += -1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -182,8 +182,8 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
INSTRUCTION_STATS(OP);
|
INSTRUCTION_STATS(OP);
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
spam();
|
spam();
|
||||||
STACK_GROW(1);
|
stack_pointer[0] = res;
|
||||||
stack_pointer[-1] = res;
|
stack_pointer += 1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -227,8 +227,8 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
right = stack_pointer[-1];
|
right = stack_pointer[-1];
|
||||||
left = stack_pointer[-2];
|
left = stack_pointer[-2];
|
||||||
spam();
|
spam();
|
||||||
STACK_SHRINK(1);
|
stack_pointer[-2] = res;
|
||||||
stack_pointer[-1] = res;
|
stack_pointer += -1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -273,7 +273,6 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
next_instr += 1;
|
next_instr += 1;
|
||||||
INSTRUCTION_STATS(OP1);
|
INSTRUCTION_STATS(OP1);
|
||||||
PREDICTED(OP1);
|
PREDICTED(OP1);
|
||||||
static_assert(INLINE_CACHE_ENTRIES_OP1 == 0, "incorrect cache size");
|
|
||||||
PyObject *arg;
|
PyObject *arg;
|
||||||
PyObject *rest;
|
PyObject *rest;
|
||||||
arg = stack_pointer[-1];
|
arg = stack_pointer[-1];
|
||||||
@ -285,6 +284,7 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
frame->instr_ptr = next_instr;
|
frame->instr_ptr = next_instr;
|
||||||
next_instr += 1;
|
next_instr += 1;
|
||||||
INSTRUCTION_STATS(OP3);
|
INSTRUCTION_STATS(OP3);
|
||||||
|
static_assert(INLINE_CACHE_ENTRIES_OP1 == 0, "incorrect cache size");
|
||||||
PyObject *arg;
|
PyObject *arg;
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
arg = stack_pointer[-1];
|
arg = stack_pointer[-1];
|
||||||
@ -325,6 +325,7 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
next_instr += 1;
|
next_instr += 1;
|
||||||
INSTRUCTION_STATS(OP);
|
INSTRUCTION_STATS(OP);
|
||||||
if (cond) goto label;
|
if (cond) goto label;
|
||||||
|
// Comment is ok
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -347,8 +348,8 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
right = stack_pointer[-1];
|
right = stack_pointer[-1];
|
||||||
left = stack_pointer[-2];
|
left = stack_pointer[-2];
|
||||||
if (cond) goto pop_2_label;
|
if (cond) goto pop_2_label;
|
||||||
STACK_SHRINK(1);
|
stack_pointer[-2] = res;
|
||||||
stack_pointer[-1] = res;
|
stack_pointer += -1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -368,7 +369,7 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
value = stack_pointer[-1];
|
value = stack_pointer[-1];
|
||||||
uint16_t counter = read_u16(&this_instr[1].cache);
|
uint16_t counter = read_u16(&this_instr[1].cache);
|
||||||
uint32_t extra = read_u32(&this_instr[2].cache);
|
uint32_t extra = read_u32(&this_instr[2].cache);
|
||||||
STACK_SHRINK(1);
|
stack_pointer += -1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -411,26 +412,26 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
INSTRUCTION_STATS(OP);
|
INSTRUCTION_STATS(OP);
|
||||||
PREDICTED(OP);
|
PREDICTED(OP);
|
||||||
_Py_CODEUNIT *this_instr = next_instr - 6;
|
_Py_CODEUNIT *this_instr = next_instr - 6;
|
||||||
static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size");
|
|
||||||
PyObject *right;
|
PyObject *right;
|
||||||
PyObject *left;
|
PyObject *left;
|
||||||
PyObject *arg2;
|
PyObject *arg2;
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
// OP1
|
// _OP1
|
||||||
right = stack_pointer[-1];
|
right = stack_pointer[-1];
|
||||||
left = stack_pointer[-2];
|
left = stack_pointer[-2];
|
||||||
{
|
{
|
||||||
uint16_t counter = read_u16(&this_instr[1].cache);
|
uint16_t counter = read_u16(&this_instr[1].cache);
|
||||||
op1(left, right);
|
op1(left, right);
|
||||||
}
|
}
|
||||||
|
/* Skip 2 cache entries */
|
||||||
// OP2
|
// OP2
|
||||||
arg2 = stack_pointer[-3];
|
arg2 = stack_pointer[-3];
|
||||||
{
|
{
|
||||||
uint32_t extra = read_u32(&this_instr[4].cache);
|
uint32_t extra = read_u32(&this_instr[4].cache);
|
||||||
res = op2(arg2, left, right);
|
res = op2(arg2, left, right);
|
||||||
}
|
}
|
||||||
STACK_SHRINK(2);
|
stack_pointer[-3] = res;
|
||||||
stack_pointer[-1] = res;
|
stack_pointer += -2;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,6 +452,7 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
frame->instr_ptr = next_instr;
|
frame->instr_ptr = next_instr;
|
||||||
next_instr += 6;
|
next_instr += 6;
|
||||||
INSTRUCTION_STATS(OP3);
|
INSTRUCTION_STATS(OP3);
|
||||||
|
static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size");
|
||||||
PyObject *right;
|
PyObject *right;
|
||||||
PyObject *left;
|
PyObject *left;
|
||||||
PyObject *arg2;
|
PyObject *arg2;
|
||||||
@ -459,8 +461,24 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
left = stack_pointer[-2];
|
left = stack_pointer[-2];
|
||||||
arg2 = stack_pointer[-3];
|
arg2 = stack_pointer[-3];
|
||||||
res = op3(arg2, left, right);
|
res = op3(arg2, left, right);
|
||||||
STACK_SHRINK(2);
|
stack_pointer[-3] = res;
|
||||||
stack_pointer[-1] = 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();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -519,11 +537,10 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
PyObject **values;
|
PyObject **values;
|
||||||
PyObject *below;
|
PyObject *below;
|
||||||
above = stack_pointer[-1];
|
above = stack_pointer[-1];
|
||||||
values = stack_pointer - 1 - oparg*2;
|
values = &stack_pointer[-1 - oparg*2];
|
||||||
below = stack_pointer[-2 - oparg*2];
|
below = stack_pointer[-2 - oparg*2];
|
||||||
spam();
|
spam();
|
||||||
STACK_SHRINK(oparg*2);
|
stack_pointer += -2 - oparg*2;
|
||||||
STACK_SHRINK(2);
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -543,11 +560,11 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
PyObject *below;
|
PyObject *below;
|
||||||
PyObject **values;
|
PyObject **values;
|
||||||
PyObject *above;
|
PyObject *above;
|
||||||
values = stack_pointer - 1;
|
values = &stack_pointer[-1];
|
||||||
spam(values, oparg);
|
spam(values, oparg);
|
||||||
STACK_GROW(oparg*3);
|
stack_pointer[-2] = below;
|
||||||
stack_pointer[-2 - oparg*3] = below;
|
stack_pointer[-1 + oparg*3] = above;
|
||||||
stack_pointer[-1] = above;
|
stack_pointer += oparg*3;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -566,10 +583,10 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
INSTRUCTION_STATS(OP);
|
INSTRUCTION_STATS(OP);
|
||||||
PyObject **values;
|
PyObject **values;
|
||||||
PyObject *above;
|
PyObject *above;
|
||||||
values = stack_pointer - oparg;
|
values = &stack_pointer[-oparg];
|
||||||
spam(values, oparg);
|
spam(values, oparg);
|
||||||
STACK_GROW(1);
|
stack_pointer[0] = above;
|
||||||
stack_pointer[-1] = above;
|
stack_pointer += 1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -588,11 +605,10 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
INSTRUCTION_STATS(OP);
|
INSTRUCTION_STATS(OP);
|
||||||
PyObject **values;
|
PyObject **values;
|
||||||
PyObject *extra;
|
PyObject *extra;
|
||||||
values = stack_pointer - oparg;
|
values = &stack_pointer[-oparg];
|
||||||
extra = stack_pointer[-1 - oparg];
|
extra = stack_pointer[-1 - oparg];
|
||||||
if (oparg == 0) { STACK_SHRINK(oparg); goto pop_1_somewhere; }
|
if (oparg == 0) { stack_pointer += -1 - oparg; goto somewhere; }
|
||||||
STACK_SHRINK(oparg);
|
stack_pointer += -1 - oparg;
|
||||||
STACK_SHRINK(1);
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -616,14 +632,13 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
PyObject *output = NULL;
|
PyObject *output = NULL;
|
||||||
PyObject *zz;
|
PyObject *zz;
|
||||||
cc = stack_pointer[-1];
|
cc = stack_pointer[-1];
|
||||||
if ((oparg & 1) == 1) { input = stack_pointer[-1 - ((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)];
|
aa = stack_pointer[-2 - ((((oparg & 1) == 1) ? 1 : 0))];
|
||||||
output = spam(oparg, input);
|
output = spam(oparg, input);
|
||||||
STACK_SHRINK((((oparg & 1) == 1) ? 1 : 0));
|
stack_pointer[-2 - ((((oparg & 1) == 1) ? 1 : 0))] = xx;
|
||||||
STACK_GROW(((oparg & 2) ? 1 : 0));
|
if (oparg & 2) stack_pointer[-1 - ((((oparg & 1) == 1) ? 1 : 0))] = output;
|
||||||
stack_pointer[-2 - (oparg & 2 ? 1 : 0)] = xx;
|
stack_pointer[-1 - ((((oparg & 1) == 1) ? 1 : 0)) + (((oparg & 2) ? 1 : 0))] = zz;
|
||||||
if (oparg & 2) { stack_pointer[-1 - (oparg & 2 ? 1 : 0)] = output; }
|
stack_pointer += -((((oparg & 1) == 1) ? 1 : 0)) + (((oparg & 2) ? 1 : 0));
|
||||||
stack_pointer[-1] = zz;
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -661,11 +676,10 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
{
|
{
|
||||||
# Body of B
|
# Body of B
|
||||||
}
|
}
|
||||||
STACK_SHRINK(1);
|
stack_pointer[-3] = deep;
|
||||||
STACK_GROW((oparg ? 1 : 0));
|
if (oparg) stack_pointer[-2] = extra;
|
||||||
stack_pointer[-2 - (oparg ? 1 : 0)] = deep;
|
stack_pointer[-2 + (((oparg) ? 1 : 0))] = res;
|
||||||
if (oparg) { stack_pointer[-1 - (oparg ? 1 : 0)] = extra; }
|
stack_pointer += -1 + (((oparg) ? 1 : 0));
|
||||||
stack_pointer[-1] = res;
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -696,9 +710,9 @@ class TestGeneratedCases(unittest.TestCase):
|
|||||||
{
|
{
|
||||||
val2 = spam();
|
val2 = spam();
|
||||||
}
|
}
|
||||||
STACK_GROW(2);
|
stack_pointer[0] = val1;
|
||||||
stack_pointer[-2] = val1;
|
stack_pointer[1] = val2;
|
||||||
stack_pointer[-1] = val2;
|
stack_pointer += 2;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
@ -444,6 +444,7 @@ def analyze_forest(forest: list[parser.AstNode]) -> Analysis:
|
|||||||
if target.text in instructions:
|
if target.text in instructions:
|
||||||
instructions[target.text].is_target = True
|
instructions[target.text].is_target = True
|
||||||
# Hack
|
# Hack
|
||||||
|
if "BINARY_OP_INPLACE_ADD_UNICODE" in instructions:
|
||||||
instructions["BINARY_OP_INPLACE_ADD_UNICODE"].family = families["BINARY_OP"]
|
instructions["BINARY_OP_INPLACE_ADD_UNICODE"].family = families["BINARY_OP"]
|
||||||
return Analysis(instructions, uops, families, pseudos)
|
return Analysis(instructions, uops, families, pseudos)
|
||||||
|
|
||||||
|
@ -38,7 +38,8 @@ class CWriter:
|
|||||||
parens = txt.count("(") - txt.count(")")
|
parens = txt.count("(") - txt.count(")")
|
||||||
if parens < 0:
|
if parens < 0:
|
||||||
self.indents.pop()
|
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()
|
self.indents.pop()
|
||||||
|
|
||||||
def maybe_indent(self, txt: str) -> None:
|
def maybe_indent(self, txt: str) -> None:
|
||||||
@ -50,7 +51,9 @@ class CWriter:
|
|||||||
self.indents.append(offset)
|
self.indents.append(offset)
|
||||||
if is_label(txt):
|
if is_label(txt):
|
||||||
self.indents.append(self.indents[-1] + 4)
|
self.indents.append(self.indents[-1] + 4)
|
||||||
elif "{" in txt:
|
else:
|
||||||
|
braces = txt.count("{") - txt.count("}")
|
||||||
|
if braces > 0:
|
||||||
if 'extern "C"' in txt:
|
if 'extern "C"' in txt:
|
||||||
self.indents.append(self.indents[-1])
|
self.indents.append(self.indents[-1])
|
||||||
else:
|
else:
|
||||||
|
@ -22,8 +22,10 @@ DEFAULT_INPUT = (ROOT / "Python/bytecodes.c").absolute().as_posix()
|
|||||||
|
|
||||||
|
|
||||||
def root_relative_path(filename: str) -> str:
|
def root_relative_path(filename: str) -> str:
|
||||||
|
try:
|
||||||
return Path(filename).absolute().relative_to(ROOT).as_posix()
|
return Path(filename).absolute().relative_to(ROOT).as_posix()
|
||||||
|
except ValueError:
|
||||||
|
return filename
|
||||||
|
|
||||||
def write_header(generator: str, sources: list[str], outfile: TextIO) -> None:
|
def write_header(generator: str, sources: list[str], outfile: TextIO) -> None:
|
||||||
outfile.write(
|
outfile.write(
|
||||||
|
@ -181,6 +181,14 @@ arg_parser.add_argument(
|
|||||||
"input", nargs=argparse.REMAINDER, help="Instruction definition file(s)"
|
"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__":
|
if __name__ == "__main__":
|
||||||
args = arg_parser.parse_args()
|
args = arg_parser.parse_args()
|
||||||
if len(args.input) == 0:
|
if len(args.input) == 0:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user