GH-111485: Generate instruction and uop metadata (GH-113287)

This commit is contained in:
Mark Shannon 2023-12-20 14:27:25 +00:00 committed by GitHub
parent a545a86ec6
commit e96f26083b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 1738 additions and 1269 deletions

View file

@ -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