Skip to content

Commit

Permalink
refactor[venom]: remove dup_requirements analysis (vyperlang#4262)
Browse files Browse the repository at this point in the history
this commit updates `next_liveness` to reflect `out_vars` when the
instruction is the last instruction in the basic block.

after this change, membership in `dup_requirements` is the same as
membership in `next_liveness`, so we can remove the `dup_requirements`
analysis.
  • Loading branch information
charles-cooper authored Sep 28, 2024
1 parent b83bc98 commit e21f3e8
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 27 deletions.
15 changes: 0 additions & 15 deletions vyper/venom/analysis/dup_requirements.py

This file was deleted.

2 changes: 0 additions & 2 deletions vyper/venom/basicblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ class IRInstruction:
output: Optional[IROperand]
# set of live variables at this instruction
liveness: OrderedSet[IRVariable]
dup_requirements: OrderedSet[IRVariable]
parent: "IRBasicBlock"
fence_id: int
annotation: Optional[str]
Expand All @@ -228,7 +227,6 @@ def __init__(
self.operands = list(operands) # in case we get an iterator
self.output = output
self.liveness = OrderedSet()
self.dup_requirements = OrderedSet()
self.fence_id = -1
self.annotation = None
self.ast_source = None
Expand Down
24 changes: 14 additions & 10 deletions vyper/venom/venom_to_assembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
)
from vyper.utils import MemoryPositions, OrderedSet
from vyper.venom.analysis.analysis import IRAnalysesCache
from vyper.venom.analysis.dup_requirements import DupRequirementsAnalysis
from vyper.venom.analysis.liveness import LivenessAnalysis
from vyper.venom.basicblock import (
IRBasicBlock,
Expand Down Expand Up @@ -153,7 +152,6 @@ def generate_evm(self, no_optimize: bool = False) -> list[str]:

NormalizationPass(ac, fn).run_pass()
self.liveness_analysis = ac.request_analysis(LivenessAnalysis)
ac.request_analysis(DupRequirementsAnalysis)

assert fn.normalized, "Non-normalized CFG!"

Expand Down Expand Up @@ -231,7 +229,12 @@ def _stack_reorder(
return cost

def _emit_input_operands(
self, assembly: list, inst: IRInstruction, ops: list[IROperand], stack: StackModel
self,
assembly: list,
inst: IRInstruction,
ops: list[IROperand],
stack: StackModel,
next_liveness: OrderedSet[IRVariable],
) -> None:
# PRE: we already have all the items on the stack that have
# been scheduled to be killed. now it's just a matter of emitting
Expand All @@ -241,7 +244,7 @@ def _emit_input_operands(
# it with something that is wanted
if ops and stack.height > 0 and stack.peek(0) not in ops:
for op in ops:
if isinstance(op, IRVariable) and op not in inst.dup_requirements:
if isinstance(op, IRVariable) and op not in next_liveness:
self.swap_op(assembly, stack, op)
break

Expand All @@ -264,7 +267,7 @@ def _emit_input_operands(
stack.push(op)
continue

if op in inst.dup_requirements and op not in emitted_ops:
if op in next_liveness and op not in emitted_ops:
self.dup_op(assembly, stack, op)

if op in emitted_ops:
Expand All @@ -288,7 +291,9 @@ def _generate_evm_for_basicblock_r(
all_insts = sorted(basicblock.instructions, key=lambda x: x.opcode != "param")

for i, inst in enumerate(all_insts):
next_liveness = all_insts[i + 1].liveness if i + 1 < len(all_insts) else OrderedSet()
next_liveness = (
all_insts[i + 1].liveness if i + 1 < len(all_insts) else basicblock.out_vars
)

asm.extend(self._generate_evm_for_instruction(inst, stack, next_liveness))

Expand Down Expand Up @@ -327,10 +332,9 @@ def clean_stack_from_cfg_in(
self.pop(asm, stack)

def _generate_evm_for_instruction(
self, inst: IRInstruction, stack: StackModel, next_liveness: OrderedSet = None
self, inst: IRInstruction, stack: StackModel, next_liveness: OrderedSet
) -> list[str]:
assembly: list[str | int] = []
next_liveness = next_liveness or OrderedSet()
opcode = inst.opcode

#
Expand Down Expand Up @@ -375,7 +379,7 @@ def _generate_evm_for_instruction(
# example, for `%56 = %label1 %13 %label2 %14`, we will
# find an instance of %13 *or* %14 in the stack and replace it with %56.
to_be_replaced = stack.peek(depth)
if to_be_replaced in inst.dup_requirements:
if to_be_replaced in next_liveness:
# %13/%14 is still live(!), so we make a copy of it
self.dup(assembly, stack, depth)
stack.poke(0, ret)
Expand All @@ -390,7 +394,7 @@ def _generate_evm_for_instruction(
return apply_line_numbers(inst, assembly)

# Step 2: Emit instruction's input operands
self._emit_input_operands(assembly, inst, operands, stack)
self._emit_input_operands(assembly, inst, operands, stack, next_liveness)

# Step 3: Reorder stack before join points
if opcode == "jmp":
Expand Down

0 comments on commit e21f3e8

Please sign in to comment.