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: implement new IR for vyper (venom IR) #3659

Merged
merged 488 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
488 commits
Select commit Hold shift + click to select a range
4c5965f
get next instruction
harkal Oct 17, 2023
fd5f49e
forward
harkal Oct 17, 2023
8c4ce2b
ordered set constructor
harkal Oct 17, 2023
de2e2b5
passes refactor
harkal Oct 17, 2023
84f8e75
passes
harkal Oct 17, 2023
4cb921d
optimization
harkal Oct 17, 2023
ac54557
constant propagation
harkal Oct 17, 2023
5dd39b0
more refactor
harkal Oct 18, 2023
38e4a0f
cleanup
harkal Oct 18, 2023
58cbd12
cleanup
harkal Oct 18, 2023
4a6a7d9
ir_pass decorator
harkal Oct 18, 2023
6db1d87
make passes
harkal Oct 18, 2023
d7e2bbf
ir passes calling
harkal Oct 18, 2023
bb5aa8c
immutables cherry-pick
harkal Oct 18, 2023
caad6df
compute dup requirements
harkal Oct 22, 2023
1d4cd36
add dup_requirements to IRInstruction
harkal Oct 22, 2023
24a78e6
recalculations
harkal Oct 22, 2023
574d523
recursive dup insertion
harkal Oct 23, 2023
d390281
temporary
harkal Oct 23, 2023
da042a1
temporary
harkal Oct 23, 2023
cfa2f54
fixed
harkal Oct 23, 2023
466f393
disable dfg pass for now
harkal Oct 23, 2023
19917df
remove the use of .use_count
harkal Oct 23, 2023
c5a38ee
more cleanup of unused code after the stack handling update
harkal Oct 23, 2023
6dbea92
more clean up
harkal Oct 23, 2023
3b2ebaa
Remove all phi_var related code
harkal Oct 23, 2023
770b5eb
refactor out "last instr" dup code
harkal Oct 23, 2023
845cf0d
Merge remote-tracking branch 'origin/master' into feature/ir_rewrite
harkal Oct 23, 2023
14dd24b
fix formating
harkal Oct 23, 2023
a6c8a97
cleanups, code style
harkal Oct 23, 2023
99df45e
isort
harkal Oct 23, 2023
3308fbe
type checks
harkal Oct 23, 2023
994d742
typofix
harkal Oct 23, 2023
ddf4bb0
amend unterminated blocks with jmps
harkal Oct 24, 2023
d63d73a
fix typo
harkal Oct 24, 2023
5eab147
linter fixes
harkal Oct 24, 2023
87fa45c
remove unused code
harkal Oct 24, 2023
c56f67c
remove unnecessary defaults
harkal Oct 24, 2023
3dceb38
no poping required with new scheduling
harkal Oct 25, 2023
3504d80
remove return type and statement
harkal Oct 26, 2023
fb273db
remove IRFunctionBase
harkal Oct 26, 2023
980642b
add some review comments, rename in_set/out_set to cfg_in/cfg_out
charles-cooper Oct 26, 2023
024d891
remove None target for in_vars_for, add review comments
charles-cooper Oct 26, 2023
a5df008
add more comments, rename TERMINATOR_INSTRUCTIONS
charles-cooper Oct 26, 2023
fded614
add review comments
charles-cooper Oct 26, 2023
21f36ea
remove dead code
charles-cooper Oct 26, 2023
9cf815c
rename `in_vars_for` to `in_vars_from`
charles-cooper Oct 28, 2023
5b43039
add some OrderedSet hygiene
charles-cooper Oct 28, 2023
4554e6f
fix stability of _get_symbols_common
charles-cooper Oct 28, 2023
0eea288
add more review comments, OrderedSet hygiene
charles-cooper Oct 28, 2023
c10e964
simplify _stack_reorder
charles-cooper Oct 28, 2023
2d90a0c
always use experimental_codegen - for now
charles-cooper Oct 28, 2023
e1f4e4f
fix an optimization
charles-cooper Oct 28, 2023
a97d352
add more tracing
charles-cooper Oct 28, 2023
7d4088e
add some review comments
charles-cooper Oct 28, 2023
0bf2277
clean up recursion into emit_instruction
charles-cooper Oct 28, 2023
b0ad061
remove no longer used is_terminal()
harkal Oct 30, 2023
0e50f78
correct typo
harkal Oct 30, 2023
3729aee
remove unused definition
harkal Oct 30, 2023
1fd8728
remove unneeded .keys()
harkal Oct 30, 2023
24854b4
various small review tweaks
harkal Oct 30, 2023
7f33aac
remove unused instruction dbg info
harkal Oct 30, 2023
9f5d32c
group passthrough instructions
harkal Oct 30, 2023
e0351d8
StackModel and stack_map rename
harkal Oct 30, 2023
48aac0f
move stack model to venom directory
harkal Oct 30, 2023
3133fb6
Refactor directory structure
harkal Oct 30, 2023
31f0426
remove ir_ prefix from filenames in venom directory
harkal Oct 30, 2023
8026205
use remove_cfg_in()
harkal Oct 30, 2023
9c1fbc3
select -> phi, and various small review replies
harkal Oct 30, 2023
87e67b2
rename get_input_operands and get_output_operands
harkal Oct 30, 2023
a867abd
replace [::-1] with reversed where posible
harkal Oct 30, 2023
4884248
volatile instructions global
harkal Oct 30, 2023
ccd1bf6
MemType top level
harkal Oct 30, 2023
91256e6
stack_map -> stack
harkal Oct 30, 2023
17f7fbf
get_depth cleanup
harkal Oct 30, 2023
08955f2
stack reorder and duplication always operate on IRValues
harkal Oct 30, 2023
9f6913d
cleanups
harkal Oct 30, 2023
c265396
further review
charles-cooper Oct 30, 2023
f185ecd
some organizational comments
charles-cooper Oct 30, 2023
af5819f
a couple more comments
charles-cooper Oct 30, 2023
4769aa4
restructure file tree
harkal Oct 31, 2023
56a08de
add review comment
harkal Oct 31, 2023
5927a76
api hygiene
charles-cooper Oct 31, 2023
2c725cb
use temp var in StackModel.swap
charles-cooper Oct 31, 2023
666aea1
add a couple review comments
charles-cooper Oct 31, 2023
a194747
index outputs and inputs by pointer of variable
harkal Oct 31, 2023
6ea9e24
add organizational comment
charles-cooper Oct 31, 2023
cc9a70b
remove dead DFGNode
harkal Oct 31, 2023
579bb2c
Merge branch 'feature/ir_rewrite' of github.com:harkal/vyper into fea…
harkal Oct 31, 2023
d738776
remove comments
harkal Oct 31, 2023
6057325
factor out DFG data structure into class
charles-cooper Oct 31, 2023
78262c9
Merge branch 'feature/ir_rewrite' of github.com:harkal/vyper into fea…
charles-cooper Oct 31, 2023
339a79c
rename get_output to get_assignment_instruction
charles-cooper Oct 31, 2023
58f212a
partially refactor out dft pass
charles-cooper Oct 31, 2023
8d4104d
add missing file
charles-cooper Oct 31, 2023
5e4deb3
simplify compute_dup_requirements and emit_evm_instruction
charles-cooper Oct 31, 2023
a82045b
add more review comments
charles-cooper Oct 31, 2023
28e487f
add a comment
charles-cooper Nov 1, 2023
88dcd5d
add a bit of review
charles-cooper Nov 1, 2023
829580d
add a heuristic to swap out top of stack
charles-cooper Nov 1, 2023
a0cbf85
Default constructor name for functions -> "global"
harkal Nov 2, 2023
a7a25e2
Fix the case where operands are used multiple times from an instruction
harkal Nov 2, 2023
396ad00
Amendment to the previous commit to handle a special case
harkal Nov 2, 2023
979383a
add review
charles-cooper Nov 2, 2023
84aa461
more review
charles-cooper Nov 2, 2023
d168901
Move NOT_IN_STACK asserts to StackModel
harkal Nov 2, 2023
748b0aa
Code simplification by providing stack operations dub_op and swap_op
harkal Nov 2, 2023
ffe7659
refactoring
harkal Nov 2, 2023
00fde3f
add some review
charles-cooper Nov 2, 2023
d637f2c
review
charles-cooper Nov 2, 2023
01ce696
add explanation for `phi` magic
charles-cooper Nov 2, 2023
07b8c7c
add review
charles-cooper Nov 2, 2023
6c6c883
ONE_TO_ONE_INSTRUCTIONS refactor
harkal Nov 3, 2023
d2ae3ac
rename calculate_cfg_in to calculate_cfg
harkal Nov 3, 2023
db598f3
rename ir.py to __init__.py
harkal Nov 3, 2023
f404238
move VenomCompiler to own module
harkal Nov 3, 2023
911a1f2
Remove unused parameters
harkal Nov 3, 2023
7da6d0c
Move ctx to the class
harkal Nov 3, 2023
ea0eadf
review comment
harkal Nov 3, 2023
14d8af8
Make StackMap decoupled from evm
harkal Nov 3, 2023
4cef5dd
review comments
harkal Nov 3, 2023
1e5d885
remove unsused variable
harkal Nov 3, 2023
b9978e6
Optimization: use set instead of list
harkal Nov 3, 2023
1348ce2
comment clean up
harkal Nov 3, 2023
ff3b145
clean up comments
harkal Nov 3, 2023
90e0891
simplified _process_instruction_r() ->smaller code
harkal Nov 3, 2023
ba0b51b
commutative handling scafolding
harkal Nov 3, 2023
0d6d5f6
imports cleanup
harkal Nov 3, 2023
43bf549
remove dead code
charles-cooper Nov 3, 2023
cb61ccb
review comments
charles-cooper Nov 3, 2023
e811dc9
style: rename some globals with initial underscore
charles-cooper Nov 3, 2023
ae0a182
rename ir_to_ modules for clarification
charles-cooper Nov 3, 2023
433598f
remove dead members on IRFunction,
charles-cooper Nov 3, 2023
a68da3b
fix
harkal Nov 3, 2023
d867b87
small style change
charles-cooper Nov 3, 2023
f75f432
change emitted_ops to set
charles-cooper Nov 3, 2023
b49811e
small additions to compute_dup_requirements
charles-cooper Nov 3, 2023
4202454
typo fix
harkal Nov 3, 2023
8dfe149
add out vars to IRBasicBlock.__repr__()
charles-cooper Nov 3, 2023
b4e9940
add review
charles-cooper Nov 3, 2023
689cc11
more review
charles-cooper Nov 3, 2023
dd2fdbb
add review
charles-cooper Nov 3, 2023
aa67349
fixed stack leftover regression
harkal Nov 5, 2023
27cf2b1
Refactor BINARY_IR_INSTRUCTIONS
harkal Nov 5, 2023
1ce0940
all passes return change counts
harkal Nov 5, 2023
e9c499a
review comment
harkal Nov 5, 2023
828d6b8
remove slipped code for other branch
harkal Nov 5, 2023
0d316e6
merge the dup requirements into liveness calculations
harkal Nov 5, 2023
63f57e4
import reorder, formating
harkal Nov 5, 2023
3818833
lint fixes
harkal Nov 5, 2023
f4c4e06
review: hide stack implementation
charles-cooper Nov 5, 2023
1ef2ee2
add a couple more review comments
charles-cooper Nov 5, 2023
429d75c
review items
harkal Nov 6, 2023
d38f6d9
Make stack private (_stack)
harkal Nov 6, 2023
cdf282b
Add __repr__() method to stack
harkal Nov 6, 2023
5767927
use self.pop()
harkal Nov 6, 2023
66ebc8a
remove inspection of private `_stack` member
charles-cooper Nov 6, 2023
bcc14cf
rename ret to output
harkal Nov 8, 2023
139affc
fix a local variable
charles-cooper Nov 8, 2023
c2a5114
update a couple docstrings
charles-cooper Nov 8, 2023
92a35ca
remove liveness from IRInstruction.__repr__
charles-cooper Nov 8, 2023
daf3df7
fix lint
charles-cooper Nov 8, 2023
2f0c27f
change default mem_addr
charles-cooper Nov 8, 2023
8cc542f
fix lint
charles-cooper Nov 8, 2023
7916185
some small cleanup
charles-cooper Nov 8, 2023
4e41460
Revert "remove liveness from IRInstruction.__repr__"
charles-cooper Nov 8, 2023
5accc3b
add another jump for hygiene
charles-cooper Nov 8, 2023
70b654f
factor out bb entry stack cleaning
charles-cooper Nov 8, 2023
d0b1645
fix params for clean_stack_for_cfg_in
charles-cooper Nov 8, 2023
535ee2d
move some functions into analysis.py
charles-cooper Nov 8, 2023
ac386ad
perf nit
charles-cooper Nov 8, 2023
4ac187a
rename a variable
charles-cooper Nov 8, 2023
260cecf
move input_vars_from and liveness analysis into analysis.py
charles-cooper Nov 8, 2023
548b216
add some comments, small style adjustments and remove is_commutative …
charles-cooper Nov 8, 2023
31aba53
fix lint
charles-cooper Nov 8, 2023
e7540fd
add a couple comments
charles-cooper Nov 8, 2023
7cd9030
add review comment
charles-cooper Nov 8, 2023
8b808eb
Add test for multi-entry block in Vyper compiler
harkal Nov 9, 2023
7be6321
Remove not wanted test and assertion
harkal Nov 9, 2023
264142a
Add normalization pass to split basic blocks with
harkal Nov 9, 2023
c7b50fa
Use normalize pass in multi-entry block test case
harkal Nov 9, 2023
ca42dc6
return changes from normalization pass
harkal Nov 13, 2023
40fa04b
remove review comment
harkal Nov 13, 2023
4591b00
Add normalized property to IRFunction
harkal Nov 13, 2023
821bedd
normalization pass return changes
harkal Nov 13, 2023
2f40fc5
dirty cfg tracking
harkal Nov 13, 2023
96bf316
Add CFG_ALTERING_OPS to basicblock imports
harkal Nov 13, 2023
3a36dc7
Refactor basic block module: use frozenset for
harkal Nov 13, 2023
a7c076d
Clear CFG dirty flag in calculate_cfg function
harkal Nov 13, 2023
b0cbca0
Add normalization check and control flow graph
harkal Nov 13, 2023
f6777e6
Remove redundant code for already normalized
harkal Nov 13, 2023
2134b48
Refactor multi-entry block test case
harkal Nov 13, 2023
7c573c5
lint
harkal Nov 13, 2023
bed0fe3
mypy lint
harkal Nov 13, 2023
b3e6b41
Add VariableRecord import and type annotations to
harkal Nov 13, 2023
da70812
Refactor OrderedSet class to use generics
harkal Nov 13, 2023
f60dc5d
Set called_functions type to ContractFunctionT
harkal Nov 13, 2023
104ee79
append_instruction does not return
harkal Nov 13, 2023
f24cbf1
Add return type None to append_data method.
harkal Nov 13, 2023
4389a81
Assert calculate_cfg function and add
harkal Nov 13, 2023
d8ec267
Add visited_instructions and visited_basicblocks
harkal Nov 13, 2023
317ea91
Make NOT_IN_STACK int
harkal Nov 13, 2023
6a0da61
Fix variable naming in DFG class method (mypy).
harkal Nov 13, 2023
c3dd681
Refactor IRInstruction constructor to allow for
harkal Nov 13, 2023
9661564
lint: add passthrough fields to FuncIR
harkal Nov 13, 2023
5a10513
lint
harkal Nov 13, 2023
5c5ecbb
Refactor NOT_IN_STACK constant in StackModel
harkal Nov 13, 2023
a3bd61f
Merge remote-tracking branch 'origin/master' into feature/ir_rewrite
harkal Nov 13, 2023
d9a67e8
Rename Normalization to NormalizationPass
harkal Nov 16, 2023
95c9721
small revert from feature/const_propagation changes
harkal Nov 20, 2023
cb57826
Merge remote-tracking branch 'origin' into feature/ir_rewrite
harkal Nov 22, 2023
0eabd92
rename IRValueBase to IRValue
charles-cooper Nov 22, 2023
29ab92b
add review
charles-cooper Nov 23, 2023
b83fd28
don't reverse on printout
harkal Nov 26, 2023
1a29685
remove review comment (resolved)
harkal Nov 27, 2023
f194103
remove outdated review discussion
harkal Nov 27, 2023
6ffb33a
Remove CFG tracking machinery
harkal Nov 27, 2023
a46bf71
fix mypy
charles-cooper Nov 28, 2023
36cce8b
remove some `is False`
charles-cooper Nov 28, 2023
54a2bea
refine the inheritance tree for IRValues
charles-cooper Nov 28, 2023
b664277
add sanity checks in add_cfg_in, add_cfg_out
charles-cooper Nov 28, 2023
38b537f
review: polish and fix cfg normalization
charles-cooper Nov 28, 2023
bcda7a4
disable experimental codegen by default
charles-cooper Nov 28, 2023
72b4b45
add a note
charles-cooper Nov 28, 2023
ec0a0ed
add readme (mostly written by harkal)
charles-cooper Nov 30, 2023
267cb2a
readme formatting
charles-cooper Nov 30, 2023
7044767
Merge remote-tracking branch 'origin/master' into feature/ir_rewrite
harkal Nov 30, 2023
632e554
Add experimental codegen flag to vyper_compile.py
harkal Nov 30, 2023
04d425b
Commented out liveness output in IRInstruction
harkal Nov 30, 2023
1d8059a
Use normalization pass
harkal Nov 30, 2023
db768dd
add note on pluggability
charles-cooper Nov 30, 2023
73399fc
reword normalization pass explanation
charles-cooper Dec 1, 2023
234c89c
Add comment for special case of jump to selector
harkal Dec 1, 2023
2109bb2
refactor starting point
harkal Dec 1, 2023
e1a1626
Dont throw in get_basic_block when bb not found
harkal Dec 1, 2023
9af2c84
Normalize basic blocks and split multiple incoming
harkal Dec 1, 2023
a50dc7e
Add adding and removing cfg_in and cfg_out in
harkal Dec 1, 2023
765044d
Fix dynamic jump normalization
harkal Dec 1, 2023
ac5b283
Fix cfg calculation, normalization and liveness calculation order
harkal Dec 1, 2023
fc06f02
Remove unused code
harkal Dec 1, 2023
b3f620b
Revert get_basic_block method changes
harkal Dec 1, 2023
ac59201
fix multi entry test
harkal Dec 1, 2023
600505e
Refactor NormalizationPass
harkal Dec 1, 2023
8a76658
Remove assert guarding against adding existing
harkal Dec 1, 2023
b00a413
Revert normalized property
harkal Dec 1, 2023
37ed3bf
Normalize based on instructions not cfg outputs
harkal Dec 1, 2023
f596312
Added some TODOS
harkal Dec 1, 2023
febd073
add some comments
charles-cooper Dec 1, 2023
1b75ce0
add some comments, minor nits
charles-cooper Dec 1, 2023
8aa5b4f
comments
charles-cooper Dec 1, 2023
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
28 changes: 28 additions & 0 deletions tests/compiler/venom/test_duplicate_operands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from vyper.compiler.settings import OptimizationLevel
from vyper.venom import generate_assembly_experimental
from vyper.venom.basicblock import IRLiteral
from vyper.venom.function import IRFunction


def test_duplicate_operands():
"""
Test the duplicate operands code generation.
The venom code:

%1 = 10
%2 = add %1, %1
%3 = mul %1, %2
stop

Should compile to: [PUSH1, 10, DUP1, DUP1, DUP1, ADD, MUL, STOP]
"""
ctx = IRFunction()

op = ctx.append_instruction("store", [IRLiteral(10)])
sum = ctx.append_instruction("add", [op, op])
ctx.append_instruction("mul", [sum, op])
ctx.append_instruction("stop", [], False)

asm = generate_assembly_experimental(ctx, OptimizationLevel.CODESIZE)

assert asm == ["PUSH1", 10, "DUP1", "DUP1", "DUP1", "ADD", "MUL", "STOP", "REVERT"]
96 changes: 96 additions & 0 deletions tests/compiler/venom/test_multi_entry_block.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
from vyper.venom.analysis import calculate_cfg
from vyper.venom.basicblock import IRLiteral
from vyper.venom.function import IRBasicBlock, IRFunction, IRLabel
from vyper.venom.passes.normalization import NormalizationPass


def test_multi_entry_block_1():
ctx = IRFunction()

finish_label = IRLabel("finish")
target_label = IRLabel("target")
block_1_label = IRLabel("block_1", ctx)

op = ctx.append_instruction("store", [IRLiteral(10)])
acc = ctx.append_instruction("add", [op, op])
ctx.append_instruction("jnz", [acc, finish_label, block_1_label], False)

block_1 = IRBasicBlock(block_1_label, ctx)
ctx.append_basic_block(block_1)
acc = ctx.append_instruction("add", [acc, op])
op = ctx.append_instruction("store", [IRLiteral(10)])
ctx.append_instruction("mstore", [acc, op], False)
ctx.append_instruction("jnz", [acc, finish_label, target_label], False)

target_bb = IRBasicBlock(target_label, ctx)
ctx.append_basic_block(target_bb)
ctx.append_instruction("mul", [acc, acc])
ctx.append_instruction("jmp", [finish_label], False)

finish_bb = IRBasicBlock(finish_label, ctx)
ctx.append_basic_block(finish_bb)
ctx.append_instruction("stop", [], False)

calculate_cfg(ctx)
assert not ctx.normalized, "CFG should not be normalized"

NormalizationPass.run_pass(ctx)

assert ctx.normalized, "CFG should be normalized"

finish_bb = ctx.get_basic_block(finish_label.value)
cfg_in = list(finish_bb.cfg_in.keys())
assert cfg_in[0].label.value == "target", "Should contain target"
assert cfg_in[1].label.value == "finish_split_global", "Should contain finish_split_global"
assert cfg_in[2].label.value == "finish_split_block_1", "Should contain finish_split_block_1"


# more complicated one
def test_multi_entry_block_2():
ctx = IRFunction()

finish_label = IRLabel("finish")
target_label = IRLabel("target")
block_1_label = IRLabel("block_1", ctx)
block_2_label = IRLabel("block_2", ctx)

op = ctx.append_instruction("store", [IRLiteral(10)])
acc = ctx.append_instruction("add", [op, op])
ctx.append_instruction("jnz", [acc, finish_label, block_1_label], False)

block_1 = IRBasicBlock(block_1_label, ctx)
ctx.append_basic_block(block_1)
acc = ctx.append_instruction("add", [acc, op])
op = ctx.append_instruction("store", [IRLiteral(10)])
ctx.append_instruction("mstore", [acc, op], False)
ctx.append_instruction("jnz", [acc, target_label, finish_label], False)

block_2 = IRBasicBlock(block_2_label, ctx)
ctx.append_basic_block(block_2)
acc = ctx.append_instruction("add", [acc, op])
op = ctx.append_instruction("store", [IRLiteral(10)])
ctx.append_instruction("mstore", [acc, op], False)
# switch the order of the labels, for fun
ctx.append_instruction("jnz", [acc, finish_label, target_label], False)

target_bb = IRBasicBlock(target_label, ctx)
ctx.append_basic_block(target_bb)
ctx.append_instruction("mul", [acc, acc])
ctx.append_instruction("jmp", [finish_label], False)

finish_bb = IRBasicBlock(finish_label, ctx)
ctx.append_basic_block(finish_bb)
ctx.append_instruction("stop", [], False)

calculate_cfg(ctx)
assert not ctx.normalized, "CFG should not be normalized"

NormalizationPass.run_pass(ctx)

assert ctx.normalized, "CFG should be normalized"

finish_bb = ctx.get_basic_block(finish_label.value)
cfg_in = list(finish_bb.cfg_in.keys())
assert cfg_in[0].label.value == "target", "Should contain target"
assert cfg_in[1].label.value == "finish_split_global", "Should contain finish_split_global"
assert cfg_in[2].label.value == "finish_split_block_1", "Should contain finish_split_block_1"
5 changes: 5 additions & 0 deletions tests/compiler/venom/test_stack_at_external_return.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def test_stack_at_external_return():
"""
TODO: USE BOA DO GENERATE THIS TEST
"""
pass
8 changes: 8 additions & 0 deletions vyper/cli/vyper_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ def _parse_args(argv):
"-p", help="Set the root path for contract imports", default=".", dest="root_folder"
)
parser.add_argument("-o", help="Set the output path", dest="output_path")
parser.add_argument(
"--experimental-codegen",
help="The compiler use the new IR codegen. This is an experimental feature.",
action="store_true",
)

args = parser.parse_args(argv)

Expand Down Expand Up @@ -188,6 +193,7 @@ def _parse_args(argv):
settings,
args.storage_layout,
args.no_bytecode_metadata,
args.experimental_codegen,
)

if args.output_path:
Expand Down Expand Up @@ -225,6 +231,7 @@ def compile_files(
settings: Optional[Settings] = None,
storage_layout_paths: list[str] = None,
no_bytecode_metadata: bool = False,
experimental_codegen: bool = False,
) -> dict:
root_path = Path(root_folder).resolve()
if not root_path.exists():
Expand Down Expand Up @@ -275,6 +282,7 @@ def compile_files(
storage_layout_override=storage_layout_override,
show_gas_estimates=show_gas_estimates,
no_bytecode_metadata=no_bytecode_metadata,
experimental_codegen=experimental_codegen,
)

ret[file_path] = output
Expand Down
4 changes: 4 additions & 0 deletions vyper/codegen/function_definitions/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,9 @@ def generate_ir_for_function(
# (note: internal functions do not need to adjust gas estimate since
mem_expansion_cost = calc_mem_gas(func_t._ir_info.frame_info.mem_used) # type: ignore
ret.common_ir.add_gas_estimate += mem_expansion_cost # type: ignore
ret.common_ir.passthrough_metadata["func_t"] = func_t # type: ignore
ret.common_ir.passthrough_metadata["frame_info"] = frame_info # type: ignore
else:
ret.func_ir.passthrough_metadata["frame_info"] = frame_info # type: ignore

return ret
4 changes: 3 additions & 1 deletion vyper/codegen/function_definitions/internal_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,6 @@ def generate_ir_for_internal_function(
["seq"] + nonreentrant_post + [["exit_to", "return_pc"]],
]

return IRnode.from_list(["seq", body, cleanup_routine])
ir_node = IRnode.from_list(["seq", body, cleanup_routine])
ir_node.passthrough_metadata["func_t"] = func_t
return ir_node
16 changes: 16 additions & 0 deletions vyper/codegen/ir_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ class IRnode:
valency: int
args: List["IRnode"]
value: Union[str, int]
is_self_call: bool
passthrough_metadata: dict[str, Any]
func_ir: Any
common_ir: Any

def __init__(
self,
Expand All @@ -184,6 +188,8 @@ def __init__(
mutable: bool = True,
add_gas_estimate: int = 0,
encoding: Encoding = Encoding.VYPER,
is_self_call: bool = False,
passthrough_metadata: dict[str, Any] = None,
):
if args is None:
args = []
Expand All @@ -201,6 +207,10 @@ def __init__(
self.add_gas_estimate = add_gas_estimate
self.encoding = encoding
self.as_hex = AS_HEX_DEFAULT
self.is_self_call = is_self_call
self.passthrough_metadata = passthrough_metadata or {}
self.func_ir = None
self.common_ir = None

assert self.value is not None, "None is not allowed as IRnode value"

Expand Down Expand Up @@ -585,6 +595,8 @@ def from_list(
error_msg: Optional[str] = None,
mutable: bool = True,
add_gas_estimate: int = 0,
is_self_call: bool = False,
passthrough_metadata: dict[str, Any] = None,
encoding: Encoding = Encoding.VYPER,
) -> "IRnode":
if isinstance(typ, str):
Expand Down Expand Up @@ -617,6 +629,8 @@ def from_list(
source_pos=source_pos,
encoding=encoding,
error_msg=error_msg,
is_self_call=is_self_call,
passthrough_metadata=passthrough_metadata,
)
else:
return cls(
Expand All @@ -630,4 +644,6 @@ def from_list(
add_gas_estimate=add_gas_estimate,
encoding=encoding,
error_msg=error_msg,
is_self_call=is_self_call,
passthrough_metadata=passthrough_metadata,
)
4 changes: 3 additions & 1 deletion vyper/codegen/return_.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ def finalize(fill_return_buffer):
cleanup_loops = "cleanup_repeat" if context.forvars else "seq"
# NOTE: because stack analysis is incomplete, cleanup_repeat must
# come after fill_return_buffer otherwise the stack will break
return IRnode.from_list(["seq", fill_return_buffer, cleanup_loops, jump_to_exit])
jump_to_exit_ir = IRnode.from_list(jump_to_exit)
jump_to_exit_ir.passthrough_metadata["func_t"] = func_t
return IRnode.from_list(["seq", fill_return_buffer, cleanup_loops, jump_to_exit_ir])

if context.return_type is None:
if context.is_internal:
Expand Down
2 changes: 2 additions & 0 deletions vyper/codegen/self_call.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,6 @@ def ir_for_self_call(stmt_expr, context):
add_gas_estimate=func_t._ir_info.gas_estimate,
)
o.is_self_call = True
o.passthrough_metadata["func_t"] = func_t
o.passthrough_metadata["args_ir"] = args_ir
return o
2 changes: 2 additions & 0 deletions vyper/compiler/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def compile_code(
no_bytecode_metadata: bool = False,
show_gas_estimates: bool = False,
exc_handler: Optional[Callable] = None,
experimental_codegen: bool = False,
) -> dict:
"""
Generate consumable compiler output(s) from a single contract source code.
Expand Down Expand Up @@ -104,6 +105,7 @@ def compile_code(
storage_layout_override,
show_gas_estimates,
no_bytecode_metadata,
experimental_codegen,
)

ret = {}
Expand Down
28 changes: 24 additions & 4 deletions vyper/compiler/phases.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from vyper.semantics import set_data_positions, validate_semantics
from vyper.semantics.types.function import ContractFunctionT
from vyper.typing import StorageLayout
from vyper.venom import generate_assembly_experimental, generate_ir

DEFAULT_CONTRACT_NAME = PurePath("VyperContract.vy")

Expand Down Expand Up @@ -60,6 +61,7 @@ def __init__(
storage_layout: StorageLayout = None,
show_gas_estimates: bool = False,
no_bytecode_metadata: bool = False,
experimental_codegen: bool = False,
) -> None:
"""
Initialization method.
Expand All @@ -78,14 +80,18 @@ def __init__(
Show gas estimates for abi and ir output modes
no_bytecode_metadata: bool, optional
Do not add metadata to bytecode. Defaults to False
experimental_codegen: bool, optional
Use experimental codegen. Defaults to False
"""
# to force experimental codegen, uncomment:
# experimental_codegen = True
self.contract_path = contract_path
self.source_code = source_code
self.source_id = source_id
self.storage_layout_override = storage_layout
self.show_gas_estimates = show_gas_estimates
self.no_bytecode_metadata = no_bytecode_metadata

self.experimental_codegen = experimental_codegen
self.settings = settings or Settings()
self.input_bundle = input_bundle or FilesystemInputBundle([Path(".")])

Expand Down Expand Up @@ -160,7 +166,11 @@ def global_ctx(self) -> GlobalContext:
@cached_property
def _ir_output(self):
# fetch both deployment and runtime IR
return generate_ir_nodes(self.global_ctx, self.settings.optimize)
nodes = generate_ir_nodes(self.global_ctx, self.settings.optimize)
if self.experimental_codegen:
return [generate_ir(nodes[0]), generate_ir(nodes[1])]
else:
return nodes

@property
def ir_nodes(self) -> IRnode:
Expand All @@ -183,11 +193,21 @@ def function_signatures(self) -> dict[str, ContractFunctionT]:

@cached_property
def assembly(self) -> list:
return generate_assembly(self.ir_nodes, self.settings.optimize)
if self.experimental_codegen:
return generate_assembly_experimental(
self.ir_nodes, self.settings.optimize # type: ignore
)
else:
return generate_assembly(self.ir_nodes, self.settings.optimize)

@cached_property
def assembly_runtime(self) -> list:
return generate_assembly(self.ir_runtime, self.settings.optimize)
if self.experimental_codegen:
return generate_assembly_experimental(
self.ir_runtime, self.settings.optimize # type: ignore
)
else:
return generate_assembly(self.ir_runtime, self.settings.optimize)

@cached_property
def bytecode(self) -> bytes:
Expand Down
Loading
Loading