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(-)

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;
-- 
2.20.1

Reply via email to