xtensa: Improve constant synthesis for both integer and floating-point
authorTakayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
Fri, 10 Jun 2022 15:26:17 +0000 (00:26 +0900)
committerMax Filippov <jcmvbkbc@gmail.com>
Sat, 11 Jun 2022 21:39:10 +0000 (14:39 -0700)
commitcd02f15f1aecc45b2c2feae16840503549508619
tree1d24602e683cd4344f5927af29275f33fffaff1d
parentccd02e734e0f1742629403b46e5b1c650b00fd65
xtensa: Improve constant synthesis for both integer and floating-point

This patch revises the previous implementation of constant synthesis.

First, changed to use define_split machine description pattern and to run
after reload pass, in order not to interfere some optimizations such as
the loop invariant motion.

Second, not only integer but floating-point is subject to processing.

Third, several new synthesis patterns - when the constant cannot fit into
a "MOVI Ax, simm12" instruction, but:

I.   can be represented as a power of two minus one (eg. 32767, 65535 or
     0x7fffffffUL)
       => "MOVI(.N) Ax, -1" + "SRLI Ax, Ax, 1 ... 31" (or "EXTUI")
II.  is between -34816 and 34559
       => "MOVI(.N) Ax, -2048 ... 2047" + "ADDMI Ax, Ax, -32768 ... 32512"
III. (existing case) can fit into a signed 12-bit if the trailing zero bits
     are stripped
       => "MOVI(.N) Ax, -2048 ... 2047" + "SLLI Ax, Ax, 1 ... 31"

The above sequences consist of 5 or 6 bytes and have latency of 2 clock cycles,
in contrast with "L32R Ax, <litpool>" (3 bytes and one clock latency, but may
suffer additional one clock pipeline stall and implementation-specific
InstRAM/ROM access penalty) plus 4 bytes of constant value.

In addition, 3-instructions synthesis patterns (8 or 9 bytes, 3 clock latency)
are also provided when optimizing for speed and L32R instruction has
considerable access penalty:

IV.  2-instructions synthesis (any of I ... III) followed by
     "SLLI Ax, Ax, 1 ... 31"
V.   2-instructions synthesis followed by either "ADDX[248] Ax, Ax, Ax"
     or "SUBX8 Ax, Ax, Ax" (multiplying by 3, 5, 7 or 9)

gcc/ChangeLog:

* config/xtensa/xtensa-protos.h (xtensa_constantsynth):
New prototype.
* config/xtensa/xtensa.cc (xtensa_emit_constantsynth,
xtensa_constantsynth_2insn, xtensa_constantsynth_rtx_SLLI,
xtensa_constantsynth_rtx_ADDSUBX, xtensa_constantsynth):
New backend functions that process the abovementioned logic.
(xtensa_emit_move_sequence): Revert the previous changes.
* config/xtensa/xtensa.md: New split patterns for integer
and floating-point, as the frontend part.

gcc/testsuite/ChangeLog:

* gcc.target/xtensa/constsynth_2insns.c: New.
* gcc.target/xtensa/constsynth_3insns.c: Ditto.
* gcc.target/xtensa/constsynth_double.c: Ditto.
gcc/config/xtensa/xtensa-protos.h
gcc/config/xtensa/xtensa.cc
gcc/config/xtensa/xtensa.md
gcc/testsuite/gcc.target/xtensa/constsynth_2insns.c [new file with mode: 0644]
gcc/testsuite/gcc.target/xtensa/constsynth_3insns.c [new file with mode: 0644]
gcc/testsuite/gcc.target/xtensa/constsynth_double.c [new file with mode: 0644]