Skip to content

Commit

Permalink
feat[venom]: add extract_literals pass (#4067)
Browse files Browse the repository at this point in the history
extract `IRLiterals` which are instruction arguments; this reduces
pressure on the stack scheduler because `_emit_input_operands` can cause
stack storms when we hit `_stack_reorder`. by extracting them, we allow
`DFTPass` to reorder literal emission in a more optimized way before
even getting to `_emit_input_operands`
  • Loading branch information
charles-cooper authored May 31, 2024
1 parent 7b0ee5f commit bb9129a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
2 changes: 2 additions & 0 deletions vyper/venom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from vyper.venom.passes.algebraic_optimization import AlgebraicOptimizationPass
from vyper.venom.passes.branch_optimization import BranchOptimizationPass
from vyper.venom.passes.dft import DFTPass
from vyper.venom.passes.extract_literals import ExtractLiteralsPass
from vyper.venom.passes.make_ssa import MakeSSA
from vyper.venom.passes.mem2var import Mem2Var
from vyper.venom.passes.remove_unused_variables import RemoveUnusedVariablesPass
Expand Down Expand Up @@ -53,6 +54,7 @@ def _run_passes(fn: IRFunction, optimize: OptimizationLevel) -> None:
SimplifyCFGPass(ac, fn).run_pass()
AlgebraicOptimizationPass(ac, fn).run_pass()
BranchOptimizationPass(ac, fn).run_pass()
ExtractLiteralsPass(ac, fn).run_pass()
RemoveUnusedVariablesPass(ac, fn).run_pass()
DFTPass(ac, fn).run_pass()

Expand Down
37 changes: 37 additions & 0 deletions vyper/venom/passes/extract_literals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from vyper.venom.analysis.dfg import DFGAnalysis
from vyper.venom.analysis.liveness import LivenessAnalysis
from vyper.venom.basicblock import IRInstruction, IRLiteral
from vyper.venom.passes.base_pass import IRPass


class ExtractLiteralsPass(IRPass):
"""
This pass extracts literals so that they can be reordered by the DFT pass
"""

def run_pass(self):
for bb in self.function.get_basic_blocks():
self._process_bb(bb)

self.analyses_cache.invalidate_analysis(DFGAnalysis)
self.analyses_cache.invalidate_analysis(LivenessAnalysis)

def _process_bb(self, bb):
i = 0
while i < len(bb.instructions):
inst = bb.instructions[i]
if inst.opcode == "store":
i += 1
continue

for j, op in enumerate(inst.operands):
# first operand to log is magic
if inst.opcode == "log" and j == 0:
continue

if isinstance(op, IRLiteral):
var = self.function.get_next_variable()
to_insert = IRInstruction("store", [op], var)
bb.insert_instruction(to_insert, index=i)
inst.operands[j] = var
i += 1

0 comments on commit bb9129a

Please sign in to comment.