Constant to Array Reallocation

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.

Note: This optimization creates extra data for its own use in the .data section. If the .data section load address is different from the .data section run address (e.g., because of an AT linker command file directive) avoid using the constant to array optimization in any functions executing before the run address. Use #pragma constarray off to ensure proper function execution.