From db99368e96e5839e53369ee75e8693ebd73047a6 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 12 Nov 2021 19:58:21 +0300 Subject: [PATCH] compiler: optimize GAS cost of type conversion CONVERT call base price is 8192. DUP, ISTYPE and JMPIF all cost 2. So we add 0.07% overhead in the worst case and save 99.93% otherwise. At the same time, old code was just two bytes and new one is seven, but I think it's tolerable considering how much GAS it can potentially save. Fix #2250. --- pkg/compiler/codegen.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 7a5922856..2c292e5f5 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -1272,7 +1272,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { goTyp := c.typeOf(n.Type) if canConvert(goTyp.String()) { typ := toNeoType(goTyp) - emit.Instruction(c.prog.BinWriter, opcode.CONVERT, []byte{byte(typ)}) + c.emitConvert(typ) } return nil } @@ -1763,6 +1763,9 @@ func transformArgs(fs *funcScope, fun ast.Expr, args []ast.Expr) []ast.Expr { // emitConvert converts top stack item to the specified type. func (c *codegen) emitConvert(typ stackitem.Type) { + emit.Opcodes(c.prog.BinWriter, opcode.DUP) + emit.Instruction(c.prog.BinWriter, opcode.ISTYPE, []byte{byte(typ)}) + emit.Instruction(c.prog.BinWriter, opcode.JMPIF, []byte{2 + 2}) // After CONVERT. emit.Instruction(c.prog.BinWriter, opcode.CONVERT, []byte{byte(typ)}) }