This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, ARM] PR71607: New approach to arm_disable_literal_pool


Hello,

This patch tackles the issue reported in PR71607. This patch takes a
different approach for disabling the creation of literal pools. Instead
of disabling the patterns that would normally transform the rtl into
actual literal pools, it disables the creation of this literal pool rtl
by making the target hook TARGET_CANNOT_FORCE_CONST_MEM return true if
arm_disable_literal_pool is true. I added patterns to split floating
point constants for both SF and DFmode. A pattern to handle the
addressing of label_refs had to be included as well since all
"memory_operand" patterns are disabled when
TARGET_CANNOT_FORCE_CONST_MEM returns true. Also the pattern for
splitting 32-bit immediates had to be changed, it was not accepting
unsigned 32-bit unsigned integers with the MSB set. I believe
const_int_operand expects the mode of the operand to be set to VOIDmode
and not SImode. I have only changed it in the patterns that were
affecting this code, though I suggest looking into changing it in the
rest of the ARM backend.

I added more test cases. No regressions for arm-none-eabi with
Cortex-M0, Cortex-M3 and Cortex-M7.

Is this OK for trunk?

Cheers,
Andre

gcc/ChangeLog:

2016-10-06  Andre Vieira  <andre.simoesdiasvieira@arm.com>

    PR target/71607
    * config/arm/arm.md (use_literal_pool): Remove.
    (64-bit immediate split): No longer take cost into consideration
    if 'arm_disable_literal_pool' is enabled.
    (32-bit const split): Remove SImode from constant, which was
    not allowing large unsigned integers to be split.
    * config/arm/arm.c (thumb2_legitimate_address_p): Remove handling
    of 'arm_disable_literal_pool' here.
    (arm_max_const_double_inline_cost): Likewise.
    (arm_cannot_force_const_mem): Return false for
'arm_disable_literal_pool'.
    (thumb2_legitimate_address_p): Remove check involving
'arm_disable_literal_pool'
    that is no longer relevant.
    (arm_legitimate_constant_p): Ignore the outcome of
'arm_cannot_force_const_mem'
    if 'arm_disable_literal_pool' is enabled.
    * config/arm/vfp.md (no_literal_pool_df_immediate): New.
    (no_literal_pool_sf_immediate): New.
    * config/arm/thumb2.md (*thumb2_movsi_labelref_insn): New.

gcc/testsuite/ChangeLog:

2016-10-06  Andre Vieira  <andre.simoesdiasvieira@arm.com>
            Thomas Preud'homme  <thomas.preudhomme@arm.com>

    PR target/71607
    * gcc.target/arm/thumb2-slow-flash-data.c: Rename to ...
    * gcc.target/arm/thumb2-slow-flash-data-1.c: ... this.
    * gcc.target/arm/thumb2-slow-flash-data-2.c: New.
    * gcc.target/arm/thumb2-slow-flash-data-3.c: New.


From 88304e3d5507787a5453c9745c42c4c5f4093975 Mon Sep 17 00:00:00 2001
From: Andre Simoes Dias Vieira <andre.simoesdiasvieira@arm.com>
Date: Tue, 30 Aug 2016 13:26:49 +0100
Subject: [PATCH 1/2] gcc32rm-709

Fix disabling of literal pool

mend
---
 gcc/config/arm/arm.c                               | 30 ++-------
 gcc/config/arm/arm.md                              | 13 ++--
 gcc/config/arm/thumb2.md                           | 11 ++++
 gcc/config/arm/vfp.md                              | 34 ++++++++++
 .../gcc.target/arm/thumb2-slow-flash-data-1.c      | 73 ++++++++++++++++++++++
 .../gcc.target/arm/thumb2-slow-flash-data-2.c      | 27 ++++++++
 .../gcc.target/arm/thumb2-slow-flash-data-3.c      | 24 +++++++
 .../gcc.target/arm/thumb2-slow-flash-data.c        | 73 ----------------------
 8 files changed, 179 insertions(+), 106 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-1.c
 create mode 100644 gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-2.c
 create mode 100644 gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-3.c
 delete mode 100644 gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data.c

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 946f308ca84e232af8af6eca4813464914cbd59c..dce2569a2c3867464039e6a57e11acee2b28c423 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -7380,25 +7380,6 @@ thumb2_legitimate_address_p (machine_mode mode, rtx x, int strict_p)
 		  && thumb2_legitimate_index_p (mode, xop0, strict_p)));
     }
 
-  /* Normally we can assign constant values to target registers without
-     the help of constant pool.  But there are cases we have to use constant
-     pool like:
-     1) assign a label to register.
-     2) sign-extend a 8bit value to 32bit and then assign to register.
-
-     Constant pool access in format:
-     (set (reg r0) (mem (symbol_ref (".LC0"))))
-     will cause the use of literal pool (later in function arm_reorg).
-     So here we mark such format as an invalid format, then the compiler
-     will adjust it into:
-     (set (reg r0) (symbol_ref (".LC0")))
-     (set (reg r0) (mem (reg r0))).
-     No extra register is required, and (mem (reg r0)) won't cause the use
-     of literal pools.  */
-  else if (arm_disable_literal_pool && code == SYMBOL_REF
-	   && CONSTANT_POOL_ADDRESS_P (x))
-    return 0;
-
   else if (GET_MODE_CLASS (mode) != MODE_FLOAT
 	   && code == SYMBOL_REF
 	   && CONSTANT_POOL_ADDRESS_P (x)
@@ -8295,7 +8276,7 @@ thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
 static bool
 arm_legitimate_constant_p (machine_mode mode, rtx x)
 {
-  return (!arm_cannot_force_const_mem (mode, x)
+  return (!(arm_cannot_force_const_mem (mode, x) && !arm_disable_literal_pool)
 	  && (TARGET_32BIT
 	      ? arm_legitimate_constant_p_1 (mode, x)
 	      : thumb_legitimate_constant_p (mode, x)));
@@ -8308,6 +8289,9 @@ arm_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
 {
   rtx base, offset;
 
+  if (arm_disable_literal_pool)
+    return true;
+
   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
     {
       split_const (x, &base, &offset);
@@ -17173,10 +17157,6 @@ push_minipool_fix (rtx_insn *insn, HOST_WIDE_INT address, rtx *loc,
 int
 arm_max_const_double_inline_cost ()
 {
-  /* Let the value get synthesized to avoid the use of literal pools.  */
-  if (arm_disable_literal_pool)
-    return 99;
-
   return ((optimize_size || arm_ld_sched) ? 3 : 4);
 }
 
@@ -17746,7 +17726,7 @@ arm_reorg (void)
 	  ftmp = last_barrier;
 	}
       else
-        {
+	{
 	  /* ftmp is first fix that we can't fit into this pool and
 	     there no natural barriers that we could use.  Insert a
 	     new barrier in the code somewhere between the previous
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 318db75ece9615412b48943ba197aae364a78a54..80a9fe7c700e46abd5a4d9baade0c18e0d3cbe5a 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -233,10 +233,6 @@
 	       (match_test "arm_restrict_it"))
 	  (const_string "no")
 
-	  (and (eq_attr "use_literal_pool" "yes")
-	       (match_test "arm_disable_literal_pool"))
-	  (const_string "no")
-
 	  (eq_attr "arch_enabled" "no")
 	  (const_string "no")]
 	 (const_string "yes")))
@@ -5853,8 +5849,9 @@
 	(match_operand:ANY64 1 "immediate_operand" ""))]
   "TARGET_32BIT
    && reload_completed
-   && (arm_const_double_inline_cost (operands[1])
-       <= arm_max_const_double_inline_cost ())"
+   && (arm_disable_literal_pool
+       || (arm_const_double_inline_cost (operands[1])
+	   <= arm_max_const_double_inline_cost ()))"
   [(const_int 0)]
   "
   arm_split_constant (SET, SImode, curr_insn,
@@ -6070,7 +6067,7 @@
 
 (define_split
   [(set (match_operand:SI 0 "arm_general_register_operand" "")
-	(match_operand:SI 1 "const_int_operand" ""))]
+	(match_operand 1 "const_int_operand" ""))]
   "TARGET_32BIT
   && (!(const_ok_for_arm (INTVAL (operands[1]))
         || const_ok_for_arm (~INTVAL (operands[1]))))"
@@ -6099,7 +6096,7 @@
 (define_split
   [(set (match_operand:SI 0 "arm_general_register_operand" "")
 	(const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
-			   (match_operand:SI 2 "const_int_operand" ""))))]
+			   (match_operand 2 "const_int_operand" ""))))]
   "TARGET_THUMB
    && TARGET_HAVE_MOVT
    && arm_disable_literal_pool
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index ab08288413c3e64911e8d7a8199b9809e0282d8e..217ca36f53130f89e0e0c893035d35505cd150f3 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -300,6 +300,17 @@
    (set_attr "neg_pool_range" "*,*,*,*,*,0,0,*,*")]
 )
 
+(define_insn "*thumb2_movsi_labelref_insn"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=l")
+    (label_ref (match_operand 1 "" "")))]
+    "TARGET_HAVE_MOVT && arm_disable_literal_pool"
+    "movt%?\\t%0, #:upper16:%l1\;movw%?\\t%0, #:lower16:%l1"
+    [(set_attr "type" "multiple")
+     (set_attr "length" "8")
+     (set_attr "ce_count" "2")
+     (set_attr "predicable" "yes")
+     (set_attr "predicable_short_it" "no")])
+
 (define_insn "tls_load_dot_plus_four"
   [(set (match_operand:SI 0 "register_operand" "=l,l,r,r")
 	(mem:SI (unspec:SI [(match_operand:SI 2 "register_operand" "0,1,0,1")
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index 9750ba16260af5a10defc7cfcecd5e8f78039205..62f7e348e253f8608a9bdb41a42e2997d5a1f24e 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -1410,3 +1410,37 @@
 ;; fmdhr et al (VFPv1)
 ;; Support for xD (single precision only) variants.
 ;; fmrrs, fmsrr
+
+;; Split an immediate DF move to two immediate SI moves.
+(define_insn_and_split "no_literal_pool_df_immediate"
+  [(set (match_operand 0 "s_register_operand" "")
+	(match_operand:DF 1 "const_double_operand" ""))]
+  "TARGET_THUMB2 && arm_disable_literal_pool"
+  "#"
+  "&& !reload_completed"
+  [(set (subreg:SI (match_dup 1) 0) (match_dup 2))
+   (set (subreg:SI (match_dup 1) 4) (match_dup 3))
+   (set (match_dup 0) (match_dup 1))]
+  "
+  long buf[2];
+  real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
+  operands[2] = GEN_INT (buf[0]);
+  operands[3] = GEN_INT (buf[1]);
+  operands[1] = gen_reg_rtx (DFmode);
+  ")
+
+;; Split an immediate SF move to one immediate SI move.
+(define_insn_and_split "no_literal_pool_sf_immediate"
+  [(set (match_operand 0 "s_register_operand" "")
+	(match_operand:SF 1 "const_double_operand" ""))]
+  "TARGET_THUMB2 && arm_disable_literal_pool"
+  "#"
+  "&& !reload_completed"
+  [(set (subreg:SI (match_dup 1) 0) (match_dup 2))
+   (set (match_dup 0) (match_dup 1))]
+  "
+  long buf;
+  real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
+  operands[2] = GEN_INT (buf);
+  operands[1] = gen_reg_rtx (SFmode);
+  ")
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-1.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..089a72b67f3af570dbbed248a64a18b8b4e89ba4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-1.c
@@ -0,0 +1,73 @@
+/* The option -mslow-flash-data is just for performance tuning, it
+   doesn't totally disable the use of literal pools.  But for below
+   simple cases, the use of literal pool should be replaced by
+   movw/movt or read-only constant pool.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_cortex_m } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-options "-O2 -mthumb -mslow-flash-data" } */
+
+float sf;
+double df;
+long long l;
+static char *p = "Hello World";
+
+float
+testsf (float *p)
+{
+  if (*p > 1.1234f)
+    return 2.1234f;
+  else
+    return 3.1234f;
+}
+
+double
+testdf (double *p)
+{
+  if (*p > 4.1234)
+    return 2.1234;
+  else
+    return 3.1234;
+}
+
+long long
+testll (long long *p)
+{
+  if (*p > 0x123456789ABCDEFll)
+    return 0x111111111ll;
+  else
+    return 0x222222222ll;
+}
+
+char *
+testchar ()
+{
+  return p + 4;
+}
+
+int
+foo (int a, int b)
+{
+  int i;
+  volatile int *labelref = &&label1;
+
+  if (a > b)
+    {
+      while (i < b)
+	{
+	  a += *labelref;
+	  i += 1;
+	}
+      goto *labelref;
+    }
+  else
+    b = b + 3;
+
+  a = a * b;
+
+label1:
+  return a + b;
+}
+
+/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-2.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..c52de113809b63986a4621524d68686fc795f7ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-2.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_cortex_m } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
+/* { dg-options "-O2 -mthumb -mfloat-abi=hard -mslow-flash-data" } */
+
+float f (float);
+
+const float max = 0.01f;
+
+int
+g (float in)
+{
+  if (f (in) + f (in) < max)
+    return 0;
+  return 1;
+}
+
+double foo (void)
+{
+  return 0xF1EC7A5239123AF;
+}
+
+double bar (void)
+{
+  return 0.0f;
+}
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-3.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..d25ba87413cb949e5e2162dbf4e695e205b01a34
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-3.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_cortex_m } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
+/* { dg-options "-mthumb -mfloat-abi=hard -mslow-flash-data" } */
+
+/* From PR71607 */
+
+float b;
+void fn1 ();
+
+float
+fn2 ()
+{
+  return 1.1f;
+}
+
+void
+fn3 ()
+{
+  float a[2];
+  a[1] = b;
+  fn1 (a);
+}
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data.c
deleted file mode 100644
index 089a72b67f3af570dbbed248a64a18b8b4e89ba4..0000000000000000000000000000000000000000
--- a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* The option -mslow-flash-data is just for performance tuning, it
-   doesn't totally disable the use of literal pools.  But for below
-   simple cases, the use of literal pool should be replaced by
-   movw/movt or read-only constant pool.  */
-
-/* { dg-do compile } */
-/* { dg-require-effective-target arm_cortex_m } */
-/* { dg-require-effective-target arm_thumb2_ok } */
-/* { dg-options "-O2 -mthumb -mslow-flash-data" } */
-
-float sf;
-double df;
-long long l;
-static char *p = "Hello World";
-
-float
-testsf (float *p)
-{
-  if (*p > 1.1234f)
-    return 2.1234f;
-  else
-    return 3.1234f;
-}
-
-double
-testdf (double *p)
-{
-  if (*p > 4.1234)
-    return 2.1234;
-  else
-    return 3.1234;
-}
-
-long long
-testll (long long *p)
-{
-  if (*p > 0x123456789ABCDEFll)
-    return 0x111111111ll;
-  else
-    return 0x222222222ll;
-}
-
-char *
-testchar ()
-{
-  return p + 4;
-}
-
-int
-foo (int a, int b)
-{
-  int i;
-  volatile int *labelref = &&label1;
-
-  if (a > b)
-    {
-      while (i < b)
-	{
-	  a += *labelref;
-	  i += 1;
-	}
-      goto *labelref;
-    }
-  else
-    b = b + 3;
-
-  a = a * b;
-
-label1:
-  return a + b;
-}
-
-/* { dg-final { scan-assembler-not "\\.(float|l\\?double|\d?byte|short|int|long|quad|word)\\s+\[^.\]" } } */
-- 
1.9.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]