Constants/large constants encoded in instructions are stored into an array in data memory and immediate operands are changed into data memory access using register-indirect, post-increment operands.
The main target of this optimization is speed, but occasionally size improvements can also be obtained.
Each transformed instruction reduces the execution time of an instruction by 1-2 cycles and reduces program memory size by 1-2 words, but also causes an increase of data memory by 1-2 words, depending on the size of immediates.
Besides the operand mode transformation, grouping transformed instructions can further decrease total program memory size.
The following instructions take between 2-3 words of program memory and 2-3 cycles to execute:
MOVE.W#xxxx, HHHHH MOVE.L#xxxxxx, HHHHH
and they are transformed to:
MOVE.W(Rx)+, HHHHH MOVE.L(Rx)+, HHHHH
so that the resulting instruction will take 1word of program memory and 1 cycle to execute, but it will add an extra 1-2 words into data memory (the immediate values). It will also add an overhead of one instruction per sequence for computing the address of the first element.
If no instruction grouping happens with instructions transformed to post-increment indirect addressing, the total memory size used will slightly increase, due to the computation of stack offset for the first element in a sequence.
An example of how this optimization works on the following piece of low-level intermediate code:
.code
move.w X:(R3)+, X0
move.w #<number_1>, Y0
mac Y0, X0, A
move.w X:(R3)+, X0
move.w #<number_2>, Y0
mac Y0, X0, A
The code above can be optimized to:
.code
move.w #<array_starting_address>, R0
move.w X:(R3)+, X0
move.w X:(R0)+, Y0
mac Y0, X0, A
move.w X:(R3)+, X0
move.w X:(R0)+, Y0
mac Y0, X0, A
.data
array_starting_address:
<number_1>
<number_2>
This optimization is disabled for -Os and is automatically enabled on speed optimization level >= 2. Constant to array reallocation can be enabled/disabled at any optimization level using -[no]constarray options in the command line. At function level, you should use #pragma constarray on/off.