Skip to content

Latest commit

 

History

History
113 lines (91 loc) · 3 KB

optimizer.md

File metadata and controls

113 lines (91 loc) · 3 KB

Optimizer

uGO has a builtin simple optimizer to improve bytecode execution performance. Optimizer is loosely coupled in compiler which enables to disable optimizer before compilation. If your script has many constants and arithmetic operations, optimizer may save some cpu cycles.

As of now optimizer works on Abstract Syntax Tree (AST) like compiler but it replaces expressions, if applicable, with constant literals. Optimizer uses two techniques to modify AST, constant folding and dynamically evaluating expressions, which has no side effect. Optimizer greedily tries to modify AST until the given limit is reached. Constant propagation will be implemented in the future which may improve execution performance more than current implementation.

Following example shows how the optimizer works:

If optimizer is not enabled, for a basic binary operation, at least 3 instructions, 2 constants are emitted by compiler in bytecode as can be seen in the comments (ignore SETLOCAL and RETURN opcodes for the example).

a := 1 << 4
Bytecode
Modules:0
Constants:
   0: 1|int
   1: 4|int
Params:1 Variadic:false Locals:1
Instructions:
0000 CONSTANT        0
0003 CONSTANT        1
0006 BINARYOP        20
0008 SETLOCAL        0
0010 RETURN          0
SourceMap:map[0:6 3:11 6:6 8:1 10:0]

If optimizer is enabled, 1 instruction is emitted by the compiler as below. We saved 2 instructions, 1 constant and a few source map entries.

a := 1 << 4
Bytecode
Modules:0
Constants:
   0: 16|int
Params:1 Variadic:false Locals:1
Instructions:
0000 CONSTANT        0
0003 SETLOCAL        0
0005 RETURN          0
SourceMap:map[0:6 3:1 5:0]

Of course user can directly write constant value instead of writing 1 << 4 but for readibility purposes and cases where verbosity matters, it may be useful.

Another advantage of using optimizer is to get some builtin function results at compile time.

a := uint("0b0101")   // a == 5

As be seen in generated bytecode below, builtin function is not called.

Bytecode
Modules:0
Constants:
   0: 0x5|uint
Params:1 Variadic:false Locals:1
Instructions:
0000 CONSTANT        0
0003 SETLOCAL        0
0005 RETURN          0
SourceMap:map[0:6 3:1 5:0]

uGO's terminal application enables you to see the generated bytecode for the last executed code. To see the bytecode, type .bytecode command in terminal.

To see unoptimized bytecode start application like this

./ugo -no-optimizer

uGO's terminal application provides trace output for parser, optimizer and compiler that can help you to learn, test or debug. To enable traces see usage of the application like below.

./ugo -h

Usage of ugo:
  -no-optimizer
        disable optimization
  -trace string
        comma separated units: -trace parser,optimizer,compiler

The options to configure the optimizer are passed by compiler options. Optimizer is enabled by default in default compiler options.

Please don't expect much from the optimizer, but it is going to be smarter!