combine.c (try_combine): Canonicalize (plus (mult X pow2) Y) into (plus (ashift X...
authorJeff Law <law@redhat.com>
Fri, 22 May 2015 20:08:43 +0000 (14:08 -0600)
committerJeff Law <law@gcc.gnu.org>
Fri, 22 May 2015 20:08:43 +0000 (14:08 -0600)
* combine.c (try_combine): Canonicalize (plus (mult X pow2) Y) into
(plus (ashift X log2) Y) if it is a split point.

* gcc.target/hppa/shadd-3.c: New test.

From-SVN: r223583

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/hppa/shadd-3.c [new file with mode: 0644]

index e2d49e67f1349ba80d3b7ee4cdc30e0f67ed827c..a6f06d9dfe31ca4fd4c987a521672bf6cc673ae1 100644 (file)
@@ -1,5 +1,8 @@
 2015-05-22  Jeff Law  <law@redhat.com>
 
+       * combine.c (try_combine): Canonicalize (plus (mult X pow2) Y) into
+       (plus (ashift X log2) Y) if it is a split point.
+
        * pa.c (mem_shadd_or_shadd_rtx_p): New function factored out
        of hppa_legitimize_address to handle both forms of a multiply
        by 2, 4 or 8.
index 4a57557fe8cf16481fa5a56d621cf8b970d3a0de..0817af2a2a376884f0843c01d62121106383bf78 100644 (file)
@@ -3746,6 +3746,21 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
              split_code = GET_CODE (*split);
            }
 
+         /* Similarly for (plus (mult FOO (const_int pow2))).  */
+         if (split_code == PLUS
+             && GET_CODE (XEXP (*split, 0)) == MULT
+             && CONST_INT_P (XEXP (XEXP (*split, 0), 1))
+             && INTVAL (XEXP (XEXP (*split, 0), 1)) > 0
+             && (i = exact_log2 (UINTVAL (XEXP (XEXP (*split, 0), 1)))) >= 0)
+           {
+             rtx nsplit = XEXP (*split, 0);
+             SUBST (XEXP (*split, 0), gen_rtx_ASHIFT (GET_MODE (nsplit),
+                                            XEXP (nsplit, 0), GEN_INT (i)));
+             /* Update split_code because we may not have a multiply
+                anymore.  */
+             split_code = GET_CODE (*split);
+           }
+
 #ifdef INSN_SCHEDULING
          /* If *SPLIT is a paradoxical SUBREG, when we split it, it should
             be written as a ZERO_EXTEND.  */
index b5b7b9f9a074781fc55ea03b7cf7bb2b0f1698c1..0b0de20c7dffee1f4ef61103cf539f4c66e7f4f9 100644 (file)
 
 2015-05-21  Jeff Law  <law@redhat.com>
 
+       * gcc.target/hppa/shadd-3.c: New test.
        * gcc.target/hppa/shadd-4.c: New test.
 
 2015-05-21  Michael Matz  <matz@suse.de>
diff --git a/gcc/testsuite/gcc.target/hppa/shadd-3.c b/gcc/testsuite/gcc.target/hppa/shadd-3.c
new file mode 100644 (file)
index 0000000..f0443ea
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do compile }  */
+/* { dg-options "-O2" }  */
+/* In this test we want to verify that combine canonicalizes the
+   MULT into an ASHIFT which in turn allows postreload-gcse to
+   find the common subexpression.
+
+   Neither pass dumps stuff in a format that is particularly good
+   for parsing here, so we count the shadd insns.  More is not
+   necessarily better in this test.  If this test is too fragile
+   over time we'll have to revisit the combine and/or postreload
+   dumps.  */
+/* { dg-final { scan-assembler-times "sh.add" 5 } }  */
+
+extern void oof (void);
+typedef struct simple_bitmap_def *sbitmap;
+struct simple_bitmap_def
+{
+  unsigned char *popcount;
+  unsigned int n_bits;
+  unsigned long elms[1];
+};
+__inline__ void
+SET_BIT (sbitmap map, unsigned int bitno)
+{
+  if (map->popcount)
+    {
+      unsigned char oldbit;
+      oldbit =
+       ((map)->elms[bitno / 64]);
+      if (!oldbit)
+       oof ();
+    }
+  map->elms[bitno / 64] |= 1;
+}
+
+void
+fix_bb_placements (int indx1, int indx2, sbitmap in_queue)
+{
+  SET_BIT (in_queue, indx1);
+  SET_BIT (in_queue, indx2);
+}