mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
GH-128914: Remove conditional stack effects from bytecodes.c
and the code generators (GH-128918)
This commit is contained in:
parent
0a6412f9cc
commit
ab61d3f430
44 changed files with 1460 additions and 1679 deletions
|
@ -25,7 +25,6 @@ class Properties:
|
|||
side_exit: bool
|
||||
pure: bool
|
||||
tier: int | None = None
|
||||
oparg_and_1: bool = False
|
||||
const_oparg: int = -1
|
||||
needs_prev: bool = False
|
||||
no_save_ip: bool = False
|
||||
|
@ -124,16 +123,14 @@ class Flush:
|
|||
class StackItem:
|
||||
name: str
|
||||
type: str | None
|
||||
condition: str | None
|
||||
size: str
|
||||
peek: bool = False
|
||||
used: bool = False
|
||||
|
||||
def __str__(self) -> str:
|
||||
cond = f" if ({self.condition})" if self.condition else ""
|
||||
size = f"[{self.size}]" if self.size else ""
|
||||
type = "" if self.type is None else f"{self.type} "
|
||||
return f"{type}{self.name}{size}{cond} {self.peek}"
|
||||
return f"{type}{self.name}{size} {self.peek}"
|
||||
|
||||
def is_array(self) -> bool:
|
||||
return self.size != ""
|
||||
|
@ -315,25 +312,19 @@ def override_error(
|
|||
)
|
||||
|
||||
|
||||
def convert_stack_item(
|
||||
item: parser.StackEffect, replace_op_arg_1: str | None
|
||||
) -> StackItem:
|
||||
cond = item.cond
|
||||
if replace_op_arg_1 and OPARG_AND_1.match(item.cond):
|
||||
cond = replace_op_arg_1
|
||||
return StackItem(item.name, item.type, cond, item.size)
|
||||
def convert_stack_item(item: parser.StackEffect) -> StackItem:
|
||||
return StackItem(item.name, item.type, item.size)
|
||||
|
||||
|
||||
def analyze_stack(
|
||||
op: parser.InstDef | parser.Pseudo, replace_op_arg_1: str | None = None
|
||||
) -> StackEffect:
|
||||
op: parser.InstDef | parser.Pseudo) -> StackEffect:
|
||||
inputs: list[StackItem] = [
|
||||
convert_stack_item(i, replace_op_arg_1)
|
||||
convert_stack_item(i)
|
||||
for i in op.inputs
|
||||
if isinstance(i, parser.StackEffect)
|
||||
]
|
||||
outputs: list[StackItem] = [
|
||||
convert_stack_item(i, replace_op_arg_1) for i in op.outputs
|
||||
convert_stack_item(i) for i in op.outputs
|
||||
]
|
||||
# Mark variables with matching names at the base of the stack as "peek"
|
||||
modified = False
|
||||
|
@ -756,40 +747,6 @@ def always_exits(op: parser.InstDef) -> bool:
|
|||
return True
|
||||
return False
|
||||
|
||||
|
||||
def stack_effect_only_peeks(instr: parser.InstDef) -> bool:
|
||||
stack_inputs = [s for s in instr.inputs if not isinstance(s, parser.CacheEffect)]
|
||||
if len(stack_inputs) != len(instr.outputs):
|
||||
return False
|
||||
if len(stack_inputs) == 0:
|
||||
return False
|
||||
if any(s.cond for s in stack_inputs) or any(s.cond for s in instr.outputs):
|
||||
return False
|
||||
return all(
|
||||
(s.name == other.name and s.type == other.type and s.size == other.size)
|
||||
for s, other in zip(stack_inputs, instr.outputs)
|
||||
)
|
||||
|
||||
|
||||
OPARG_AND_1 = re.compile("\\(*oparg *& *1")
|
||||
|
||||
|
||||
def effect_depends_on_oparg_1(op: parser.InstDef) -> bool:
|
||||
for effect in op.inputs:
|
||||
if isinstance(effect, parser.CacheEffect):
|
||||
continue
|
||||
if not effect.cond:
|
||||
continue
|
||||
if OPARG_AND_1.match(effect.cond):
|
||||
return True
|
||||
for effect in op.outputs:
|
||||
if not effect.cond:
|
||||
continue
|
||||
if OPARG_AND_1.match(effect.cond):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def compute_properties(op: parser.InstDef) -> Properties:
|
||||
escaping_calls = find_escaping_api_calls(op)
|
||||
has_free = (
|
||||
|
@ -863,29 +820,6 @@ def make_uop(
|
|||
body=op.block.tokens,
|
||||
properties=compute_properties(op),
|
||||
)
|
||||
if effect_depends_on_oparg_1(op) and "split" in op.annotations:
|
||||
result.properties.oparg_and_1 = True
|
||||
for bit in ("0", "1"):
|
||||
name_x = name + "_" + bit
|
||||
properties = compute_properties(op)
|
||||
if properties.oparg:
|
||||
# May not need oparg anymore
|
||||
properties.oparg = any(
|
||||
token.text == "oparg" for token in op.block.tokens
|
||||
)
|
||||
rep = Uop(
|
||||
name=name_x,
|
||||
context=op.context,
|
||||
annotations=op.annotations,
|
||||
stack=analyze_stack(op, bit),
|
||||
caches=analyze_caches(inputs),
|
||||
deferred_refs=analyze_deferred_refs(op),
|
||||
output_stores=find_stores_outputs(op),
|
||||
body=op.block.tokens,
|
||||
properties=properties,
|
||||
)
|
||||
rep.replicates = result
|
||||
uops[name_x] = rep
|
||||
for anno in op.annotations:
|
||||
if anno.startswith("replicate"):
|
||||
result.replicated = int(anno[10:-1])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue