Contents | < Browse | Browse >
16G. register allocation
------------------------
E v3 supports a register allocation, which is a technique to keep
variables in registers instead of on the stack. For normal code
that uses OS-routines you won't notice the difference very much,
but for tight computation-loops, this optimisation can make a big
difference. There are two ways to use register allocation:

- with the option REG.
  If you write for example EC REG=3 bla.e, (max=5, currently),
  EC will compute for each PROC the 3 most-used variables in
  registers. Register allocation is a technique that tries to be
  intelligent: it will compute for each var a weight, and will
  use heuristics to increase that weight, for example a var used
  in a FOR loop gets relatively a higher weight than one outside
  it, and one in an IF gets an even lower weight. These weights
  are combined, so a WHILE in a FOR gets quite a high weight.

- DIY: you can put the keyword REG in front of any type in a
  declaration, for example:

	DEF x:REG, s[4]:REG LIST

  you can do this if you don't trust the register-allocator,
  or if you want to fine-tune just one PROC. You can even use
  both together: if in a PROC you have one var with :REG,
  compiling with REG=5 will allow EC to pick the remaining 4
  by itself.

The default is REG=0, so EC works much like the older versions.

The variables that CAN be allocated are only local variables
that are not parameters. also, if you take the address of
a variable with {} it can't be put in a register either (guess
why...). registers can't be allocated in PROCs that have
an exception handler, for now.

There are a few things to note when using registers:
- this part of EC is currently (E v3.0a) was tested to
  be pretty reliable, but you still check that behaviour is
  the same as in non-allocated code.
- EC uses registers D7..D3 for variables, so if you use
  inline assembly, you need to check that PROCs that use
  register-allocation or :REG don't trash these (see  15E ).
  The code generated for a PROC automatically saves the
  registers it uses (callee save) to protect the code that
  called it.
- hint: compiling with REG=5 is not inherently fastest,
  since variable saving on function/library calls also
  incurs an overhead. REG=3 may be better for some
  cases. Also if _all_ code in question deals with
  library calls instead of pure computation, expect no
  gain from registers.

-> register allocation will easily make this program twice as fast

PROC main()
  DEF a,b=10,c=20,d
  FOR a:=1 TO 1000000 DO d:=b+c
ENDPROC

-> at most 5% faster when using register allocation

PROC main()
  DEF a,s[100]:STRING,t
  t:='putting "a" in a reg won''t give that much of a speedup, I think.'
  FOR a:=1 TO 100000 DO StrCopy(s,t)
ENDPROC