Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat[venom]: new DFTPass algorithm #4255

Merged
merged 149 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 83 commits
Commits
Show all changes
149 commits
Select commit Hold shift + click to select a range
919346b
τεμπ
harkal Sep 11, 2024
f4c7ac5
revert `get_phi_depth()` changes
harkal Sep 18, 2024
cc50efe
revert change that slipped in from another branch
harkal Sep 18, 2024
28eed40
`StackModel` refactor
harkal Sep 19, 2024
e871868
feat[venom]: add small heuristic for cleaning input stack
charles-cooper Sep 20, 2024
e97bc88
print correct liveness and fence
harkal Jun 3, 2024
12487fc
improve ordering
harkal Jun 3, 2024
185ae23
r fences
harkal Jun 3, 2024
d8e6c74
remove old code
harkal Jun 3, 2024
4a87e93
adapt fensing
harkal Jun 3, 2024
24ad003
more
harkal Jun 3, 2024
5b7f60c
improve ordering and grouping of instructions in DFTPass
harkal Jun 4, 2024
2f0b4af
wip
harkal Jun 4, 2024
1f94e46
wip
harkal Jun 4, 2024
f12192c
squash
harkal Jun 11, 2024
d89adb6
wip - ament
harkal Jun 11, 2024
a581a09
pass all tests
harkal Jun 12, 2024
948f7f1
preserve last child if terminator
harkal Jun 12, 2024
8c99eee
cleanups
harkal Jun 12, 2024
58182ab
wip
harkal Jun 18, 2024
6efbce8
wip
harkal Jun 18, 2024
57353b2
no merge node
harkal Jun 18, 2024
8bac9f5
fix
harkal Jun 18, 2024
a332610
fix
harkal Jun 18, 2024
56fed17
gda
harkal Jun 19, 2024
93c7dcf
groups
harkal Jun 19, 2024
1958f48
wip
harkal Jun 19, 2024
ce584ac
wip
harkal Jun 19, 2024
81143c6
wip
harkal Jun 19, 2024
44e6880
better dep traversal
harkal Jun 19, 2024
ebeb9ee
wip
harkal Jun 19, 2024
fce4086
before circle breaking
harkal Jun 19, 2024
e7ce364
cycles detector
harkal Jun 19, 2024
58d7387
wip
harkal Jun 19, 2024
644e124
wip
harkal Jun 19, 2024
9f8511f
fix
harkal Jun 20, 2024
26c129c
wip
harkal Jun 20, 2024
ec29d76
grouping refactor
harkal Jun 20, 2024
f30b11c
cleanup
harkal Jun 20, 2024
44ebf21
spelling
harkal Jun 20, 2024
a8ffb79
`DUP1 SWAP1` optimization
harkal Jun 21, 2024
192ee8f
small cleanup and store expantion (not working)
harkal Jun 25, 2024
958974b
cleanup and add comments
harkal Jun 25, 2024
9e64c6e
lint
harkal Jun 25, 2024
3cd1e8b
fixes
harkal Sep 24, 2024
a008fe8
refactor
harkal Sep 24, 2024
23f2b65
lint
harkal Sep 24, 2024
e3c3ba4
remove store expantion pass
harkal Sep 24, 2024
ba88b4e
refactor
harkal Sep 24, 2024
63246e7
Merge branch 'master' into feat/stack2mem
harkal Sep 24, 2024
1f0ae6a
Merge branch 'master' into feat/dft_upgrade
harkal Sep 26, 2024
3e08f83
properly hash
harkal Sep 26, 2024
3d3a4cf
review dead code
harkal Sep 26, 2024
8ccb393
refactor
harkal Sep 26, 2024
1bb6da6
`get_uses_in_bb()` utility method
harkal Sep 26, 2024
b61f9b9
refactor
harkal Sep 26, 2024
f259618
refactor
harkal Sep 26, 2024
e04285f
remove force
harkal Sep 26, 2024
588a818
refactor/cleanup
harkal Sep 26, 2024
d4f3cf0
combine children to allow for ordering heuristics later
harkal Sep 26, 2024
72b10b5
disable liveness print out for debuging purposes
harkal Sep 26, 2024
918cd5f
Merge branch 'master' into feat/dft_upgrade
harkal Sep 27, 2024
3d26886
work
harkal Sep 27, 2024
6f77fa8
lint
harkal Sep 27, 2024
7367822
wip
harkal Sep 27, 2024
0a9240b
wip
harkal Sep 27, 2024
7f89a8b
w
harkal Sep 27, 2024
ceffef6
remove duplicate `assert`, `assert_unreachable` from `VOLATILE_INSTRU…
harkal Sep 27, 2024
3f45f5e
new dep
harkal Sep 27, 2024
8cb64da
no groups
harkal Sep 27, 2024
2987d36
refactor[venom]: add effects to instructions
charles-cooper Sep 27, 2024
b1425ca
wip
harkal Sep 27, 2024
cfbb0eb
wip
harkal Sep 27, 2024
2a9a3ce
push iszero-assert together
harkal Sep 27, 2024
65b1351
cleanup
harkal Sep 27, 2024
dae696a
Revert "remove store expantion pass"
harkal Sep 28, 2024
db87ff8
enable store expansion
harkal Sep 28, 2024
d025298
improve naming
harkal Sep 28, 2024
e9b5303
fix get_write_effects()
charles-cooper Sep 28, 2024
36ff613
effects
harkal Sep 28, 2024
283d93a
effect deps
harkal Sep 28, 2024
f94e103
work
harkal Sep 28, 2024
8be0bef
Update vyper/venom/effects.py
charles-cooper Sep 30, 2024
fcb688f
update effects to be an enum.Flag
charles-cooper Sep 30, 2024
94aeeb0
effects magic
harkal Oct 1, 2024
b9046cc
Merge remote-tracking branch 'origin-vyper/master' into feat/dft_upgrade
harkal Oct 1, 2024
bdc1b4d
wip
harkal Oct 1, 2024
62616cd
disable effects
harkal Oct 1, 2024
805b079
Merge remote-tracking branch 'origin-charles/refactor/effects-analysi…
harkal Oct 1, 2024
eea930b
find roots and make terminator last to process
harkal Oct 1, 2024
826e821
remove sort
harkal Oct 1, 2024
2e628b6
fix
harkal Oct 2, 2024
cbf47ef
cleanup
harkal Oct 2, 2024
9b791f3
Merge remote-tracking branch 'origin-vyper/master' into feat/stack2mem
harkal Oct 2, 2024
843a127
fix deps
harkal Oct 2, 2024
a99ccf6
remove store expanstion
harkal Oct 2, 2024
d8d747b
Revert "remove store expanstion"
harkal Oct 2, 2024
ba0b912
lint
harkal Oct 2, 2024
da7c00a
python 3.11 support
harkal Oct 2, 2024
d8a63c9
cleanup
harkal Oct 2, 2024
face008
cleanup
harkal Oct 2, 2024
3836b87
wip
harkal Oct 4, 2024
015278a
Merge branch 'master' into feat/dft_upgrade
charles-cooper Oct 5, 2024
9191c6a
Merge branch 'master' into feat/stack2mem
harkal Oct 5, 2024
1d6b762
Merge branch 'master' into feat/dft_upgrade
harkal Oct 5, 2024
ff9e43c
Merge branch 'feat/dft_upgrade' of github.com:harkal/vyper into feat/…
harkal Oct 5, 2024
baadeed
debug
charles-cooper Oct 5, 2024
d5cc045
wip - improve heuristic
charles-cooper Oct 5, 2024
0a1a001
wip barriers
charles-cooper Oct 6, 2024
6a72efe
refactor offspring count
charles-cooper Oct 6, 2024
ddde336
an improvement
charles-cooper Oct 6, 2024
6a8d595
Merge pull request #8 from charles-cooper/dft-shenanigans
harkal Oct 7, 2024
defdf8d
cleanup
harkal Oct 8, 2024
0b899e4
remove deadcode and debuging
harkal Oct 8, 2024
9e2c428
Merge remote-tracking branch 'origin-vyper/master' into feat/dft_upgrade
harkal Oct 8, 2024
747e54b
Merge branch 'master' into feat/venom-pops
harkal Oct 8, 2024
919dc22
Merge branch 'master' into feat/venom-pops
harkal Oct 8, 2024
2b49132
Merge branch 'feat/venom-pops' of github.com:charles-cooper/vyper int…
harkal Oct 8, 2024
26592bc
Merge branch 'devel' into feat/dft_upgrade
harkal Oct 8, 2024
7406e85
Merge branch 'master' into feat/dft_upgrade
harkal Oct 10, 2024
b4c6998
Merge branch 'master' into feat/dft_upgrade
harkal Oct 10, 2024
3192f9c
Merge branch 'master' into feat/dft_upgrade
charles-cooper Oct 13, 2024
e46d946
Merge branch 'feat/dft_upgrade' of github.com:harkal/vyper into feat/…
harkal Oct 16, 2024
ef84d70
Merge branch 'master' into feat/dft_upgrade
harkal Oct 16, 2024
1c98c23
fix Effects.__iter__() for python3.10
charles-cooper Oct 16, 2024
b450deb
Merge branch 'master' into feat/dft_upgrade
harkal Oct 16, 2024
7523cb1
bring back sorting and offsprings
harkal Oct 16, 2024
d2ed247
merge barriers
harkal Oct 16, 2024
b4b22cf
Merge branch 'master' into feat/stack2mem
harkal Oct 16, 2024
52efbaf
refactor to the new pass importing
harkal Oct 16, 2024
9212c86
add back SCCP
harkal Oct 16, 2024
414ca33
fixes and cleanup
harkal Oct 16, 2024
f48ded6
Merge branch 'feat/stack2mem' into feat/dft_upgrade
harkal Oct 23, 2024
caaae55
heuristic update
harkal Oct 23, 2024
a29efac
Revert "Merge branch 'feat/stack2mem' into feat/dft_upgrade"
harkal Oct 23, 2024
02b5082
cleanup
harkal Oct 23, 2024
aec32a0
refactor
harkal Oct 23, 2024
267732c
fix test
harkal Oct 23, 2024
acd5d77
add `sha3_64` to effects
harkal Oct 23, 2024
40e2e94
lint
harkal Oct 23, 2024
5b4b9c1
Merge branch 'master' into feat/dft_upgrade
harkal Oct 29, 2024
9b7b01e
refactor
harkal Oct 30, 2024
0925547
Merge branch 'master' into feat/dft_upgrade
harkal Oct 30, 2024
6891e7f
lint
harkal Oct 30, 2024
f7c6e94
improve offspring cost - ignore store chains
charles-cooper Nov 10, 2024
0725890
Merge branch 'master' into feat/dft_upgrade
charles-cooper Nov 12, 2024
a80c7bd
Merge branch 'master' into feat/dft_upgrade
charles-cooper Nov 12, 2024
39c27bb
add a comment
charles-cooper Nov 12, 2024
1f53984
Merge branch 'master' into feat/dft_upgrade
charles-cooper Nov 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions vyper/ir/compile_ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,9 @@ def _stack_peephole_opts(assembly):
if assembly[i] == "SWAP1" and assembly[i + 1].lower() in COMMUTATIVE_OPS:
changed = True
del assembly[i]
if assembly[i] == "DUP1" and assembly[i + 1] == "SWAP1":
changed = True
del assembly[i + 1]
i += 1

return changed
Expand Down
2 changes: 1 addition & 1 deletion vyper/semantics/analysis/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,7 @@ def _import_to_path(level: int, module_str: str) -> PurePath:
base_path = "../" * (level - 1)
elif level == 1:
base_path = "./"
return PurePath(f"{base_path}{module_str.replace('.','/')}/")
return PurePath(f"{base_path}{module_str.replace('.', '/')}/")


# can add more, e.g. "vyper.builtins.interfaces", etc.
Expand Down
2 changes: 2 additions & 0 deletions vyper/venom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from typing import Optional

from vyper.venom.passes.store_expansion import StoreExpansionPass
from vyper.codegen.ir_node import IRnode
from vyper.compiler.settings import OptimizationLevel
from vyper.venom.analysis.analysis import IRAnalysesCache
Expand Down Expand Up @@ -56,6 +57,7 @@ def _run_passes(fn: IRFunction, optimize: OptimizationLevel) -> None:
BranchOptimizationPass(ac, fn).run_pass()
ExtractLiteralsPass(ac, fn).run_pass()
RemoveUnusedVariablesPass(ac, fn).run_pass()
StoreExpansionPass(ac, fn).run_pass()
DFTPass(ac, fn).run_pass()


Expand Down
2 changes: 1 addition & 1 deletion vyper/venom/analysis/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ def request_analysis(self, analysis_cls: Type[IRAnalysis], *args, **kwargs):
if analysis_cls in self.analyses_cache:
return self.analyses_cache[analysis_cls]
analysis = analysis_cls(self, self.function)
self.analyses_cache[analysis_cls] = analysis
analysis.analyze(*args, **kwargs)

self.analyses_cache[analysis_cls] = analysis
return analysis

def invalidate_analysis(self, analysis_cls: Type[IRAnalysis]):
Expand Down
2 changes: 1 addition & 1 deletion vyper/venom/analysis/cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def analyze(self) -> None:
for bb in fn.get_basic_blocks():
assert len(bb.instructions) > 0, "Basic block should not be empty"
last_inst = bb.instructions[-1]
assert last_inst.is_bb_terminator, f"Last instruction should be a terminator {bb}"
assert last_inst.is_bb_terminator, "Last instruction should be a terminator"

for inst in bb.instructions:
if inst.opcode in CFG_ALTERING_INSTRUCTIONS:
Expand Down
8 changes: 7 additions & 1 deletion vyper/venom/analysis/dfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from vyper.venom.analysis.analysis import IRAnalysesCache, IRAnalysis
from vyper.venom.analysis.liveness import LivenessAnalysis
from vyper.venom.basicblock import IRInstruction, IRVariable
from vyper.venom.basicblock import IRBasicBlock, IRInstruction, IRVariable
from vyper.venom.function import IRFunction


Expand All @@ -19,6 +19,12 @@ def __init__(self, analyses_cache: IRAnalysesCache, function: IRFunction):
def get_uses(self, op: IRVariable) -> list[IRInstruction]:
return self._dfg_inputs.get(op, [])

def get_uses_in_bb(self, op: IRVariable, bb: IRBasicBlock):
"""
Get uses of a given variable in a specific basic block.
"""
return [inst for inst in self.get_uses(op) if inst.parent == bb]

# the instruction which produces this variable.
def get_producing_instruction(self, op: IRVariable) -> Optional[IRInstruction]:
return self._dfg_outputs.get(op)
Expand Down
2 changes: 1 addition & 1 deletion vyper/venom/analysis/liveness.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def _calculate_out_vars(self, bb: IRBasicBlock) -> bool:
Compute out_vars of basic block.
Returns True if out_vars changed
"""
out_vars = bb.out_vars
out_vars = bb.out_vars.copy()
bb.out_vars = OrderedSet()
for out_bb in bb.cfg_out:
target_vars = self.input_vars_from(bb, out_bb)
Expand Down
80 changes: 72 additions & 8 deletions vyper/venom/basicblock.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import TYPE_CHECKING, Any, Iterator, Optional, Union

import vyper.venom.effects as effects
from vyper.codegen.ir_node import IRnode
from vyper.utils import OrderedSet

Expand All @@ -21,8 +22,6 @@
"istore",
"tload",
"tstore",
"assert",
"assert_unreachable",
"mstore",
"mload",
"calldatacopy",
Expand Down Expand Up @@ -210,7 +209,6 @@
# set of live variables at this instruction
liveness: OrderedSet[IRVariable]
parent: "IRBasicBlock"
fence_id: int
annotation: Optional[str]
ast_source: Optional[IRnode]
error_msg: Optional[str]
Expand All @@ -227,7 +225,6 @@
self.operands = list(operands) # in case we get an iterator
self.output = output
self.liveness = OrderedSet()
self.fence_id = -1
self.annotation = None
self.ast_source = None
self.error_msg = None
Expand All @@ -239,6 +236,34 @@
@property
def is_bb_terminator(self) -> bool:
return self.opcode in BB_TERMINATORS

def get_read_effects(self):
Fixed Show fixed Hide fixed
return effects.reads.get(self.opcode, ())

def get_write_effects(self):
Fixed Show fixed Hide fixed
return effects.writes.get(self.opcode, ())

@property
def is_phi(self) -> bool:
return self.opcode == "phi"

@property
def is_param(self) -> bool:
return self.opcode == "param"

@property
def is_pseudo(self) -> bool:
"""
Check if instruction is pseudo, i.e. not an actual instruction but
a construct for intermediate representation like phi and param.
"""
return self.is_phi or self.is_param

def get_read_effects(self):
return effects.reads.get(self.opcode, effects.EMPTY)

def get_write_effects(self):
return effects.writes.get(self.opcode, effects.EMPTY)

def get_label_operands(self) -> Iterator[IRLabel]:
"""
Expand Down Expand Up @@ -319,6 +344,20 @@
return inst.ast_source
return self.parent.parent.ast_source

def str_short(self) -> str:
s = ""
if self.output:
s += f"{self.output} = "
opcode = f"{self.opcode} " if self.opcode != "store" else ""
s += opcode
operands = self.operands
if opcode not in ["jmp", "jnz", "invoke"]:
operands = list(reversed(operands))
s += ", ".join(
[(f"label %{op}" if isinstance(op, IRLabel) else str(op)) for op in operands]
)
return s

def __repr__(self) -> str:
s = ""
if self.output:
Expand All @@ -335,10 +374,7 @@
if self.annotation:
s += f" <{self.annotation}>"

if self.liveness:
return f"{s: <30} # {self.liveness}"

return s
return f"{s: <30}"


def _ir_operand_from_value(val: Any) -> IROperand:
Expand Down Expand Up @@ -477,6 +513,34 @@
def clear_instructions(self) -> None:
self.instructions = []

@property
def phi_instructions(self) -> Iterator[IRInstruction]:
for inst in self.instructions:
if inst.opcode == "phi":
yield inst
else:
return

@property
def non_phi_instructions(self) -> Iterator[IRInstruction]:
return (inst for inst in self.instructions if inst.opcode != "phi")

@property
def param_instructions(self) -> Iterator[IRInstruction]:
for inst in self.instructions:
if inst.opcode == "param":
yield inst
else:
return

@property
def pseudo_instructions(self) -> Iterator[IRInstruction]:
return (inst for inst in self.instructions if inst.is_pseudo)

@property
def body_instructions(self) -> Iterator[IRInstruction]:
return (inst for inst in self.instructions[:-1] if not inst.is_pseudo)

def replace_operands(self, replacements: dict) -> None:
"""
Update operands with replacements.
Expand Down
59 changes: 59 additions & 0 deletions vyper/venom/effects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from enum import Flag, auto


class Effects(Flag):
STORAGE = auto()
TRANSIENT = auto()
MEMORY = auto()
IMMUTABLES = auto()
BALANCE = auto()
RETURNDATA = auto()


EMPTY = Effects(0)
ALL = ~EMPTY
STORAGE = Effects.STORAGE
TRANSIENT = Effects.TRANSIENT
MEMORY = Effects.MEMORY
IMMUTABLES = Effects.IMMUTABLES
BALANCE = Effects.BALANCE
RETURNDATA = Effects.RETURNDATA


writes = {
"sstore": STORAGE,
"tstore": TRANSIENT,
"mstore": MEMORY,
"istore": IMMUTABLES,
"call": ALL,
"delegatecall": ALL,
"staticcall": MEMORY | RETURNDATA,
"create": ALL,
"create2": ALL,
"invoke": ALL, # could be smarter, look up the effects of the invoked function
"dloadbytes": MEMORY,
"returndatacopy": MEMORY,
"calldatacopy": MEMORY,
"codecopy": MEMORY,
"extcodecopy": MEMORY,
"mcopy": MEMORY,
}

reads = {
"sload": STORAGE,
"tload": TRANSIENT,
"iload": IMMUTABLES,
"mload": MEMORY,
"mcopy": MEMORY,
"call": ALL,
"delegatecall": ALL,
"staticcall": ALL,
"returndatasize": RETURNDATA,
"returndatacopy": RETURNDATA,
"balance": BALANCE,
"selfbalance": BALANCE,
"log": MEMORY,
"revert": MEMORY,
"return": MEMORY,
"sha3": MEMORY,
}
Loading
Loading