def generate_ir_nodes( global_ctx: GlobalContext, no_optimize: bool) -> Tuple[IRnode, IRnode, FunctionSignatures]: """ Generate the intermediate representation (IR) from the contextualized AST. This phase also includes IR-level optimizations. This function returns three values: deployment bytecode, runtime bytecode and the function signatures of the contract Arguments --------- global_ctx : GlobalContext Contextualized Vyper AST Returns ------- (IRnode, IRnode) IR to generate deployment bytecode IR to generate runtime bytecode """ ir_nodes, ir_runtime, function_sigs = module.generate_ir_for_module( global_ctx) if not no_optimize: ir_nodes = optimizer.optimize(ir_nodes) ir_runtime = optimizer.optimize(ir_runtime) return ir_nodes, ir_runtime, function_sigs
def cache_when_complex(self, name): from vyper.ir.optimizer import optimize # for caching purposes, see if the ir_node will be optimized # because a non-literal expr could turn into a literal, # (e.g. `(add 1 2)`) # TODO this could really be moved into optimizer.py should_inline = not optimize(self).is_complex_ir return _WithBuilder(self, name, should_inline)
def test_ir_optimizer(ir): optimized = optimizer.optimize(IRnode.from_list(ir[0])) optimized.repr_show_gas = True if ir[1] is None: # no-op, assert optimizer does nothing expected = IRnode.from_list(ir[0]) else: expected = IRnode.from_list(ir[1]) expected.repr_show_gas = True optimized.annotation = None assert optimized == expected
def ir_compiler(ir, *args, **kwargs): ir = IRnode.from_list(ir) if not no_optimize: ir = optimizer.optimize(ir) bytecode, _ = compile_ir.assembly_to_evm( compile_ir.compile_to_assembly(ir, no_optimize=no_optimize)) abi = kwargs.get("abi") or [] c = w3.eth.contract(abi=abi, bytecode=bytecode) deploy_transaction = c.constructor() tx_hash = deploy_transaction.transact() address = w3.eth.get_transaction_receipt(tx_hash)["contractAddress"] contract = w3.eth.contract(address, abi=abi, bytecode=bytecode, ContractFactoryClass=VyperContract) return contract
def __init__(self, ir_node, name): # TODO figure out how to fix this circular import from vyper.ir.optimizer import optimize self.ir_node = ir_node # for caching purposes, see if the ir_node will be optimized # because a non-literal expr could turn into a literal, # (e.g. `(add 1 2)`) # TODO this could really be moved into optimizer.py self.should_cache = optimize(ir_node).is_complex_ir # a named IR variable which represents the # output of `ir_node` self.ir_var = IRnode.from_list(name, typ=ir_node.typ, location=ir_node.location, encoding=ir_node.encoding)
def __init__(self, ir_node, name, should_inline=False): # TODO figure out how to fix this circular import from vyper.ir.optimizer import optimize if should_inline and optimize(ir_node).is_complex_ir: # this can only mean trouble raise CompilerPanic("trying to inline a complex IR node") self.ir_node = ir_node # whether or not to inline the ir_node self.should_inline = should_inline # a named IR variable which represents the # output of `ir_node` self.ir_var = IRnode.from_list(name, typ=ir_node.typ, location=ir_node.location, encoding=ir_node.encoding)
def compile_to_ir(input_file, output_formats, show_gas_estimates=False): with open(input_file) as fh: s_expressions = parse_s_exp(fh.read()) if show_gas_estimates: IRnode.repr_show_gas = True compiler_data = {} ir = IRnode.from_list(s_expressions[0]) ir = optimizer.optimize(ir) if "ir" in output_formats: compiler_data["ir"] = ir asm = compile_ir.compile_to_assembly(ir) if "asm" in output_formats: compiler_data["asm"] = asm if "bytecode" in output_formats: (bytecode, _srcmap) = compile_ir.assembly_to_evm(asm) compiler_data["bytecode"] = "0x" + bytecode.hex() return compiler_data
def test_ir_compile_fail(ir): optimized = optimizer.optimize(IRnode.from_list(ir[0])) optimized.repr_show_gas = True hand_optimized = IRnode.from_list(ir[1]) hand_optimized.repr_show_gas = True assert optimized == hand_optimized
def test_sha3_32(): ir = ["sha3_32", 0] evm = ["PUSH1", 0, "PUSH1", 0, "MSTORE", "PUSH1", 32, "PUSH1", 0, "SHA3"] assert compile_ir.compile_to_assembly(IRnode.from_list(ir)) == evm assert compile_ir.compile_to_assembly( optimizer.optimize(IRnode.from_list(ir))) == evm
def test_static_assertions(ir, assert_compile_failed): ir = IRnode.from_list(ir) assert_compile_failed(lambda: optimizer.optimize(ir), StaticAssertionException)