From: Bill Schmidt Date: Wed, 24 Jan 2018 21:12:55 +0000 (+0000) Subject: backport: rs6000-p8swap.c (swap_feeds_both_load_and_store): New function. X-Git-Tag: releases/gcc-6.5.0~562 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3cc017d815042da573b9c8722b13d333274371c3;p=thirdparty%2Fgcc.git backport: rs6000-p8swap.c (swap_feeds_both_load_and_store): New function. 2018-01-24 Bill Schmidt Backport from mainline 2018-01-02 Bill Schmidt * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8d92bd8f4b70..1f67a8793301 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2018-01-24 Bill Schmidt + + Backport from mainline + 2018-01-02 Bill Schmidt + + * 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 Back port from mainline diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 6423bf38da1f..784fdbe254d1 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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)