REGISTER statement

Purpose

To define Register variables, which are local to a Sub or Function.  The REGISTER statement provides an optimization hint to the compiler.

Syntax

REGISTER variable [AS type] [, variable [AS type]]

Remarks

The REGISTER statement is used to define certain local variables as Register variables - that is, variables which are stored directly in specific CPU registers, rather than in application memory.  Since data in a CPU register can be accessed much faster, and with less code, Register variables are valuable optimization tools.

Register variables are always local to the Sub or Function where they appear.  In the current version of PowerBASIC, there may be up to two integer-class variables (Word/Dword/Integer/Long) and up to four Extended-precision floats.  It is possible that future versions of the compiler will change these limits, so you may declare an unlimited number of them.  Any "extra" Register variables are automatically reclassified as locals during compilation.

The REGISTER statement allows you to choose which variables will be classified as Register variables.  If you do not make the choice in a particular Sub/Function, the compiler will attempt to choose for you.  By default, the compiler will always assign any integer-class local variables available.  Extended-precision float variables will be automatically assigned only in Functions that contain no external Function calls.

Integer class Register variables are most efficient for variables that are updated or used often, such as For/Next loop counter variables, and variables that are used repeatedly as array indexes.

Floating-point Register variables should generally be chosen with a bit more caution, since the compiler must generate code to save and restore them to conventional memory around each call to a Sub or Function.  In some rather rare cases, it is possible that floating-point Register variables could actually reduce execution speed.  However, they are extremely valuable with intensive floating-point calculations in Functions that have few references to other Subs and Functions.

Due to the design of FPUs (floating point units), and the instruction sets available, the first float register variable declared in your program has far more optimization possibilities than the others do.  Use care in choosing the variable which is used most within floating-point expressions (that is, on the right side of the '=' assignment operator), in order to gain the greatest advantage in execution speed.  Also, remember it is typically valuable to assign floating-point constants to Register variables when they are used in repetitive or intensive calculations.

You must use care with Inline Assembler floating-point opcodes in Functions that enable Register variables. Floating-point Register variables may occupy up to four of the FPU registers, so you must limit your use of the x87 registers to the remaining four. Further, floating-point Register variables may never be referenced by name from Inline Assembler code, as the compiler cannot always track the register locations with absolute certainty.

Restrictions

VARPTR cannot be used on a Register variable.

PowerBASIC transparently prevents the automatic register conversion of the variable used in the TO clause of the DIALOG SHOW MODAL and DIALOG SHOW MODELESS statements.  If the target variable is explicitly declared as a register variable, PowerBASIC raises a compile-time Error 491 ("Invalid register variable").  This is necessary as the result values stored in such variables may be assigned from the context of other Subs/Functions, and this may only occur with a memory variable.

See also

#REGISTER, Optimizing your code

Example

SUB ReindexDatabase() AS LONG

  #REGISTER NONE   ' I'll choose my own register vars.

  REGISTER i AS LONG

  REGISTER fVar AS EXT

  ...

END FUNCTION