13.3 Static Superinstructions

Static superinstructions combine a sequence of primitives and are added to the gforth-fast engines at Gforth build time. They are used even if dynamic native-code generation is disabled with --no-dynamic.

As an example, Gforth has a static superinstruction for the sequence < ?branch that occurs in mymin. Enabling static superinstructions by leaving away the --ss-number=0 from the command line above results in the right column below:

    gforth-fast --ss-states=1 --opt-ip-updates=0
with --ss-number=0              without --ss-number=0
<mymin+$8>    <    1->1         <mymin+$8>    < ?branch     1->1 
 add    $0x8,%rbx               <mymin+$10>   ?branch    1->1    
 add    $0x8,%r10               <mymin+$18>   <mymin+$38>        
 cmp    %r13,(%r10)              add    $0x18,%rbx               
 setl   %r13b                    mov    0x8(%r10),%rax           
 movzbl %r13b,%r13d              add    $0x10,%r10               
 neg    %r13                     mov    -0x8(%rbx),%rsi          
<mymin+$10>   ?branch    1->1    cmp    %r13,%rax                
<mymin+$18>   <mymin+$38>        mov    (%r10),%r13              
 add    $0x10,%rbx               jl     0x7f51790998b4           
 add    $0x8,%r10                mov    (%rsi),%rax              
 test   %r13,%r13                mov    %rsi,%rbx                
 mov    -0x8(%rbx),%rsi          jmp    *%rax                    
 mov    (%r10),%r13
 jne    0x7f8c2a49d396
 mov    (%rsi),%rax
 mov    %rsi,%rbx
 jmp    *%rax

The benefit of the static superinstruction is that the comparison result does not need to be converted into a cell and that cell then checked the make the branch decision.

The threaded-code slot for < contains the address of the static superinstruction, the code slot for the ?branch still exists, but is not used.

There are only 63 (at the time of this writing) static superinstructions in gforth-fast, because the combination of stack caching and the IP update optimization provides the same benefits in many cases. Moreover, currently static superinstructions can only start and end in the canonical stack state, eliminating some potentially beneficial uses.

You can determine how many of the static superinstructions you want to use with --ss-number=n. The first n superinstructions will then be used, no finer-granularity control is provided. Static superinstructions will only be used if they result in code that is at least as short as can be achieved with the other optimizations. You can see the static superinstructions in gforth-fast with (on Unix):

gforth-fast --print-prims -e bye |& cut -b -18|awk 'NF>1'

You can read a little more about static superinstructions in M. Anton Ertl, David Gregg, Andreas Krall, and Bernd Paysan, vmgen — A Generator of Efficient Virtual Machine Interpreters, Software: Practice and Experience 32(3), p. 265–294, 2002.