Skip to content

Commit

Permalink
feat: add simple pass to collapse constants repeated >= 2 times by us…
Browse files Browse the repository at this point in the history
…ing a dupn
  • Loading branch information
achidlow committed Feb 16, 2024
1 parent 597b939 commit 47d90d6
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/puya/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,12 @@ def __repr__(self) -> str:
result += f"-{self.end_column}"
return result

def __add__(self, other: "SourceLocation") -> "SourceLocation":
def __add__(self, other: "SourceLocation | None") -> "SourceLocation":
from puya.errors import InternalError

if other is None:
return self

if self.file != other.file:
raise InternalError("uh oh")
# BEGIN: YIKES
Expand Down
2 changes: 1 addition & 1 deletion src/puya/teal/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class TealOp:
op_code: str
consumes: int
produces: int
source_location: SourceLocation | None
source_location: SourceLocation | None = attrs.field(eq=False)
comment: str | None = None
"""A comment that is always emitted, should only be used for user comments related to an
op such as assert or err"""
Expand Down
39 changes: 39 additions & 0 deletions src/puya/teal/optimize/constant_stack_shuffling.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import functools
import operator

from puya.teal import models
from puya.teal.optimize._data import LOAD_OP_CODES

Expand Down Expand Up @@ -31,3 +34,39 @@ def perform_constant_stack_shuffling(block: models.TealBlock) -> bool:
result.extend(loads)
block.ops = result
return modified


def constant_dupn_insertion(block: models.TealBlock) -> bool:
result = list[models.TealOp]()
loads = list[models.TealOp]()
modified = False
for op in block.ops:
if loads and op == loads[0]:
loads.append(op)
else:
if loads:
modified = _collapse_loads(loads) or modified
result.extend(loads)
loads = []
if op.op_code in LOAD_OP_CODES or (
op.op_code == "frame_dig" and int(op.immediates[0]) < 0
):
loads.append(op)
else:
result.append(op)
if loads:
modified = _collapse_loads(loads) or modified
result.extend(loads)
block.ops = result
return modified


def _collapse_loads(loads: list[models.TealOp]) -> bool:
n = len(loads) - 1
if n >= 2:
dupn_source_location = functools.reduce(
operator.add, (op.source_location for op in loads[1:])
)
loads[1:] = [models.DupN(n=n, source_location=dupn_source_location)]
return True
return False

0 comments on commit 47d90d6

Please sign in to comment.