xtensa: Defer storing integer constants into litpool until reload
Commit Message
Storing integer constants into litpool in the early stage of compilation
hinders some integer optimizations. In fact, such integer constants are
not subject to the constant folding process.
For example:
extern unsigned int value;
extern void foo(void);
void test(void) {
if (value == 30001)
foo();
}
.literal_position
.literal .LC0, value
.literal .LC1, 30001
test:
l32r a3, .LC0
l32r a2, .LC1
l16ui a3, a3, 0
extui a2, a2, 0, 16 // runtime zero-extension despite constant
bne a3, a2, .L1
j.l foo, a9
.L1:
ret.n
This patch defers the placement of integer constants into litpool until
the start of reload:
.literal_position
.literal .LC0, value
.literal .LC1, 30001
test:
l32r a3, .LC0
l32r a2, .LC1
l16ui a3, a3, 0
bne a3, a2, .L1
j.l foo, a9
.L1:
ret.n
gcc/ChangeLog:
* config/xtensa/constraints.md (Y):
Change to include integer constants until reload begins.
* config/xtensa/predicates.md (move_operand): Ditto.
* config/xtensa/xtensa.cc (xtensa_emit_move_sequence):
Change to allow storing integer constants into litpool only after
reload begins.
---
gcc/config/xtensa/constraints.md | 6 ++++--
gcc/config/xtensa/predicates.md | 5 +++--
gcc/config/xtensa/xtensa.cc | 3 ++-
3 files changed, 9 insertions(+), 5 deletions(-)
Comments
erratum:
- extern unsigned int value;
+ extern unsigned short value;
On 2022/06/17 22:47, Takayuki 'January June' Suwa via Gcc-patches wrote:
> Storing integer constants into litpool in the early stage of compilation
> hinders some integer optimizations. In fact, such integer constants are
> not subject to the constant folding process.
>
> For example:
>
> extern unsigned int value;
> extern void foo(void);
> void test(void) {
> if (value == 30001)
> foo();
> }
>
> .literal_position
> .literal .LC0, value
> .literal .LC1, 30001
> test:
> l32r a3, .LC0
> l32r a2, .LC1
> l16ui a3, a3, 0
> extui a2, a2, 0, 16 // runtime zero-extension despite constant
> bne a3, a2, .L1
> j.l foo, a9
> .L1:
> ret.n
>
> This patch defers the placement of integer constants into litpool until
> the start of reload:
>
> .literal_position
> .literal .LC0, value
> .literal .LC1, 30001
> test:
> l32r a3, .LC0
> l32r a2, .LC1
> l16ui a3, a3, 0
> bne a3, a2, .L1
> j.l foo, a9
> .L1:
> ret.n
>
> gcc/ChangeLog:
>
> * config/xtensa/constraints.md (Y):
> Change to include integer constants until reload begins.
> * config/xtensa/predicates.md (move_operand): Ditto.
> * config/xtensa/xtensa.cc (xtensa_emit_move_sequence):
> Change to allow storing integer constants into litpool only after
> reload begins.
On Fri, Jun 17, 2022 at 6:48 AM Takayuki 'January June' Suwa
<jjsuwa_sys3175@yahoo.co.jp> wrote:
>
> Storing integer constants into litpool in the early stage of compilation
> hinders some integer optimizations. In fact, such integer constants are
> not subject to the constant folding process.
>
> For example:
>
> extern unsigned int value;
> extern void foo(void);
> void test(void) {
> if (value == 30001)
> foo();
> }
>
> .literal_position
> .literal .LC0, value
> .literal .LC1, 30001
> test:
> l32r a3, .LC0
> l32r a2, .LC1
> l16ui a3, a3, 0
> extui a2, a2, 0, 16 // runtime zero-extension despite constant
> bne a3, a2, .L1
> j.l foo, a9
> .L1:
> ret.n
>
> This patch defers the placement of integer constants into litpool until
> the start of reload:
>
> .literal_position
> .literal .LC0, value
> .literal .LC1, 30001
> test:
> l32r a3, .LC0
> l32r a2, .LC1
> l16ui a3, a3, 0
> bne a3, a2, .L1
> j.l foo, a9
> .L1:
> ret.n
>
> gcc/ChangeLog:
>
> * config/xtensa/constraints.md (Y):
> Change to include integer constants until reload begins.
> * config/xtensa/predicates.md (move_operand): Ditto.
> * config/xtensa/xtensa.cc (xtensa_emit_move_sequence):
> Change to allow storing integer constants into litpool only after
> reload begins.
> ---
> gcc/config/xtensa/constraints.md | 6 ++++--
> gcc/config/xtensa/predicates.md | 5 +++--
> gcc/config/xtensa/xtensa.cc | 3 ++-
> 3 files changed, 9 insertions(+), 5 deletions(-)
Regtested for target=xtensa-linux-uclibc, no new regressions.
Folded in the description correction and committed to master.
@@ -113,8 +113,10 @@
(define_constraint "Y"
"A constant that can be used in relaxed MOVI instructions."
- (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
- (match_test "TARGET_AUTO_LITPOOLS")))
+ (ior (and (match_code "const_int,const_double,const,symbol_ref,label_ref")
+ (match_test "TARGET_AUTO_LITPOOLS"))
+ (and (match_code "const_int")
+ (match_test "can_create_pseudo_p ()"))))
;; Memory constraints. Do not use define_memory_constraint here. Doing so
;; causes reload to force some constants into the constant pool, but since
@@ -147,8 +147,9 @@
(match_test "!constantpool_mem_p (op)
|| GET_MODE_SIZE (mode) % UNITS_PER_WORD == 0")))
(ior (and (match_code "const_int")
- (match_test "GET_MODE_CLASS (mode) == MODE_INT
- && xtensa_simm12b (INTVAL (op))"))
+ (match_test "(GET_MODE_CLASS (mode) == MODE_INT
+ && xtensa_simm12b (INTVAL (op)))
+ || can_create_pseudo_p ()"))
(and (match_code "const_int,const_double,const,symbol_ref,label_ref")
(match_test "(TARGET_CONST16 || TARGET_AUTO_LITPOOLS)
&& CONSTANT_P (op)
@@ -1182,7 +1182,8 @@ xtensa_emit_move_sequence (rtx *operands, machine_mode mode)
return 1;
}
- if (! TARGET_AUTO_LITPOOLS && ! TARGET_CONST16)
+ if (! TARGET_AUTO_LITPOOLS && ! TARGET_CONST16
+ && ! (CONST_INT_P (src) && can_create_pseudo_p ()))
{
src = force_const_mem (SImode, src);
operands[1] = src;