Address Optimization

For some architectures, referencing a global variable by constant address requires two instructions, while referencing the same variable through a pointer requires only one. Even on architectures with full-address-precision addressing modes, it may be faster to use a pointer and offset.

The number of global scalar variables in many programs is relatively small, and often can fit in a global variable pool. For such programs, all of the global scalar variables (and small global arrays) can be accessed via one pointer and an offset, thus avoiding more expensive load and store sequences and reducing code size.

Example:

In the code fragment below, the three global variables can be placed together in one contiguous memory region (global variable pool) and referenced via one pointer and an offset.

Before:

int a;
int b;
int c;

void f (void)
{
  a = 3;
  b = 5;
  c = 7;
  return;
}

Below is the code fragment after the global variables have been mapped into a global memory pool.

After:

int __t1[3];               /* global pool for a, b, c */
int *__t2 = &__t1[0];      /* pointer to global pool */

void f (void)
{
  *__t2 = 3;               /* a = 3; */
  *(__t2 + 1) = 5;         /* b = 5; */
  *(__t2 + 2) = 7;         /* c = 7; */
  return;
}

Notes:

This optimization generally requires cooperation between the compiler and the linker to be most effective. In particular, the number of global variables and offsets are not know during compilation.

Some compilers support a command-line option to control the number of global variables and the maximum size of global variables that are allocated to the global variable pool.

Some ABI's define a specific register as a pointer to the global variable pool.

If the ABI does not define a register for the global variable pool, then loading the pointer may be more expensive than addressing the global directly, and the optimization should be controlled by a heuristic, such as number of globals accessed in a function.