From ebbcbc2ed315384e2689ffcaf6141febb9e01765 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Sun, 11 Nov 2012 20:17:17 +0100 Subject: [PATCH] re PR target/47440 (Use LCM for vzeroupper insertion) PR target/47440 * config/i386/i386.c (check_avx256_stores): Remove. (ix86_check_avx256_register): New. (ix86_avx_u128_mode_needed): Use ix86_check_avx256_register. Check the whole RTX for 256bit registers using for_each_rtx. (ix86_check_avx_stores): New. (ix86_avx_u128_mode_after): Change mode of CALL RTX to AVX_U128_CLEAN if there are no 256bit registers used in the function return register. (ix86_avx_u128_mode_entry): Use ix86_check_avx256_register. (ix86_avx_u128_mode_exit): Ditto. From-SVN: r193409 --- gcc/ChangeLog | 17 ++++++++++-- gcc/config/i386/i386.c | 71 +++++++++++++++++++++++++++----------------------- 2 files changed, 54 insertions(+), 34 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 535c0ef..8149a85 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,10 +1,23 @@ +2012-11-10 Uros Bizjak + + PR target/47440 + * config/i386/i386.c (check_avx256_stores): Remove. + (ix86_check_avx256_register): New. + (ix86_avx_u128_mode_needed): Use ix86_check_avx256_register. + Check the whole RTX for 256bit registers using for_each_rtx. + (ix86_check_avx_stores): New. + (ix86_avx_u128_mode_after): Change mode of CALL RTX to AVX_U128_CLEAN + if there are no 256bit registers used in the function return register. + (ix86_avx_u128_mode_entry): Use ix86_check_avx256_register. + (ix86_avx_u128_mode_exit): Ditto. + 2012-11-10 Jan Hubicka PR middle-end/48636 * ipa-inline.c (want_inline_small_function_p): Take aray index hint. (edge_badness): Likewise. * ipa-inline.h (inline_hints_vals): Add array_index and comments. - (inline_summary_: Add ARRAY_INDEX. + (inline_summary): Add ARRAY_INDEX. * ipa-inline-analysis.c (dump_inline_hints): Dump array_index hint. (reset_inline_summary): Handle array_index hint. (inline_node_duplication_hook): Likewise. @@ -27,7 +40,7 @@ 2012-11-10 Sandra Loosemore - * doc/extend.texi: Copy-edit to fix incorrect uses of "which" + * doc/extend.texi: Copy-edit to fix incorrect uses of "which" and "that" throughout the file. 2012-11-10 Andrew Pinski diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 60a39b8..0872295 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -14942,20 +14942,16 @@ output_387_binary_op (rtx insn, rtx *operands) return buf; } -/* Check if a 256bit AVX register is referenced in stores. */ +/* Check if a 256bit AVX register is referenced inside of EXP. */ -static void -check_avx256_stores (rtx dest, const_rtx set, void *data) +static int +ix86_check_avx256_register (rtx *exp, void *data ATTRIBUTE_UNUSED) { - if (((REG_P (dest) || MEM_P (dest)) - && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (dest))) - || (GET_CODE (set) == SET - && (REG_P (SET_SRC (set)) || MEM_P (SET_SRC (set))) - && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (SET_SRC (set))))) - { - bool *used = (bool *) data; - *used = true; - } + if (REG_P (*exp) + && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (*exp))) + return 1; + + return 0; } /* Return needed mode for entity in optimize_mode_switching pass. */ @@ -14963,8 +14959,6 @@ check_avx256_stores (rtx dest, const_rtx set, void *data) static int ix86_avx_u128_mode_needed (rtx insn) { - bool avx_u128_used; - if (CALL_P (insn)) { rtx link; @@ -14979,8 +14973,7 @@ ix86_avx_u128_mode_needed (rtx insn) { rtx arg = XEXP (XEXP (link, 0), 0); - if (REG_P (arg) - && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (arg))) + if (ix86_check_avx256_register (&arg, NULL)) return AVX_U128_ANY; } } @@ -14988,10 +14981,11 @@ ix86_avx_u128_mode_needed (rtx insn) return AVX_U128_CLEAN; } - /* Check if a 256bit AVX register is referenced in stores. */ - avx_u128_used = false; - note_stores (PATTERN (insn), check_avx256_stores, &avx_u128_used); - if (avx_u128_used) + /* Require DIRTY mode if a 256bit AVX register is referenced. Hardware + changes state only when a 256bit register is written to, but we need + to prevent the compiler from moving optimal insertion point above + eventual read from 256bit register. */ + if (for_each_rtx (&PATTERN (insn), ix86_check_avx256_register, NULL)) return AVX_U128_DIRTY; return AVX_U128_ANY; @@ -15071,28 +15065,42 @@ ix86_mode_needed (int entity, rtx insn) return 0; } +/* Check if a 256bit AVX register is referenced in stores. */ + +static void +ix86_check_avx256_stores (rtx dest, const_rtx set ATTRIBUTE_UNUSED, void *data) + { + if (ix86_check_avx256_register (&dest, NULL)) + { + bool *used = (bool *) data; + *used = true; + } + } + /* Calculate mode of upper 128bit AVX registers after the insn. */ static int ix86_avx_u128_mode_after (int mode, rtx insn) { rtx pat = PATTERN (insn); - bool avx_u128_used; if (vzeroupper_operation (pat, VOIDmode) || vzeroall_operation (pat, VOIDmode)) return AVX_U128_CLEAN; - /* Check if a 256bit AVX register is referenced in stores. */ - avx_u128_used = false; - note_stores (pat, check_avx256_stores, &avx_u128_used); - if (avx_u128_used) - return AVX_U128_DIRTY; /* We know that state is clean after CALL insn if there are no - 256bit modes used in the function return register. */ - else if (CALL_P (insn)) - return AVX_U128_CLEAN; + 256bit registers used in the function return register. */ + if (CALL_P (insn)) + { + bool avx_reg256_found = false; + note_stores (pat, ix86_check_avx256_stores, &avx_reg256_found); + if (!avx_reg256_found) + return AVX_U128_CLEAN; + } + /* Otherwise, return current mode. Remember that if insn + references AVX 256bit registers, the mode was already changed + to DIRTY from MODE_NEEDED. */ return mode; } @@ -15127,8 +15135,7 @@ ix86_avx_u128_mode_entry (void) { rtx incoming = DECL_INCOMING_RTL (arg); - if (incoming && REG_P (incoming) - && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (incoming))) + if (incoming && ix86_check_avx256_register (&incoming, NULL)) return AVX_U128_DIRTY; } @@ -15162,7 +15169,7 @@ ix86_avx_u128_mode_exit (void) /* Exit mode is set to AVX_U128_DIRTY if there are 256bit modes used in the function return register. */ - if (reg && REG_P (reg) && VALID_AVX256_REG_OR_OI_MODE (GET_MODE (reg))) + if (reg && ix86_check_avx256_register (®, NULL)) return AVX_U128_DIRTY; return AVX_U128_CLEAN; -- 2.7.4