Skip to content

Commit 417c96d

Browse files
committed
Don't apply liveness analyis to optimizer generated code
1 parent 6e2a189 commit 417c96d

File tree

4 files changed

+37
-79
lines changed

4 files changed

+37
-79
lines changed

Python/optimizer_cases.c.h

Lines changed: 20 additions & 64 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/optimizer_generator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def write_uop(
123123
try:
124124
out.start_line()
125125
if override:
126-
code_list, storage = Storage.for_uop(stack, prototype)
126+
code_list, storage = Storage.for_uop(stack, prototype, check_liveness=False)
127127
for code in code_list:
128128
out.emit(code)
129129
if debug:

Tools/cases_generator/stack.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -220,13 +220,14 @@ def __init__(self, extract_bits: bool=True, cast_type: str = "uintptr_t") -> Non
220220
self.extract_bits = extract_bits
221221
self.cast_type = cast_type
222222

223-
def drop(self, var: StackItem):
223+
def drop(self, var: StackItem, check_liveness: bool):
224224
self.top_offset.pop(var)
225225
if self.variables:
226226
popped = self.variables.pop()
227227
if popped.is_dead() or not var.used:
228228
return
229-
raise StackError(f"Dropping live value '{var.name}'")
229+
if check_liveness:
230+
raise StackError(f"Dropping live value '{var.name}'")
230231

231232
def pop(self, var: StackItem) -> tuple[str, Local]:
232233
self.top_offset.pop(var)
@@ -415,6 +416,7 @@ class Storage:
415416
stack: Stack
416417
inputs: list[Local]
417418
outputs: list[Local]
419+
check_liveness: bool
418420
spilled: int = 0
419421

420422
@staticmethod
@@ -438,11 +440,11 @@ def is_live(var: Local) -> bool:
438440
def clear_inputs(self, reason:str) -> None:
439441
while self.inputs:
440442
tos = self.inputs.pop()
441-
if self.is_live(tos):
443+
if self.is_live(tos) and self.check_liveness:
442444
raise StackError(
443445
f"Input '{tos.name}' is still live {reason}"
444446
)
445-
self.stack.drop(tos.item)
447+
self.stack.drop(tos.item, self.check_liveness)
446448

447449
def clear_dead_inputs(self) -> None:
448450
live = ""
@@ -452,7 +454,7 @@ def clear_dead_inputs(self) -> None:
452454
live = tos.name
453455
break
454456
self.inputs.pop()
455-
self.stack.drop(tos.item)
457+
self.stack.drop(tos.item, self.check_liveness)
456458
for var in self.inputs:
457459
if not self.is_live(var):
458460
raise StackError(
@@ -516,7 +518,7 @@ def reload(self, out: CWriter) -> None:
516518
out.emit_reload()
517519

518520
@staticmethod
519-
def for_uop(stack: Stack, uop: Uop) -> tuple[list[str], "Storage"]:
521+
def for_uop(stack: Stack, uop: Uop, check_liveness=True) -> tuple[list[str], "Storage"]:
520522
code_list: list[str] = []
521523
inputs: list[Local] = []
522524
peeks: list[Local] = []
@@ -542,7 +544,7 @@ def for_uop(stack: Stack, uop: Uop) -> tuple[list[str], "Storage"]:
542544
for var in inputs:
543545
stack.push(var)
544546
outputs = [ Local.undefined(var) for var in uop.stack.outputs if not var.peek ]
545-
return code_list, Storage(stack, inputs, outputs)
547+
return code_list, Storage(stack, inputs, outputs, check_liveness)
546548

547549
@staticmethod
548550
def copy_list(arg: list[Local]) -> list[Local]:
@@ -554,8 +556,8 @@ def copy(self) -> "Storage":
554556
inputs = [ variables[var.name] for var in self.inputs]
555557
assert [v.name for v in inputs] == [v.name for v in self.inputs], (inputs, self.inputs)
556558
return Storage(
557-
new_stack, inputs,
558-
self.copy_list(self.outputs), self.spilled
559+
new_stack, inputs, self.copy_list(self.outputs),
560+
self.check_liveness, self.spilled
559561
)
560562

561563
def sanity_check(self) -> None:
@@ -586,7 +588,7 @@ def merge(self, other: "Storage", out: CWriter) -> None:
586588
if len(self.inputs) != len(other.inputs):
587589
self.clear_dead_inputs()
588590
other.clear_dead_inputs()
589-
if len(self.inputs) != len(other.inputs):
591+
if len(self.inputs) != len(other.inputs) and self.check_liveness:
590592
diff = self.inputs[-1] if len(self.inputs) > len(other.inputs) else other.inputs[-1]
591593
raise StackError(f"Unmergeable inputs. Differing state of '{diff.name}'")
592594
for var, other_var in zip(self.inputs, other.inputs):
@@ -605,7 +607,7 @@ def push_outputs(self) -> None:
605607
if self.spilled:
606608
raise StackError(f"Unbalanced stack spills")
607609
self.clear_inputs("at the end of the micro-op")
608-
if self.inputs:
610+
if self.inputs and self.check_liveness:
609611
raise StackError(f"Input variable '{self.inputs[-1].name}' is still live")
610612
self._push_defined_outputs()
611613
if self.outputs:
@@ -682,7 +684,7 @@ def close_variable(var: Local, overwrite: str) -> None:
682684
self.stack.push(output)
683685
self.stack.flush(out)
684686
close_variable(self.inputs[0], "")
685-
self.stack.drop(output.item)
687+
self.stack.drop(output.item, self.check_liveness)
686688
self.inputs = []
687689
return
688690
if var_size(lowest) != var_size(output):
@@ -696,7 +698,7 @@ def close_variable(var: Local, overwrite: str) -> None:
696698
close_variable(self.inputs[0], "PyStackRef_NULL")
697699
for input in reversed(self.inputs[1:]):
698700
input.kill()
699-
self.stack.drop(input.item)
701+
self.stack.drop(input.item, self.check_liveness)
700702
self.stack.pop(self.inputs[0].item)
701703
output_in_place = self.outputs and output is self.outputs[0] and lowest.memory_offset is not None
702704
if output_in_place:

0 commit comments

Comments
 (0)