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]: store expansion pass #4068

Merged
merged 32 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
6cf7b6b
feat[venom]: extract literals pass
charles-cooper May 30, 2024
ef7c369
feat: store expansion pass
charles-cooper May 31, 2024
ff700b4
lint
charles-cooper May 31, 2024
ea9b1c5
remove inter-bb restriction
charles-cooper May 31, 2024
adbf01c
don't replace first use
charles-cooper May 31, 2024
aa2234c
fix bugs
charles-cooper Jun 1, 2024
b6b7aed
allow inter-bb
charles-cooper Jun 1, 2024
a71cad8
lint
charles-cooper Jun 1, 2024
163979b
fix a bug
charles-cooper Jun 4, 2024
61ea577
fix algorithm a bit
charles-cooper Jun 5, 2024
e3e926d
Merge branch 'master' into feat/store-expansion
charles-cooper Sep 9, 2024
ab4055e
Merge branch 'master' into feat/store-expansion
charles-cooper Sep 19, 2024
d233a75
Merge branch 'master' into feat/store-expansion
charles-cooper Sep 25, 2024
669c170
fix store expansion - expand close to the use site, not the productio…
charles-cooper Sep 25, 2024
248370d
fix lint
charles-cooper Sep 25, 2024
7313acf
fuse store expansion and literal extraction passes
charles-cooper Sep 25, 2024
fe215d9
cleanup - rename extract literals to store_expansion
charles-cooper Sep 25, 2024
a22f5c9
reorder store expansion and unused var elimination
charles-cooper Sep 25, 2024
0b0851a
Merge branch 'master' into feat/store-expansion
charles-cooper Sep 28, 2024
f843eca
simplify emit_input_operands
charles-cooper Sep 28, 2024
1bf0173
remove a heuristic
charles-cooper Sep 28, 2024
54d7e97
add equivalence analysis
charles-cooper Sep 21, 2024
42785ed
fix lint
charles-cooper Sep 28, 2024
a367b1d
fix lint, tests
charles-cooper Sep 28, 2024
b8ae0d1
add a note
charles-cooper Sep 29, 2024
df469c6
strength an assertion
charles-cooper Sep 29, 2024
2ae3ea9
add some comments
charles-cooper Sep 29, 2024
eadd44e
simplify some code
charles-cooper Sep 30, 2024
c8c240b
add an invariant
charles-cooper Sep 30, 2024
fc45007
Merge branch 'master' into feat/store-expansion
charles-cooper Oct 4, 2024
aa94d2e
fix up test
charles-cooper Oct 4, 2024
dc8c554
Merge branch 'master' into feat/store-expansion
charles-cooper Oct 4, 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
4 changes: 4 additions & 0 deletions vyper/venom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
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
from vyper.venom.passes.sccp import SCCP
from vyper.venom.passes.simplify_cfg import SimplifyCFGPass
from vyper.venom.passes.store_elimination import StoreElimination
from vyper.venom.passes.store_expansion import StoreExpansionPass
from vyper.venom.venom_to_assembly import VenomCompiler

DEFAULT_OPT_LEVEL = OptimizationLevel.default()
Expand Down Expand Up @@ -53,6 +55,8 @@ 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()
StoreExpansionPass(ac, fn).run_pass()
RemoveUnusedVariablesPass(ac, fn).run_pass()
DFTPass(ac, fn).run_pass()

Expand Down
38 changes: 38 additions & 0 deletions vyper/venom/passes/extract_literals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from vyper.utils import OrderedSet
Fixed Show fixed Hide fixed
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
49 changes: 49 additions & 0 deletions vyper/venom/passes/store_expansion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from vyper.venom.analysis.cfg import CFGAnalysis
from vyper.venom.analysis.dfg import DFGAnalysis
from vyper.venom.analysis.dominators import DominatorTreeAnalysis
Fixed Show fixed Hide fixed
from vyper.venom.analysis.liveness import LivenessAnalysis
from vyper.venom.basicblock import IRInstruction, IRVariable
Fixed Show fixed Hide fixed
from vyper.venom.passes.base_pass import IRPass


class StoreExpansionPass(IRPass):
"""
This pass expands variables to their uses though `store` instructions,
reducing pressure on the stack scheduler
"""

def run_pass(self):
self.analyses_cache.request_analysis(CFGAnalysis)
dfg = self.analyses_cache.request_analysis(DFGAnalysis)
Fixed Show fixed Hide fixed

for bb in self.function.get_basic_blocks():
for idx, inst in enumerate(bb.instructions):
if inst.opcode != "store":
continue

self._process_inst(dfg, inst, idx)

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

def _process_inst(self, dfg, inst, idx):
"""
Process store instruction. If the variable is only used by a load instruction,
forward the variable to the load instruction.
"""
var = inst.output
uses = dfg.get_uses(var)

insertion_idx = idx + 1

for use_inst in uses:
if use_inst.parent != inst.parent:
continue

for i, operand in enumerate(use_inst.operands):
if operand == var:
new_var = self.function.get_next_variable()
new_inst = IRInstruction("store", [var], new_var)
inst.parent.insert_instruction(new_inst, insertion_idx)
insertion_idx += 1
use_inst.operands[i] = new_var
Loading