When the Windowed Register Option (TARGET_WINDOWED_ABI) is enabled, and this
macro is not defined, "phantom" DF livenesses occurs in the function epilogue,
which can hinder certain optimizations. Indeed, in the following example,
the low-overhead loop optimization is rejected because the epilogue BB, which
succeeds the target loop BB, is incorrectly identified as using the loop
iterator.
/* example */
void test(char *q, const char *p, unsigned int n) {
do
*q = *p, ++q, ++p;
while (n-- != 1);
}
;; before (-mabi=windowed ; TARGET_LOOPS)
test:
entry sp, 32
movi.n a8, 0
.L2:
add.n a9, a3, a8
l8ui a10, a9, 0
add.n a9, a2, a8
s8i a10, a9, 0
addi.n a8, a8, 1
addi.n a4, a4, -1
bnez.n a4, .L2 ;; incorrectly identified as using A4
;; in the epilogue.
retw.n
This patch fixes the above issue by properly defining the relevant macro.
;; after (-mabi=windowed ; TARGET_LOOPS)
test:
entry sp, 32
movi.n a8, 0
loop a4, .L2_LEND
.L2:
add.n a9, a3, a8
l8ui a10, a9, 0
add.n a9, a2, a8
s8i a10, a9, 0
addi.n a8, a8, 1
.L2_LEND:
retw.n
gcc/ChangeLog:
* config/xtensa/xtensa.h (LOCAL_REGNO):
New macro definition.
((unsigned) ((IN) - GP_REG_FIRST) < WINDOW_SIZE)) ? \
(IN) + WINDOW_SIZE : (IN)) : (IN))
+#define LOCAL_REGNO(REGNO) \
+ (TARGET_WINDOWED_ABI && GP_REG_P (REGNO) \
+ && ((unsigned) ((REGNO) - GP_REG_FIRST) < WINDOW_SIZE))
/* Define the classes of registers for register constraints in the
machine description. */