Skip to content

Commit

Permalink
feat[venom]: add binop optimizations (vyperlang#4281)
Browse files Browse the repository at this point in the history
this commit adds additional binop optimizations to venom. these are
the analog of `optimize_binop` in the legacy optimizer and take us one
step closer to being able to bypass the legacy optimizer in the venom
pipeline.

the rules have been added to the algebraic optimizations pass. adding
them to the SCCP pass was considered, but to keep the rules all in one
place and to keep each pass more self-contained, they were added to the
algebraic optimizations pass, with additional SCCP passes performed for
branch/cfg reduction.

some additional machinery has been added, including `lit_eq` which
compares two IRLiterals in modular arithmetic, and InstructionUpdator,
which updates instructions while also updating the DFG in-place. this
should be useful to use for other passes in the future (although out of
scope for this PR).

additional passes have been added since they were found to improve
codesize. in particular, running AlgebraicOptimization multiple times,
and running SCCP after LoadElimination, seem to have some additional
benefits.

---------

Co-authored-by: Charles Cooper <[email protected]>
  • Loading branch information
HodanPlodky and charles-cooper authored Jan 20, 2025
1 parent 7136eab commit 9a2cb2e
Show file tree
Hide file tree
Showing 16 changed files with 1,084 additions and 80 deletions.
19 changes: 15 additions & 4 deletions tests/functional/builtins/codegen/test_slice.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
from vyper.compiler import compile_code
from vyper.compiler.settings import OptimizationLevel, Settings
from vyper.evm.opcodes import version_check
from vyper.exceptions import ArgumentException, CompilerPanic, TypeMismatch
from vyper.exceptions import (
ArgumentException,
CompilerPanic,
StaticAssertionException,
TypeMismatch,
)

_fun_bytes32_bounds = [(0, 32), (3, 29), (27, 5), (0, 5), (5, 3), (30, 2)]

Expand Down Expand Up @@ -533,9 +538,15 @@ def do_slice():

@pytest.mark.parametrize("bad_code", oob_fail_list)
def test_slice_buffer_oob_reverts(bad_code, get_contract, tx_failed):
c = get_contract(bad_code)
with tx_failed():
c.do_slice()
try:
c = get_contract(bad_code)
with tx_failed():
c.do_slice()
except StaticAssertionException:
# it should be ok if we
# catch the assert in compile time
# since it supposed to be revert
pass


# tests all 3 adhoc locations: `msg.data`, `self.code`, `<address>.code`
Expand Down
2 changes: 0 additions & 2 deletions tests/functional/codegen/features/test_clampers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from eth_utils import keccak

from tests.utils import ZERO_ADDRESS, decimal_to_int
from vyper.exceptions import StackTooDeep
from vyper.utils import int_bounds


Expand Down Expand Up @@ -502,7 +501,6 @@ def foo(b: DynArray[int128, 10]) -> DynArray[int128, 10]:


@pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)])
@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression")
def test_multidimension_dynarray_clamper_passing(get_contract, value):
code = """
@external
Expand Down
14 changes: 11 additions & 3 deletions tests/functional/codegen/types/test_dynamic_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
ImmutableViolation,
OverflowException,
StateAccessViolation,
StaticAssertionException,
TypeMismatch,
)

Expand Down Expand Up @@ -1863,9 +1864,16 @@ def should_revert() -> DynArray[String[65], 2]:
@pytest.mark.parametrize("code", dynarray_length_no_clobber_cases)
def test_dynarray_length_no_clobber(get_contract, tx_failed, code):
# check that length is not clobbered before dynarray data copy happens
c = get_contract(code)
with tx_failed():
c.should_revert()
try:
c = get_contract(code)
with tx_failed():
c.should_revert()
except StaticAssertionException:
# this test should create
# assert error so if it is
# detected in compile time
# we can continue
pass


def test_dynarray_make_setter_overlap(get_contract):
Expand Down
2 changes: 1 addition & 1 deletion tests/functional/syntax/test_unbalanced_return.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def test() -> int128:
if 1 == 1 :
return 1
else:
assert msg.sender != msg.sender
assert msg.sender != self
return 0
""",
"""
Expand Down
Loading

0 comments on commit 9a2cb2e

Please sign in to comment.