GH-121784: Generate an error during code gen if a variable is marked unused, but is used and thus cached in a prior uop. (#121788)

* Reject uop definitions that declare values as 'unused' that are already cached by prior uops

* Track which variables are defined and only load from memory when needed

* Support explicit `flush` in macro definitions. 

* Make sure stack is flushed in where needed.
This commit is contained in:
Mark Shannon 2024-07-18 12:49:24 +01:00 committed by GitHub
parent 169324c27a
commit 3eacfc1a4d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 443 additions and 255 deletions

View file

@ -114,7 +114,7 @@ class StackOffset:
self.pushed = []
class SizeMismatch(Exception):
class StackError(Exception):
pass
@ -134,27 +134,29 @@ class Stack:
if self.variables:
popped = self.variables.pop()
if popped.size != var.size:
raise SizeMismatch(
raise StackError(
f"Size mismatch when popping '{popped.name}' from stack to assign to {var.name}. "
f"Expected {var.size} got {popped.size}"
)
if popped.name == var.name:
if var.name in UNUSED:
if popped.name not in UNUSED and popped.name in self.defined:
raise StackError(f"Value is declared unused, but is already cached by prior operation")
return ""
elif popped.name in UNUSED:
if popped.name in UNUSED or popped.name not in self.defined:
self.defined.add(var.name)
return (
f"{var.name} = {indirect}stack_pointer[{self.top_offset.to_c()}];\n"
)
elif var.name in UNUSED:
return ""
else:
self.defined.add(var.name)
return f"{var.name} = {popped.name};\n"
if popped.name == var.name:
return ""
else:
return f"{var.name} = {popped.name};\n"
self.base_offset.pop(var)
if var.name in UNUSED:
if var.name in UNUSED or not var.used:
return ""
else:
self.defined.add(var.name)
self.defined.add(var.name)
cast = f"({var.type})" if (not indirect and var.type) else ""
bits = ".bits" if cast and not extract_bits else ""
assign = (
@ -178,6 +180,8 @@ class Stack:
return f"{var.name} = &stack_pointer[{c_offset}];\n"
else:
self.top_offset.push(var)
if var.used:
self.defined.add(var.name)
return ""
def flush(self, out: CWriter, cast_type: str = "uintptr_t", extract_bits: bool = False) -> None: