Sign in Join
FPDoc Onlineexperiment

Non processor specific

The following sections describe the general optimizations done by the compiler, they are not processor specific. Some of these require some compiler switch override while others are done automatically (those which require a switch will be noted as such).

Constant folding

In Free Pascal, if the operand(s) of an operator are constants, they will be evaluated at compile time.

Example

   x:=1+2+3+6+5;

will generate the same code as

   x:=17;

Furthermore, if an array index is a constant, the offset will be evaluated at compile time. This means that accessing MyData[5] is as efficient as accessing a normal variable.

Finally, calling Chr, Hi, Lo, Ord, Pred, or Succ functions (in general any mathematical function that is handled internally by the compiler) with constant parameters generates no run-time library calls, instead, the values are evaluated at compile time.

Constant merging

Using the same constant string, floating point value or constant set two or more times generates only one copy of that constant.

Short cut evaluation

Evaluation of boolean expression stops as soon as the result is known, which makes code execute faster then if all boolean operands were evaluated.

Constant set inlining

Using the in operator is always more efficient than using the equivalent <>, =, <=, >=, < and > operators. This is because range comparisons can be done more easily with the in operator than with normal comparison operators.

Small sets

Sets which contain less than 33 elements can be directly encoded using a 32-bit value, therefore no run-time library calls to evaluate operands on these sets are required; they are directly encoded by the code generator.

Range checking

Assignments of constants to variables are range checked at compile time, which removes the need of the generation of runtime range checking code.

And instead of modulo

When the second operand of a mod on an unsigned value is a constant power of 2, an and instruction is used instead of an integer division. This generates more efficient code.

Shifts instead of multiply or divide

When one of the operands in a multiplication is a power of two, they are encoded using arithmetic shift instructions, which generates more efficient code.

Similarly, if the divisor in a div operation is a power of two, it is encoded using arithmetic shift instructions.

The same is true when accessing array indexes which are powers of two, the address is calculated using arithmetic shifts instead of the multiply instruction.

Automatic alignment

By default all variables larger then a byte are guaranteed to be aligned at least on a word boundary.

Alignment on the stack and in the data section is processor dependent.

Smart linking

This feature removes all unreferenced code in the final executable file, making the executable file much smaller.

Smart linking is switched on with the -CX command line switch, or using the {$SMARTLINK ON} global directive.

Inline routines

The following runtime library routines are coded directly into the final executable: Lo, Hi, High, Sizeof, TypeOf, Length, Pred, Succ, Inc, Dec and Assigned.

Stack frame omission

Under specific conditions, the stack frame (entry and exit code for the routine, see section section Code issues) will be omitted, and the variable will directly be accessed via the stack pointer.

Conditions for omission of the stack frame:

  • The target CPU is x86 or ARM.

  • The -O2 or -OoSTACKFRAME command line switch must be specified.

  • No inline assembler is used.

  • No exceptions are used.

  • No routines are called with outgoing parameters on the stack.

  • The function has no parameters.

Register variables

When using the -Or switch, local variables or parameters which are used very often will be moved to registers for faster access.

An experiment, built from development snapshots. Not the official Free Pascal or Lazarus documentation.