Skip to content

Commit

Permalink
Opbinaryop and other minor optimizations (#157)
Browse files Browse the repository at this point in the history
* OpBinaryOp for performance

* Cleanup

* Remove ip limit check in every iteration of the loop.

* Micro optimizations on frequent ops

* Micro optimizations

* Patches

* Removed redundant binaryop operators from compiler

* Merged OpReturn and OpReturnValue

* Cleanup
  • Loading branch information
geseq authored and d5 committed Mar 22, 2019
1 parent 7095b56 commit 09f3d52
Show file tree
Hide file tree
Showing 10 changed files with 367 additions and 574 deletions.
18 changes: 9 additions & 9 deletions compiler/bytecode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,25 +102,25 @@ func TestBytecode(t *testing.T) {
compiler.MakeInstruction(compiler.OpSetLocal, 0),
compiler.MakeInstruction(compiler.OpGetGlobal, 0),
compiler.MakeInstruction(compiler.OpGetFree, 0),
compiler.MakeInstruction(compiler.OpAdd),
compiler.MakeInstruction(compiler.OpBinaryOp, 11),
compiler.MakeInstruction(compiler.OpGetFree, 1),
compiler.MakeInstruction(compiler.OpAdd),
compiler.MakeInstruction(compiler.OpBinaryOp, 11),
compiler.MakeInstruction(compiler.OpGetLocal, 0),
compiler.MakeInstruction(compiler.OpAdd),
compiler.MakeInstruction(compiler.OpReturnValue)),
compiler.MakeInstruction(compiler.OpBinaryOp, 11),
compiler.MakeInstruction(compiler.OpReturn, 1)),
compiledFunction(1, 0,
compiler.MakeInstruction(compiler.OpConstant, 2),
compiler.MakeInstruction(compiler.OpSetLocal, 0),
compiler.MakeInstruction(compiler.OpGetFree, 0),
compiler.MakeInstruction(compiler.OpGetLocal, 0),
compiler.MakeInstruction(compiler.OpClosure, 4, 2),
compiler.MakeInstruction(compiler.OpReturnValue)),
compiler.MakeInstruction(compiler.OpReturn, 1)),
compiledFunction(1, 0,
compiler.MakeInstruction(compiler.OpConstant, 1),
compiler.MakeInstruction(compiler.OpSetLocal, 0),
compiler.MakeInstruction(compiler.OpGetLocal, 0),
compiler.MakeInstruction(compiler.OpClosure, 5, 1),
compiler.MakeInstruction(compiler.OpReturnValue))),
compiler.MakeInstruction(compiler.OpReturn, 1))),
fileSet(srcfile{name: "file1", size: 100}, srcfile{name: "file2", size: 200})))
}

Expand Down Expand Up @@ -240,13 +240,13 @@ func TestBytecode_CountObjects(t *testing.T) {
&objects.Int{Value: 88},
compiledFunction(1, 0,
compiler.MakeInstruction(compiler.OpConstant, 3),
compiler.MakeInstruction(compiler.OpReturnValue)),
compiler.MakeInstruction(compiler.OpReturn, 1)),
compiledFunction(1, 0,
compiler.MakeInstruction(compiler.OpConstant, 2),
compiler.MakeInstruction(compiler.OpReturnValue)),
compiler.MakeInstruction(compiler.OpReturn, 1)),
compiledFunction(1, 0,
compiler.MakeInstruction(compiler.OpConstant, 1),
compiler.MakeInstruction(compiler.OpReturnValue))))
compiler.MakeInstruction(compiler.OpReturn, 1))))
assert.Equal(t, 7, b.CountObjects())
}

Expand Down
40 changes: 20 additions & 20 deletions compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (c *Compiler) Compile(node ast.Node) error {
return err
}

c.emit(node, OpGreaterThan)
c.emit(node, OpBinaryOp, int(token.Greater))

return nil
} else if node.Token == token.LessEq {
Expand All @@ -130,7 +130,7 @@ func (c *Compiler) Compile(node ast.Node) error {
return err
}

c.emit(node, OpGreaterThanEqual)
c.emit(node, OpBinaryOp, int(token.GreaterEq))

return nil
}
Expand All @@ -144,35 +144,35 @@ func (c *Compiler) Compile(node ast.Node) error {

switch node.Token {
case token.Add:
c.emit(node, OpAdd)
c.emit(node, OpBinaryOp, int(token.Add))
case token.Sub:
c.emit(node, OpSub)
c.emit(node, OpBinaryOp, int(token.Sub))
case token.Mul:
c.emit(node, OpMul)
c.emit(node, OpBinaryOp, int(token.Mul))
case token.Quo:
c.emit(node, OpDiv)
c.emit(node, OpBinaryOp, int(token.Quo))
case token.Rem:
c.emit(node, OpRem)
c.emit(node, OpBinaryOp, int(token.Rem))
case token.Greater:
c.emit(node, OpGreaterThan)
c.emit(node, OpBinaryOp, int(token.Greater))
case token.GreaterEq:
c.emit(node, OpGreaterThanEqual)
c.emit(node, OpBinaryOp, int(token.GreaterEq))
case token.Equal:
c.emit(node, OpEqual)
case token.NotEqual:
c.emit(node, OpNotEqual)
case token.And:
c.emit(node, OpBAnd)
c.emit(node, OpBinaryOp, int(token.And))
case token.Or:
c.emit(node, OpBOr)
c.emit(node, OpBinaryOp, int(token.Or))
case token.Xor:
c.emit(node, OpBXor)
c.emit(node, OpBinaryOp, int(token.Xor))
case token.AndNot:
c.emit(node, OpBAndNot)
c.emit(node, OpBinaryOp, int(token.AndNot))
case token.Shl:
c.emit(node, OpBShiftLeft)
c.emit(node, OpBinaryOp, int(token.Shl))
case token.Shr:
c.emit(node, OpBShiftRight)
c.emit(node, OpBinaryOp, int(token.Shr))
default:
return c.errorf(node, "invalid binary operator: %s", node.Token.String())
}
Expand Down Expand Up @@ -405,8 +405,8 @@ func (c *Compiler) Compile(node ast.Node) error {
}

// add OpReturn if function returns nothing
if !c.lastInstructionIs(OpReturnValue) && !c.lastInstructionIs(OpReturn) {
c.emit(node, OpReturn)
if !c.lastInstructionIs(OpReturn) {
c.emit(node, OpReturn, 0)
}

freeSymbols := c.symbolTable.FreeSymbols()
Expand Down Expand Up @@ -486,13 +486,13 @@ func (c *Compiler) Compile(node ast.Node) error {
}

if node.Result == nil {
c.emit(node, OpReturn)
c.emit(node, OpReturn, 0)
} else {
if err := c.Compile(node.Result); err != nil {
return err
}

c.emit(node, OpReturnValue)
c.emit(node, OpReturn, 1)
}

case *ast.CallExpr:
Expand Down Expand Up @@ -578,7 +578,7 @@ func (c *Compiler) Compile(node ast.Node) error {
}

c.emit(node, OpImmutable)
c.emit(node, OpReturnValue)
c.emit(node, OpReturn, 1)

case *ast.ErrorExpr:
if err := c.Compile(node.Expr); err != nil {
Expand Down
22 changes: 11 additions & 11 deletions compiler/compiler_assign.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,27 +51,27 @@ func (c *Compiler) compileAssign(node ast.Node, lhs, rhs []ast.Expr, op token.To

switch op {
case token.AddAssign:
c.emit(node, OpAdd)
c.emit(node, OpBinaryOp, int(token.Add))
case token.SubAssign:
c.emit(node, OpSub)
c.emit(node, OpBinaryOp, int(token.Sub))
case token.MulAssign:
c.emit(node, OpMul)
c.emit(node, OpBinaryOp, int(token.Mul))
case token.QuoAssign:
c.emit(node, OpDiv)
c.emit(node, OpBinaryOp, int(token.Quo))
case token.RemAssign:
c.emit(node, OpRem)
c.emit(node, OpBinaryOp, int(token.Rem))
case token.AndAssign:
c.emit(node, OpBAnd)
c.emit(node, OpBinaryOp, int(token.And))
case token.OrAssign:
c.emit(node, OpBOr)
c.emit(node, OpBinaryOp, int(token.Or))
case token.AndNotAssign:
c.emit(node, OpBAndNot)
c.emit(node, OpBinaryOp, int(token.AndNot))
case token.XorAssign:
c.emit(node, OpBXor)
c.emit(node, OpBinaryOp, int(token.Xor))
case token.ShlAssign:
c.emit(node, OpBShiftLeft)
c.emit(node, OpBinaryOp, int(token.Shl))
case token.ShrAssign:
c.emit(node, OpBShiftRight)
c.emit(node, OpBinaryOp, int(token.Shr))
}

// compile selector expressions (right to left)
Expand Down
2 changes: 1 addition & 1 deletion compiler/compiler_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (c *Compiler) compileModule(node ast.Node, moduleName, modulePath string, s
}

// add OpReturn (== export undefined) if export is missing
if !moduleCompiler.lastInstructionIs(OpReturnValue) {
if !moduleCompiler.lastInstructionIs(OpReturn) {
moduleCompiler.emit(nil, OpReturn)
}

Expand Down
Loading

0 comments on commit 09f3d52

Please sign in to comment.