]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: rs6000-p8swap.c (swap_feeds_both_load_and_store): New function.
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Wed, 24 Jan 2018 21:12:55 +0000 (21:12 +0000)
committerWilliam Schmidt <wschmidt@gcc.gnu.org>
Wed, 24 Jan 2018 21:12:55 +0000 (21:12 +0000)
2018-01-24  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

Backport from mainline
2018-01-02  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

* config/rs6000/rs6000-p8swap.c (swap_feeds_both_load_and_store):
New function.
(rs6000_analyze_swaps): Mark a web unoptimizable if it contains a
swap associated with both a load and a store.

From-SVN: r257030

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index 8d92bd8f4b7091e93805a7632212e4c63a98c4a3..1f67a87933012746c5c9cedb3ca1f8c8743d5167 100644 (file)
@@ -1,3 +1,13 @@
+2018-01-24  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       Backport from mainline
+       2018-01-02  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       * config/rs6000/rs6000-p8swap.c (swap_feeds_both_load_and_store):
+       New function.
+       (rs6000_analyze_swaps): Mark a web unoptimizable if it contains a
+       swap associated with both a load and a store.
+
 2018-01-23  Peter Bergner  <bergner@vnet.ibm.com>
 
        Back port from mainline
index 6423bf38da1f7025a13185aa0a16e285bc5e1d4f..784fdbe254d1fb308ffd5d551cfc05b2df4650a3 100644 (file)
@@ -38464,6 +38464,38 @@ insn_is_swap_p (rtx insn)
   return 1;
 }
 
+/* Return 1 iff UID, known to reference a swap, is both fed by a load
+   and a feeder of a store.  */
+static unsigned int
+swap_feeds_both_load_and_store (swap_web_entry *insn_entry)
+{
+  rtx insn = insn_entry->insn;
+  struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
+  df_ref def, use;
+  struct df_link *link = 0;
+  rtx_insn *load = 0, *store = 0;
+  bool fed_by_load = 0;
+  bool feeds_store = 0;
+
+  FOR_EACH_INSN_INFO_USE (use, insn_info)
+    {
+      link = DF_REF_CHAIN (use);
+      load = DF_REF_INSN (link->ref);
+      if (insn_is_load_p (load) && insn_is_swap_p (load))
+       fed_by_load = 1;
+    }
+
+  FOR_EACH_INSN_INFO_DEF (def, insn_info)
+    {
+      link = DF_REF_CHAIN (def);
+      store = DF_REF_INSN (link->ref);
+      if (insn_is_store_p (store) && insn_is_swap_p (store))
+       feeds_store = 1;
+    }
+
+  return fed_by_load && feeds_store;
+}
+
 /* Return TRUE if insn is a swap fed by a load from the constant pool.  */
 static bool
 const_load_sequence_p (swap_web_entry *insn_entry, rtx insn)
@@ -39620,6 +39652,14 @@ rs6000_analyze_swaps (function *fun)
          && !insn_entry[i].is_swap && !insn_entry[i].is_swappable)
        root->web_not_optimizable = 1;
 
+      /* If we have a swap that is both fed by a permuting load
+        and a feeder of a permuting store, then the optimization
+        isn't appropriate.  (Consider vec_xl followed by vec_xst_be.)  */
+      else if (insn_entry[i].is_swap && !insn_entry[i].is_load
+              && !insn_entry[i].is_store
+              && swap_feeds_both_load_and_store (&insn_entry[i]))
+       root->web_not_optimizable = 1;
+
       /* If we have permuting loads or stores that are not accompanied
         by a register swap, the optimization isn't appropriate.  */
       else if (insn_entry[i].is_load && insn_entry[i].is_swap)