Skip to content

Commit c535a13

Browse files
authored
GH-131498: Another refactoring of the code generator (GH-131827)
* Rename 'defined' attribute to 'in_local' to more accurately reflect how it is used * Make death of variables explicit even for array variables. * Convert in_memory from boolean to stack offset * Don't apply liveness analyis to optimizer generated code * Add 'out' parameter to stack.pop
1 parent ba11f45 commit c535a13

11 files changed

+204
-210
lines changed

Lib/test/test_generated_cases.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,15 @@ def test_effect_sizes(self):
6868
StackItem("b", None, "oparg*4"),
6969
StackItem("c", None, "1"),
7070
]
71-
stack.pop(z)
72-
stack.pop(y)
73-
stack.pop(x)
71+
null = CWriter.null()
72+
stack.pop(z, null)
73+
stack.pop(y, null)
74+
stack.pop(x, null)
7475
for out in outputs:
7576
stack.push(Local.undefined(out))
7677
self.assertEqual(stack.base_offset.to_c(), "-1 - oparg - oparg*2")
77-
self.assertEqual(stack.top_offset.to_c(), "1 - oparg - oparg*2 + oparg*4")
78+
self.assertEqual(stack.physical_sp.to_c(), "0")
79+
self.assertEqual(stack.logical_sp.to_c(), "1 - oparg - oparg*2 + oparg*4")
7880

7981

8082
class TestGeneratedCases(unittest.TestCase):

Python/bytecodes.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1484,7 +1484,7 @@ dummy_func(
14841484
(void)counter;
14851485
}
14861486

1487-
op(_UNPACK_SEQUENCE, (seq -- output[oparg], top[0])) {
1487+
op(_UNPACK_SEQUENCE, (seq -- unused[oparg], top[0])) {
14881488
PyObject *seq_o = PyStackRef_AsPyObjectSteal(seq);
14891489
int res = _PyEval_UnpackIterableStackRef(tstate, seq_o, oparg, -1, top);
14901490
Py_DECREF(seq_o);
@@ -1533,7 +1533,7 @@ dummy_func(
15331533
DECREF_INPUTS();
15341534
}
15351535

1536-
inst(UNPACK_EX, (seq -- left[oparg & 0xFF], unused, right[oparg >> 8], top[0])) {
1536+
inst(UNPACK_EX, (seq -- unused[oparg & 0xFF], unused, unused[oparg >> 8], top[0])) {
15371537
PyObject *seq_o = PyStackRef_AsPyObjectSteal(seq);
15381538
int res = _PyEval_UnpackIterableStackRef(tstate, seq_o, oparg & 0xFF, oparg >> 8, top);
15391539
Py_DECREF(seq_o);

Python/generated_cases.c.h

+5-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/cwriter.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import contextlib
22
from lexer import Token
33
from typing import TextIO, Iterator
4-
4+
from io import StringIO
55

66
class CWriter:
77
"A writer that understands tokens and how to format C code"
@@ -18,6 +18,10 @@ def __init__(self, out: TextIO, indent: int, line_directives: bool):
1818
self.pending_spill = False
1919
self.pending_reload = False
2020

21+
@staticmethod
22+
def null() -> "CWriter":
23+
return CWriter(StringIO(), 0, False)
24+
2125
def set_position(self, tkn: Token) -> None:
2226
if self.last_token is not None:
2327
if self.last_token.end_line < tkn.line:

Tools/cases_generator/generators_common.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,9 @@ def error_if(
205205
next(tkn_iter) # Semi colon
206206
storage.clear_inputs("at ERROR_IF")
207207

208-
c_offset = storage.stack.peek_offset()
208+
c_offset = storage.stack.sp_offset()
209209
try:
210-
offset = -int(c_offset)
210+
offset = int(c_offset)
211211
except ValueError:
212212
offset = -1
213213
self.out.emit(self.goto_error(offset, label, storage))

Tools/cases_generator/opcode_metadata_generator.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def generate_stack_effect_functions(analysis: Analysis, out: CWriter) -> None:
100100
def add(inst: Instruction | PseudoInstruction) -> None:
101101
stack = get_stack_effect(inst)
102102
popped = (-stack.base_offset).to_c()
103-
pushed = (stack.top_offset - stack.base_offset).to_c()
103+
pushed = (stack.logical_sp - stack.base_offset).to_c()
104104
popped_data.append((inst.name, popped))
105105
pushed_data.append((inst.name, pushed))
106106

Tools/cases_generator/optimizer_generator.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,15 @@ def decref_inputs(
7272

7373

7474
def emit_default(out: CWriter, uop: Uop, stack: Stack) -> None:
75+
null = CWriter.null()
7576
for var in reversed(uop.stack.inputs):
76-
stack.pop(var)
77-
top_offset = stack.top_offset.copy()
77+
stack.pop(var, null)
78+
offset = stack.base_offset - stack.physical_sp
7879
for var in uop.stack.outputs:
7980
if var.is_array() and not var.peek and not var.name == "unused":
80-
c_offset = top_offset.to_c()
81+
c_offset = offset.to_c()
8182
out.emit(f"{var.name} = &stack_pointer[{c_offset}];\n")
82-
top_offset.push(var)
83+
offset = offset.push(var)
8384
for var in uop.stack.outputs:
8485
local = Local.undefined(var)
8586
stack.push(local)
@@ -123,9 +124,7 @@ def write_uop(
123124
try:
124125
out.start_line()
125126
if override:
126-
code_list, storage = Storage.for_uop(stack, prototype, check_liveness=False)
127-
for code in code_list:
128-
out.emit(code)
127+
storage = Storage.for_uop(stack, prototype, out, check_liveness=False)
129128
if debug:
130129
args = []
131130
for input in prototype.stack.inputs:

0 commit comments

Comments
 (0)