Skip to content

Commit

Permalink
feat: allow bytes optimizations to handle addr constants, and also …
Browse files Browse the repository at this point in the history
…`global ZeroAddress` ops
  • Loading branch information
achidlow committed Mar 22, 2024
1 parent 3ad9c18 commit a508274
Show file tree
Hide file tree
Showing 25 changed files with 152 additions and 204 deletions.
4 changes: 2 additions & 2 deletions examples/sizes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
arc-28/EventEmitter 117 77 40 77 0
arc4_numeric_comparisons/UIntNOrdering 1220 908 312 908 0
arc4_types/Arc4Arrays 588 376 212 376 0
arc4_types/Arc4BoolEval 741 19 722 19 0
arc4_types/Arc4BoolEval 741 14 727 14 0
arc4_types/Arc4BoolType 329 57 272 57 0
arc4_types/Arc4DynamicBytes 247 128 119 128 0
arc4_types/Arc4DynamicStringArray 230 112 118 112 0
Expand All @@ -29,7 +29,7 @@
chained_assignment/ChainedAssignment 87 87 0 87 0
conditional_execution/ConditionalExecution 368 348 20 348 0
conditional_expressions 233 185 48 185 0
constants/AddressConstant 68 65 3 65 0
constants/AddressConstant 68 47 21 47 0
constants/ByteConstants 98 76 22 76 0
contains 159 160 -1 160 0
control_op_simplification 48 44 4 38 6
Expand Down
25 changes: 24 additions & 1 deletion src/puya/ir/optimize/intrinsic_simplification.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import base64
import operator
import typing
from collections.abc import Callable
Expand All @@ -6,6 +7,7 @@
import attrs
import structlog

from puya import algo_constants
from puya.avm_type import AVMType
from puya.context import CompileContext
from puya.ir import models
Expand Down Expand Up @@ -336,16 +338,31 @@ def _choose_encoding(a: AVMBytesEncoding, b: AVMBytesEncoding) -> AVMBytesEncodi
return AVMBytesEncoding.base16


def _decode_address(address: str) -> bytes:
"""check if address is a valid address with checksum"""
# Pad address so it's a valid b32 string
padded_address = address + (6 * "=")
address_bytes = base64.b32decode(padded_address)
public_key_hash = address_bytes[: algo_constants.PUBLIC_KEY_HASH_LENGTH]
return public_key_hash


def _get_byte_constant(
subroutine: models.Subroutine, byte_arg: models.Value
) -> models.BytesConstant | None:
if isinstance(byte_arg, models.BytesConstant):
return byte_arg
if isinstance(byte_arg, models.BigUIntConstant):
return models.BytesConstant(
source_location=byte_arg.source_location,
value=biguint_bytes_eval(byte_arg.value),
encoding=AVMBytesEncoding.base16,
source_location=byte_arg.source_location,
)
if isinstance(byte_arg, models.AddressConstant):
return models.BytesConstant(
value=_decode_address(byte_arg.value),
encoding=AVMBytesEncoding.base32,
source_location=byte_arg.source_location,
)
if isinstance(byte_arg, models.Register):
byte_arg_defn = get_definition(subroutine, byte_arg)
Expand All @@ -367,6 +384,12 @@ def _get_byte_constant(
value=b"\x00" * bzero_arg,
encoding=AVMBytesEncoding.base16,
)
case models.Intrinsic(op=AVMOp.global_, immediates=["ZeroAddress"]):
return models.BytesConstant(
value=_decode_address(algo_constants.ZERO_ADDRESS),
encoding=AVMBytesEncoding.base32,
source_location=byte_arg.source_location,
)
return None


Expand Down
10 changes: 0 additions & 10 deletions test_cases/arc4_types/out/Arc4BoolEvalContract.approval.mir
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@

// test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.approval_program() -> uint64:
main_block@0:
global ZeroAddress // {global} arc4.Address() arc4_types/bool_eval.py:19
// virtual: store tmp%6#0 to l-stack (no copy) tmp%6#0 arc4.Address() arc4_types/bool_eval.py:19
global ZeroAddress // tmp%6#0,{global} not arc4.Address() arc4_types/bool_eval.py:19
// virtual: store tmp%7#0 to l-stack (no copy) tmp%6#0,tmp%7#0 not arc4.Address() arc4_types/bool_eval.py:19
// virtual: load tmp%6#0 from l-stack (no copy) tmp%7#0,tmp%6#0 not arc4.Address() arc4_types/bool_eval.py:19
// virtual: load tmp%7#0 from l-stack (no copy) tmp%6#0,tmp%7#0 not arc4.Address() arc4_types/bool_eval.py:19
== // {==} not arc4.Address() arc4_types/bool_eval.py:19
// virtual: store tmp%8#0 to l-stack (no copy) tmp%8#0 not arc4.Address() arc4_types/bool_eval.py:19
// virtual: load tmp%8#0 from l-stack (no copy) tmp%8#0 assert not arc4.Address() arc4_types/bool_eval.py:19
assert // assert not arc4.Address() arc4_types/bool_eval.py:19
txn Sender // {txn} Txn.sender arc4_types/bool_eval.py:20
// virtual: store tmp%9#0 to l-stack (no copy) tmp%9#0 Txn.sender arc4_types/bool_eval.py:20
global ZeroAddress // tmp%9#0,{global} arc4.Address(Txn.sender) arc4_types/bool_eval.py:20
Expand Down
6 changes: 0 additions & 6 deletions test_cases/arc4_types/out/Arc4BoolEvalContract.approval.teal
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
#pragma version 10

test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.approval_program:
// arc4_types/bool_eval.py:19
// assert not arc4.Address()
global ZeroAddress
dup
==
assert
// arc4_types/bool_eval.py:20
// assert arc4.Address(Txn.sender)
txn Sender
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract:
program approval:
subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.approval_program() -> uint64:
block@0: // L12
let tmp%6#0: bytes = (global ZeroAddress)
let tmp%7#0: bytes = (global ZeroAddress)
let tmp%8#0: uint64 = (== tmp%6#0 tmp%7#0)
(assert tmp%8#0)
let tmp%9#0: bytes = (txn Sender)
let tmp%10#0: bytes = (global ZeroAddress)
let tmp%11#0: uint64 = (!= tmp%9#0 tmp%10#0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract:
(assert tmp%4#0)
let tmp%5#0: uint64 = 1u
(assert tmp%5#0)
let tmp%6#0: bytes = (global ZeroAddress)
let tmp%7#0: bytes = (global ZeroAddress)
let tmp%8#0: uint64 = (== tmp%6#0 tmp%7#0)
let tmp%8#0: uint64 = 1u
(assert tmp%8#0)
let tmp%9#0: bytes = (txn Sender)
let tmp%10#0: bytes = (global ZeroAddress)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract:
(assert tmp%1#0)
let tmp%3#0: uint64 = 1u
(assert tmp%3#0)
let tmp%6#0: bytes = (global ZeroAddress)
let tmp%7#0: bytes = (global ZeroAddress)
let tmp%8#0: uint64 = (== tmp%6#0 tmp%7#0)
(assert tmp%8#0)
let tmp%9#0: bytes = (txn Sender)
let tmp%10#0: bytes = (global ZeroAddress)
let tmp%11#0: uint64 = (!= tmp%9#0 tmp%10#0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract:
program approval:
subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.approval_program() -> uint64:
block@0: // L12
let tmp%6#0: bytes = (global ZeroAddress)
let tmp%7#0: bytes = (global ZeroAddress)
let tmp%8#0: uint64 = (== tmp%6#0 tmp%7#0)
(assert tmp%8#0)
let tmp%9#0: bytes = (txn Sender)
let tmp%10#0: bytes = (global ZeroAddress)
let tmp%11#0: uint64 = (!= tmp%9#0 tmp%10#0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract:
program approval:
subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.approval_program() -> uint64:
block@0: // L12
let tmp%6#0: bytes = (global ZeroAddress)
let tmp%7#0: bytes = (global ZeroAddress)
let tmp%8#0: uint64 = (== tmp%6#0 tmp%7#0)
(assert tmp%8#0)
let tmp%9#0: bytes = (txn Sender)
let tmp%10#0: bytes = (global ZeroAddress)
let tmp%11#0: uint64 = (!= tmp%9#0 tmp%10#0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract:
program approval:
subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.approval_program() -> uint64:
block@0: // L12
let tmp%6#0: bytes = (global ZeroAddress)
let tmp%7#0: bytes = (global ZeroAddress)
let tmp%8#0: uint64 = (== tmp%6#0 tmp%7#0)
(assert tmp%8#0)
let tmp%9#0: bytes = (txn Sender)
let tmp%10#0: bytes = (global ZeroAddress)
let tmp%11#0: uint64 = (!= tmp%9#0 tmp%10#0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract:
program approval:
subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.approval_program() -> uint64:
block@0: // L12
let tmp%6#0: bytes = (global ZeroAddress)
let tmp%7#0: bytes = (global ZeroAddress)
let tmp%8#0: uint64 = (== tmp%6#0 tmp%7#0)
(assert tmp%8#0)
let tmp%9#0: bytes = (txn Sender)
let tmp%10#0: bytes = (global ZeroAddress)
let tmp%11#0: uint64 = (!= tmp%9#0 tmp%10#0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract:
program approval:
subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.approval_program() -> uint64:
block@0: // L12
let tmp%6#0: bytes = (global ZeroAddress)
let tmp%7#0: bytes = (global ZeroAddress)
let tmp%8#0: uint64 = (== tmp%6#0 tmp%7#0)
(assert tmp%8#0)
let tmp%9#0: bytes = (txn Sender)
let tmp%10#0: bytes = (global ZeroAddress)
let tmp%11#0: uint64 = (!= tmp%9#0 tmp%10#0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract:
program approval:
subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.approval_program() -> uint64:
block@0: // L12
let tmp%6#0: bytes = (global ZeroAddress)
let tmp%7#0: bytes = (global ZeroAddress)
let tmp%8#0: uint64 = (== tmp%6#0 tmp%7#0)
(assert tmp%8#0)
let tmp%9#0: bytes = (txn Sender)
let tmp%10#0: bytes = (global ZeroAddress)
let tmp%11#0: uint64 = (!= tmp%9#0 tmp%10#0)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
#pragma version 10

test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.approval_program:
global ZeroAddress
dup
==
assert
txn Sender
global ZeroAddress
!=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ contract test_cases.arc4_types.bool_eval.Arc4BoolEvalContract:
program approval:
subroutine test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.approval_program() -> uint64:
block@0: // L12
let tmp%6#0: bytes = (global ZeroAddress)
let tmp%7#0: bytes = (global ZeroAddress)
let tmp%8#0: uint64 = (== tmp%6#0 tmp%7#0)
(assert tmp%8#0)
let tmp%9#0: bytes = (txn Sender)
let tmp%10#0: bytes = (global ZeroAddress)
let tmp%11#0: uint64 = (!= tmp%9#0 tmp%10#0)
Expand Down
22 changes: 10 additions & 12 deletions test_cases/arc4_types/puya.log
Original file line number Diff line number Diff line change
Expand Up @@ -2474,6 +2474,7 @@ debug: Simplified (setbit 0x00 0u 0u) to 0x00
debug: Simplified (setbit 0x00 0u 1u) to 0x80
debug: Simplified (== "/x00/x00" 0x0000) to 1u
debug: Simplified (!= "/x00/x01." 0x0000) to 1u
debug: Simplified (== tmp%6#0 tmp%7#0) to 1u
debug: Simplified (== 0x00 0x00) to 1u
debug: Simplified (!= 0x01 0x00) to 1u
debug: Simplified (== 0x0000 0x0000) to 1u
Expand Down Expand Up @@ -2502,6 +2503,8 @@ debug: Simplified (concat 0x 0x0000000000000000) to 0x0000000000000000
debug: Simplified (setbit 0x00 0u 0u) to 0x00
debug: Simplified (setbit 0x00 0u 0u) to 0x00
debug: Optimizer: Remove Unused Variables
debug: Removing unused variable tmp%6#0
debug: Removing unused variable tmp%7#0
debug: Removing unused variable dynamic_arr#0
debug: Removing unused variable data%36#0
debug: Optimizer: Simplify Control Ops
Expand Down Expand Up @@ -2535,6 +2538,7 @@ debug: Removing unused variable tmp%0#0
debug: Removing unused variable tmp%2#0
debug: Removing unused variable tmp%4#0
debug: Removing unused variable tmp%5#0
debug: Removing unused variable tmp%8#0
debug: Removing unused variable tmp%12#0
debug: Removing unused variable tmp%13#0
debug: Removing unused variable tmp%14#0
Expand Down Expand Up @@ -2757,18 +2761,12 @@ debug: Sequentializing parallel copies in test_cases.arc4_types.bool_eval.Arc4Bo
debug: Sequentializing parallel copies in test_cases.arc4_types.bool_eval.Arc4BoolEvalContract.clear_state_program
debug: Performing post-SSA optimizations
debug: Output IR to arc4_types/out/Arc4BoolEvalContract.destructured.ir
debug: Inserted main_block@0.ops[7]: 'store tmp%8#0 to l-stack (copy)'
debug: Replaced main_block@0.ops[9]: 'load tmp%8#0' with 'load tmp%8#0 from l-stack (no copy)'
debug: Inserted main_block@0.ops[18]: 'store tmp%11#0 to l-stack (copy)'
debug: Replaced main_block@0.ops[20]: 'load tmp%11#0' with 'load tmp%11#0 from l-stack (no copy)'
debug: Inserted main_block@0.ops[3]: 'store tmp%7#0 to l-stack (copy)'
debug: Replaced main_block@0.ops[6]: 'load tmp%7#0' with 'load tmp%7#0 from l-stack (no copy)'
debug: Inserted main_block@0.ops[15]: 'store tmp%10#0 to l-stack (copy)'
debug: Replaced main_block@0.ops[18]: 'load tmp%10#0' with 'load tmp%10#0 from l-stack (no copy)'
debug: Inserted main_block@0.ops[1]: 'store tmp%6#0 to l-stack (copy)'
debug: Replaced main_block@0.ops[6]: 'load tmp%6#0' with 'load tmp%6#0 from l-stack (no copy)'
debug: Inserted main_block@0.ops[14]: 'store tmp%9#0 to l-stack (copy)'
debug: Replaced main_block@0.ops[19]: 'load tmp%9#0' with 'load tmp%9#0 from l-stack (no copy)'
debug: Inserted main_block@0.ops[7]: 'store tmp%11#0 to l-stack (copy)'
debug: Replaced main_block@0.ops[9]: 'load tmp%11#0' with 'load tmp%11#0 from l-stack (no copy)'
debug: Inserted main_block@0.ops[3]: 'store tmp%10#0 to l-stack (copy)'
debug: Replaced main_block@0.ops[6]: 'load tmp%10#0' with 'load tmp%10#0 from l-stack (no copy)'
debug: Inserted main_block@0.ops[1]: 'store tmp%9#0 to l-stack (copy)'
debug: Replaced main_block@0.ops[6]: 'load tmp%9#0' with 'load tmp%9#0 from l-stack (no copy)'
debug: Output IR to arc4_types/out/Arc4DynamicBytesContract.ssa.ir
info: Optimizing test_cases.arc4_types.dynamic_bytes.Arc4DynamicBytesContract at level 1
debug: Begin optimization pass 1/100
Expand Down
Loading

0 comments on commit a508274

Please sign in to comment.