mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
GH-111485: Generate instruction and uop metadata (GH-113287)
This commit is contained in:
parent
a545a86ec6
commit
e96f26083b
27 changed files with 1738 additions and 1269 deletions
|
@ -1,5 +1,5 @@
|
|||
import sys
|
||||
from analyzer import StackItem
|
||||
from analyzer import StackItem, Instruction, Uop
|
||||
from dataclasses import dataclass
|
||||
from formatting import maybe_parenthesize
|
||||
from cwriter import CWriter
|
||||
|
@ -15,13 +15,16 @@ def var_size(var: StackItem) -> str:
|
|||
else:
|
||||
return var.size
|
||||
|
||||
|
||||
@dataclass
|
||||
class StackOffset:
|
||||
"The stack offset of the virtual base of the stack from the physical stack pointer"
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.popped: list[str] = []
|
||||
self.pushed: list[str] = []
|
||||
popped: list[str]
|
||||
pushed: list[str]
|
||||
|
||||
@staticmethod
|
||||
def empty() -> "StackOffset":
|
||||
return StackOffset([], [])
|
||||
|
||||
def pop(self, item: StackItem) -> None:
|
||||
self.popped.append(var_size(item))
|
||||
|
@ -29,6 +32,15 @@ class StackOffset:
|
|||
def push(self, item: StackItem) -> None:
|
||||
self.pushed.append(var_size(item))
|
||||
|
||||
def __sub__(self, other: "StackOffset") -> "StackOffset":
|
||||
return StackOffset(
|
||||
self.popped + other.pushed,
|
||||
self.pushed + other.popped
|
||||
)
|
||||
|
||||
def __neg__(self) -> "StackOffset":
|
||||
return StackOffset(self.pushed, self.popped)
|
||||
|
||||
def simplify(self) -> None:
|
||||
"Remove matching values from both the popped and pushed list"
|
||||
if not self.popped or not self.pushed:
|
||||
|
@ -88,9 +100,9 @@ class SizeMismatch(Exception):
|
|||
|
||||
class Stack:
|
||||
def __init__(self) -> None:
|
||||
self.top_offset = StackOffset()
|
||||
self.base_offset = StackOffset()
|
||||
self.peek_offset = StackOffset()
|
||||
self.top_offset = StackOffset.empty()
|
||||
self.base_offset = StackOffset.empty()
|
||||
self.peek_offset = StackOffset.empty()
|
||||
self.variables: list[StackItem] = []
|
||||
self.defined: set[str] = set()
|
||||
|
||||
|
@ -166,3 +178,15 @@ class Stack:
|
|||
|
||||
def as_comment(self) -> str:
|
||||
return f"/* Variables: {[v.name for v in self.variables]}. Base offset: {self.base_offset.to_c()}. Top offset: {self.top_offset.to_c()} */"
|
||||
|
||||
|
||||
def get_stack_effect(inst: Instruction) -> Stack:
|
||||
stack = Stack()
|
||||
for uop in inst.parts:
|
||||
if not isinstance(uop, Uop):
|
||||
continue
|
||||
for var in reversed(uop.stack.inputs):
|
||||
stack.pop(var)
|
||||
for i, var in enumerate(uop.stack.outputs):
|
||||
stack.push(var)
|
||||
return stack
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue