xtensa: Defer storing integer constants into litpool until reload

Message ID 17c66d91-37c5-7891-5489-955b4dc8a059@yahoo.co.jp
State Committed
Commit 479b6f449ee999501ad6eff0b7db8d0cd5b2d28d
Headers
Series xtensa: Defer storing integer constants into litpool until reload |

Commit Message

Takayuki 'January June' Suwa June 17, 2022, 1:47 p.m. UTC
  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

Takayuki 'January June' Suwa June 17, 2022, 1:57 p.m. UTC | #1
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.
  
Max Filippov June 18, 2022, 6:31 a.m. UTC | #2
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.
  

Patch

diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md
index e7ac8dbfebf..0b7dcd1440e 100644
--- a/gcc/config/xtensa/constraints.md
+++ b/gcc/config/xtensa/constraints.md
@@ -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
diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md
index edd13ae41b9..0590c0f81a9 100644
--- a/gcc/config/xtensa/predicates.md
+++ b/gcc/config/xtensa/predicates.md
@@ -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)
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index d6f08b11648..c5d00acdf2c 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -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;