aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>2018-01-02 22:56:45 +0000
committerWilliam Schmidt <wschmidt@gcc.gnu.org>2018-01-02 22:56:45 +0000
commit6012c652c778abaf9fb07fb1628435ff055dd349 (patch)
tree9c7959f41fe324a28bdfa3591a853985afeee38f
parentf1bdc63a898f2fa164e79528c03e96a21a779e82 (diff)
downloadgcc-6012c652c778abaf9fb07fb1628435ff055dd349.zip
gcc-6012c652c778abaf9fb07fb1628435ff055dd349.tar.gz
gcc-6012c652c778abaf9fb07fb1628435ff055dd349.tar.bz2
rs6000-p8swap.c (swap_feeds_both_load_and_store): New function.
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: r256111
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/rs6000/rs6000-p8swap.c40
2 files changed, 47 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4e5323c..bdf32da 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+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-02 Andrew Waterman <andrew@sifive.com>
* config/riscv/linux.h (ICACHE_FLUSH_FUNC): New.
diff --git a/gcc/config/rs6000/rs6000-p8swap.c b/gcc/config/rs6000/rs6000-p8swap.c
index e0d8f31..5a97116 100644
--- a/gcc/config/rs6000/rs6000-p8swap.c
+++ b/gcc/config/rs6000/rs6000-p8swap.c
@@ -328,6 +328,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)
@@ -2030,6 +2062,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)