Skip to content

Commit

Permalink
Merge branch 'feature/venom_updates' of github.com:harkal/vyper into …
Browse files Browse the repository at this point in the history
…feature/venom_updates
  • Loading branch information
charles-cooper committed Mar 19, 2024
2 parents d7ef9ef + 84f1b69 commit 540b71a
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 31 deletions.
3 changes: 0 additions & 3 deletions vyper/compiler/phases.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,6 @@ def __init__(

_ = self._generate_ast # force settings to be calculated

# to force experimental codegen, uncomment:
# self.settings.experimental_codegen = True

@cached_property
def source_code(self):
return self.file_input.source_code
Expand Down
5 changes: 3 additions & 2 deletions vyper/venom/analysis.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from typing import Optional
from vyper.exceptions import CompilerPanic
from vyper.utils import OrderedSet
from vyper.venom.basicblock import (
Expand Down Expand Up @@ -144,8 +145,8 @@ def get_uses(self, op: IRVariable) -> list[IRInstruction]:
return self._dfg_inputs.get(op, [])

# the instruction which produces this variable.
def get_producing_instruction(self, op: IRVariable) -> IRInstruction:
return self._dfg_outputs[op]
def get_producing_instruction(self, op: IRVariable) -> Optional[IRInstruction]:
return self._dfg_outputs.get(op)

@classmethod
def build_dfg(cls, ctx: IRFunction) -> "DFG":
Expand Down
15 changes: 0 additions & 15 deletions vyper/venom/dominators.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,6 @@ def _compute_dominators(self):
self.dominators[bb] = new_dominators
changed = True

# for bb in basic_blocks:
# print(bb.label)
# for dom in self.dominators[bb]:
# print(" ", dom.label)

def _compute_idoms(self):
"""
Compute immediate dominators
Expand All @@ -85,11 +80,6 @@ def _compute_idoms(self):
for dom, target in self.idoms.items():
self.dominated[target].add(dom)

# for dom, targets in self.dominated.items():
# print(dom.label)
# for t in targets:
# print(" ", t.label)

def _compute_df(self):
"""
Compute dominance frontier
Expand All @@ -105,11 +95,6 @@ def _compute_df(self):
self.df[runner].add(bb)
runner = self.idoms[runner]

# for bb in self.dfs:
# print(bb.label)
# for df in self.df[bb]:
# print(" ", df.label)

def dominance_frontier(self, basic_blocks: list[IRBasicBlock]) -> OrderedSet[IRBasicBlock]:
"""
Compute dominance frontier of a set of basic blocks.
Expand Down
6 changes: 3 additions & 3 deletions vyper/venom/passes/dft.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from vyper.venom.passes.base_pass import IRPass


# DataFlow Transformation
class DFTPass(IRPass):
def _process_instruction_r(self, bb: IRBasicBlock, inst: IRInstruction):
if inst in self.visited_instructions:
Expand All @@ -18,9 +17,9 @@ def _process_instruction_r(self, bb: IRBasicBlock, inst: IRInstruction):
bb.instructions.append(inst)
return

for op in inst.get_inputs():
for op in inst.liveness:
target = self.dfg.get_producing_instruction(op)
if target.parent != inst.parent or target.fence_id != inst.fence_id:
if target is None or target.parent != inst.parent or target.fence_id != inst.fence_id:
# don't reorder across basic block or fence boundaries
continue
self._process_instruction_r(bb, target)
Expand All @@ -44,6 +43,7 @@ def _process_basic_block(self, bb: IRBasicBlock) -> None:
def _run_pass(self, ctx: IRFunction) -> None:
self.ctx = ctx
self.dfg = DFG.build_dfg(ctx)

self.fence_id = 0
self.visited_instructions: OrderedSet[IRInstruction] = OrderedSet()

Expand Down
15 changes: 13 additions & 2 deletions vyper/venom/passes/make_ssa.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@


class MakeSSA(IRPass):
"""
This pass converts the function into Static Single Assignment (SSA) form.
"""

dom: DominatorTree
defs: dict[IRVariable, OrderedSet[IRBasicBlock]]

Expand All @@ -29,6 +33,9 @@ def _run_pass(self, ctx: IRFunction, entry: IRBasicBlock) -> int:
return 0

def _add_phi_nodes(self):
"""
Add phi nodes to the function.
"""
self._compute_defs()
self.work = {var: 0 for var in self.dom.dfs}
self.has_already = {var: 0 for var in self.dom.dfs}
Expand Down Expand Up @@ -84,6 +91,9 @@ def _add_phi(self, var: IRVariable, basic_block: IRBasicBlock) -> bool:
return True

def _rename_vars(self, basic_block: IRBasicBlock):
"""
Rename variables in the basic block. This follows the placement of phi nodes.
"""
outs = []
for inst in basic_block.instructions:
new_ops = []
Expand Down Expand Up @@ -139,8 +149,6 @@ def _remove_degenerate_phis(self, entry: IRBasicBlock):
entry.instructions.remove(inst)
elif new_ops_len == 2:
entry.instructions.remove(inst)
# inst.opcode = "store"
# inst.operands = [new_ops[1]]
else:
inst.operands = new_ops

Expand All @@ -150,6 +158,9 @@ def _remove_degenerate_phis(self, entry: IRBasicBlock):
self._remove_degenerate_phis(bb)

def _compute_defs(self):
"""
Compute the definition points of variables in the function.
"""
self.defs = {}
for bb in self.dom.dfs:
assignments = bb.get_assignments()
Expand Down
21 changes: 16 additions & 5 deletions vyper/venom/passes/simplify_cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ def _merge_blocks(self, a: IRBasicBlock, b: IRBasicBlock):
else:
inst.parent = a
a.instructions.append(inst)
a.cfg_out = b.cfg_out

for n in b.cfg_out:
n.remove_cfg_in(b)
n.add_cfg_in(a)
# Update CFG
a.cfg_out = b.cfg_out
if len(b.cfg_out) > 0:
next = b.cfg_out.first()
next.remove_cfg_in(b)
next.add_cfg_in(a)

self.ctx.basic_blocks.remove(b)

Expand All @@ -29,20 +31,26 @@ def _merge_jump(self, a: IRBasicBlock, b: IRBasicBlock):
jump_inst = a.instructions[-1]
assert b.label in jump_inst.operands, f"{b.label} {jump_inst.operands}"
jump_inst.operands[jump_inst.operands.index(b.label)] = next.label

# Update CFG
a.remove_cfg_out(b)
a.add_cfg_out(next)
next.remove_cfg_in(b)
next.add_cfg_in(a)

self.ctx.basic_blocks.remove(b)

def _collapse_chained_blocks_r(self, bb: IRBasicBlock):
"""
DFS into the cfg and collapse blocks with a single predecessor to the predecessor
"""
if len(bb.cfg_out) == 1:
next = bb.cfg_out.first()
if len(next.cfg_in) == 1:
self._merge_blocks(bb, next)
self._collapse_chained_blocks_r(bb)
return
elif len(bb.cfg_out) == 2:
elif len(bb.cfg_out) > 1:
bb_out = bb.cfg_out.copy()
for next in bb_out:
if len(next.cfg_in) == 1 and len(next.cfg_out) == 1 and len(next.instructions) == 1:
Expand All @@ -58,6 +66,9 @@ def _collapse_chained_blocks_r(self, bb: IRBasicBlock):
self._collapse_chained_blocks_r(bb_out)

def _collapse_chained_blocks(self, entry: IRBasicBlock):
"""
Collapse blocks with a single predecessor to their predecessor
"""
self.visited = OrderedSet()
self._collapse_chained_blocks_r(entry)

Expand Down
12 changes: 11 additions & 1 deletion vyper/venom/venom_to_assembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,10 +530,20 @@ def pop(self, assembly, stack, num=1):
assembly.extend(["POP"] * num)

def swap(self, assembly, stack, depth):
# Swaps of the top is no op
if depth == 0:
return

inst = _evm_swap_for(depth)

# Double swaps cancel each other out
if len(assembly) > 0 and inst == assembly[-1]:
assembly.pop()
stack.swap(depth)
return

stack.swap(depth)
assembly.append(_evm_swap_for(depth))
assembly.append(inst)

def dup(self, assembly, stack, depth):
stack.dup(depth)
Expand Down

0 comments on commit 540b71a

Please sign in to comment.