Skip to content

Commit 479ca70

Browse files
committed
Remove 'outputs' from Stack
1 parent b8c83c2 commit 479ca70

File tree

6 files changed

+40
-37
lines changed

6 files changed

+40
-37
lines changed

Tools/cases_generator/analyzer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ def find_assignment_target(idx: int) -> list[lexer.Token]:
370370
if tkn.kind != "IDENTIFIER" or tkn.text != "PyStackRef_FromPyObjectNew":
371371
continue
372372

373-
if node.block.tokens[idx-1].kind != "EQUALS":
373+
if idx == 0 or node.block.tokens[idx-1].kind != "EQUALS":
374374
raise analysis_error("Expected '=' before PyStackRef_FromPyObjectNew", tkn)
375375

376376
lhs = find_assignment_target(idx)

Tools/cases_generator/generators_common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ def py_stack_ref_from_py_object_new(
225225
# Flush the assignment to the stack. Note that we don't flush the
226226
# stack pointer here, and instead are currently relying on initializing
227227
# unused portions of the stack to NULL.
228-
stack.flush_single_var(self.out, target)
228+
stack.flush_single_var(self.out, target, uop.stack.outputs)
229229

230230

231231
def emit_tokens(

Tools/cases_generator/optimizer_generator.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,7 @@ def write_uop(
112112
out.emit(code)
113113
if local.defined:
114114
locals[local.name] = local
115-
outputs: list[Local] = []
116-
for var in prototype.stack.outputs:
117-
if var.name in locals:
118-
local = locals[var.name]
119-
else:
120-
local = Local.local(var)
121-
outputs.append(local)
122-
out.emit(stack.define_outputs(outputs))
115+
out.emit(stack.define_output_arrays(prototype.stack.outputs))
123116
if debug:
124117
args = []
125118
for var in prototype.stack.inputs:
@@ -141,7 +134,12 @@ def write_uop(
141134
else:
142135
emit_default(out, uop)
143136

144-
out.emit(stack.push_outputs())
137+
for var in prototype.stack.outputs:
138+
if var.name in locals:
139+
local = locals[var.name]
140+
else:
141+
local = Local.local(var)
142+
out.emit(stack.push(local))
145143
out.start_line()
146144
stack.flush(out, cast_type="_Py_UopsSymbol *", extract_bits=True)
147145
except StackError as ex:

Tools/cases_generator/stack.py

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ def __init__(self) -> None:
169169
self.top_offset = StackOffset.empty()
170170
self.base_offset = StackOffset.empty()
171171
self.variables: list[Local] = []
172-
self.outputs: list[Local] = []
173172
self.defined: set[str] = set()
174173

175174
def pop(self, var: StackItem, extract_bits: bool = False) -> tuple[str, Local]:
@@ -245,28 +244,22 @@ def push(self, var: Local) -> str:
245244
self.defined.add(var.name)
246245
return ""
247246

248-
def define_outputs(self, outputs: list[Local]) -> str:
247+
def define_output_arrays(self, outputs: list[StackItem]) -> str:
249248
res = []
250249
top_offset = self.top_offset.copy()
251250
for var in outputs:
252-
if var.is_array() and var.item.used and not var.item.peek:
251+
if var.is_array() and var.used and not var.peek:
253252
c_offset = top_offset.to_c()
253+
top_offset.push(var)
254254
res.append(f"{var.name} = &stack_pointer[{c_offset}];\n")
255-
self.outputs.append(var)
256-
top_offset.push(var.item)
255+
else:
256+
top_offset.push(var)
257257
return "\n".join(res)
258258

259-
def push_outputs(self) -> str:
260-
res = []
261-
for var in self.outputs:
262-
res.append(self.push(var))
263-
self.outputs = []
264-
return "".join(res)
265-
266259
@staticmethod
267-
def _do_emit(out: CWriter, var: Local, base_offset: StackOffset,
260+
def _do_emit(out: CWriter, var: StackItem, base_offset: StackOffset,
268261
cast_type: str = "uintptr_t", extract_bits: bool = False) -> None:
269-
cast = f"({cast_type})" if var.item.type else ""
262+
cast = f"({cast_type})" if var.type else ""
270263
bits = ".bits" if cast and not extract_bits else ""
271264
if var.condition == "0":
272265
return
@@ -282,7 +275,7 @@ def _do_flush(out: CWriter, variables: list[Local], base_offset: StackOffset, to
282275
out.start_line()
283276
for var in variables:
284277
if var.cached and not var.in_memory and not var.item.peek and not var.name in UNUSED:
285-
Stack._do_emit(out, var, base_offset, cast_type, extract_bits)
278+
Stack._do_emit(out, var.item, base_offset, cast_type, extract_bits)
286279
base_offset.push(var.item)
287280
if base_offset.to_c() != top_offset.to_c():
288281
print("base", base_offset, "top", top_offset)
@@ -302,18 +295,22 @@ def flush(self, out: CWriter, cast_type: str = "uintptr_t", extract_bits: bool =
302295
self.base_offset.clear()
303296
self.top_offset.clear()
304297

305-
def flush_single_var(self, out: CWriter, var_name: str, cast_type: str = "uintptr_t", extract_bits: bool = False) -> None:
306-
assert any(var.name == var_name for var in self.outputs)
298+
def flush_single_var(self, out: CWriter, var_name: str, outputs: list[StackItem],
299+
cast_type: str = "uintptr_t", extract_bits: bool = False) -> None:
300+
assert any(var.name == var_name for var in outputs)
307301
base_offset = self.base_offset.copy()
308302
top_offset = self.top_offset.copy()
309303
for var in self.variables:
310-
base_offset.push(var.item)
311-
for var in self.outputs:
304+
base_offset.push(var)
305+
for var in outputs:
306+
if any(var == v.item for v in self.variables):
307+
# The variable is already on the stack, such as a peeked value
308+
# in the tier1 generator
309+
continue
312310
if var.name == var_name:
313-
var.cached = False
314311
Stack._do_emit(out, var, base_offset, cast_type, extract_bits)
315-
base_offset.push(var.item)
316-
top_offset.push(var.item)
312+
base_offset.push(var)
313+
top_offset.push(var)
317314
if base_offset.to_c() != top_offset.to_c():
318315
print("base", base_offset, "top", top_offset)
319316
assert False

Tools/cases_generator/tier1_generator.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ def write_uop(
9292
stack.push(peeks.pop())
9393
if braces:
9494
emitter.emit("{\n")
95+
emitter.out.emit(stack.define_output_arrays(uop.stack.outputs))
9596
outputs: list[Local] = []
9697
for var in uop.stack.outputs:
9798
if not var.peek:
@@ -102,7 +103,6 @@ def write_uop(
102103
else:
103104
local = Local.local(var)
104105
outputs.append(local)
105-
emitter.emit(stack.define_outputs(outputs))
106106

107107
for cache in uop.caches:
108108
if cache.name != "unused":
@@ -119,7 +119,11 @@ def write_uop(
119119
emitter.emit(f"(void){cache.name};\n")
120120
offset += cache.size
121121
emitter.emit_tokens(uop, stack, inst)
122-
emitter.emit(stack.push_outputs())
122+
for var in outputs:
123+
if var.name in uop.deferred_refs.values():
124+
# We've already spilled this when emitting tokens
125+
var.cached = False
126+
emitter.emit(stack.push(var))
123127
if braces:
124128
emitter.out.start_line()
125129
emitter.emit("}\n")

Tools/cases_generator/tier2_generator.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,14 @@ def write_uop(uop: Uop, emitter: Emitter, stack: Stack) -> None:
165165
emitter.emit(code)
166166
if local.defined:
167167
locals[local.name] = local
168+
emitter.emit(stack.define_output_arrays(uop.stack.outputs))
168169
outputs: list[Local] = []
169170
for var in uop.stack.outputs:
170171
if var.name in locals:
171172
local = locals[var.name]
172173
else:
173174
local = Local.local(var)
174175
outputs.append(local)
175-
emitter.emit(stack.define_outputs(outputs))
176176
for cache in uop.caches:
177177
if cache.name != "unused":
178178
if cache.size == 4:
@@ -182,7 +182,11 @@ def write_uop(uop: Uop, emitter: Emitter, stack: Stack) -> None:
182182
cast = f"uint{cache.size*16}_t"
183183
emitter.emit(f"{type}{cache.name} = ({cast})CURRENT_OPERAND();\n")
184184
emitter.emit_tokens(uop, stack, None)
185-
emitter.emit(stack.push_outputs())
185+
for var in outputs:
186+
if var.name in uop.deferred_refs.values():
187+
# We've already spilled this when emitting tokens
188+
var.cached = False
189+
emitter.emit(stack.push(var))
186190
except StackError as ex:
187191
raise analysis_error(ex.args[0], uop.body[0]) from None
188192

0 commit comments

Comments
 (0)