Skip to content

Commit

Permalink
feat[venom]: improve load elimination (#4407)
Browse files Browse the repository at this point in the history
improve `LoadEliminationPass` by generalizing the algorithm to multiple
keys. for simplicity, keep the scope within a single basic block
still. generalize to "readonly" address spaces (`calldataload` and
`dload`) as well.

misc/refactor:
- add hevm harness to the load elimination tests.

---------

Co-authored-by: Harry Kalogirou <[email protected]>
Co-authored-by: Hodan <[email protected]>
  • Loading branch information
3 people authored Feb 12, 2025
1 parent ae6ab0d commit c75a2da
Show file tree
Hide file tree
Showing 5 changed files with 312 additions and 59 deletions.
2 changes: 2 additions & 0 deletions tests/functional/codegen/types/test_dynamic_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
CompilerPanic,
ImmutableViolation,
OverflowException,
StackTooDeep,
StateAccessViolation,
StaticAssertionException,
TypeMismatch,
Expand Down Expand Up @@ -290,6 +291,7 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128:
assert c.test_array(2, 7, 1, 8) == -5454


@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression")
def test_four_d_array_accessor(get_contract):
four_d_array_accessor = """
@external
Expand Down
3 changes: 2 additions & 1 deletion tests/functional/codegen/types/test_lists.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from tests.utils import check_precompile_asserts, decimal_to_int
from vyper.compiler.settings import OptimizationLevel
from vyper.evm.opcodes import version_check
from vyper.exceptions import ArrayIndexException, OverflowException, TypeMismatch
from vyper.exceptions import ArrayIndexException, OverflowException, StackTooDeep, TypeMismatch


def _map_nested(f, xs):
Expand Down Expand Up @@ -193,6 +193,7 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128:
assert c.test_array(2, 7, 1, 8) == -5454


@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression")
def test_four_d_array_accessor(get_contract):
four_d_array_accessor = """
@external
Expand Down
20 changes: 14 additions & 6 deletions tests/hevm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from tests.venom_utils import parse_from_basic_block
from vyper.ir.compile_ir import assembly_to_evm
from vyper.venom import StoreExpansionPass, VenomCompiler
from vyper.venom import LowerDloadPass, StoreExpansionPass, VenomCompiler
from vyper.venom.analysis import IRAnalysesCache
from vyper.venom.basicblock import IRInstruction, IRLiteral

Expand All @@ -27,22 +27,30 @@ def _prep_hevm_venom(venom_source_code):
num_calldataloads += 1

term = bb.instructions[-1]
# test convention, terminate by `return`ing the variables
# test convention, terminate by `sink`ing the variables
# you want to check
assert term.opcode == "sink"
if term.opcode != "sink":
continue

# testing convention: first 256 bytes can be symbolically filled
# with calldata
RETURN_START = 256

num_return_values = 0
for op in term.operands:
ptr = IRLiteral(num_return_values * 32)
ptr = IRLiteral(RETURN_START + num_return_values * 32)
new_inst = IRInstruction("mstore", [op, ptr])
bb.insert_instruction(new_inst, index=-1)
num_return_values += 1

# return 0, 32 * num_variables
term.opcode = "return"
term.operands = [IRLiteral(num_return_values * 32), IRLiteral(0)]
term.operands = [IRLiteral(num_return_values * 32), IRLiteral(RETURN_START)]

ac = IRAnalysesCache(fn)
# requirement for venom_to_assembly

# requirements for venom_to_assembly
LowerDloadPass(ac, fn).run_pass()
StoreExpansionPass(ac, fn).run_pass()

compiler = VenomCompiler([ctx])
Expand Down
Loading

0 comments on commit c75a2da

Please sign in to comment.