diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2022-06-17 17:19:44 +0200 |
---|---|---|
committer | Uros Bizjak <ubizjak@gmail.com> | 2022-06-17 17:20:41 +0200 |
commit | cc378e655740e93743e7f43e14faaff707aef6c1 (patch) | |
tree | ebc5a99a346a71fd13642ef74806936c6111c251 /gcc/config/alpha | |
parent | 1f8278bfcfc7f7157bf2b405471e67dd5097636b (diff) | |
download | gcc-cc378e655740e93743e7f43e14faaff707aef6c1.zip gcc-cc378e655740e93743e7f43e14faaff707aef6c1.tar.gz gcc-cc378e655740e93743e7f43e14faaff707aef6c1.tar.bz2 |
alpha: Introduce target specific store_data_bypass_p function [PR105209]
This patch introduces alpha-specific version of store_data_bypass_p that
ignores TRAP_IF that would result in assertion failure (and internal
compiler error) in the generic store_data_bypass_p function.
While at it, also remove ev4_ist_c reservation, store_data_bypass_p
can handle the patterns with multiple sets since some time ago.
2022-06-17 Uroš Bizjak <ubizjak@gmail.com>
gcc/ChangeLog:
PR target/105209
* config/alpha/alpha-protos.h (alpha_store_data_bypass_p): New.
* config/alpha/alpha.cc (alpha_store_data_bypass_p): New function.
(alpha_store_data_bypass_p_1): Ditto.
* config/alpha/ev4.md: Use alpha_store_data_bypass_p instead
of generic store_data_bypass_p.
(ev4_ist_c): Remove insn reservation.
gcc/testsuite/ChangeLog:
PR target/105209
* gcc.target/alpha/pr105209.c: New test.
Diffstat (limited to 'gcc/config/alpha')
-rw-r--r-- | gcc/config/alpha/alpha-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.cc | 69 | ||||
-rw-r--r-- | gcc/config/alpha/ev4.md | 15 |
3 files changed, 75 insertions, 11 deletions
diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h index 0c832bf..adfdd77 100644 --- a/gcc/config/alpha/alpha-protos.h +++ b/gcc/config/alpha/alpha-protos.h @@ -73,6 +73,8 @@ extern void alpha_end_function (FILE *, const char *, tree); extern bool alpha_find_lo_sum_using_gp (rtx); +extern int alpha_store_data_bypass_p (rtx_insn *, rtx_insn *); + #ifdef REAL_VALUE_TYPE extern int check_float_value (machine_mode, REAL_VALUE_TYPE *, int); #endif diff --git a/gcc/config/alpha/alpha.cc b/gcc/config/alpha/alpha.cc index 3db5337..0a85e66 100644 --- a/gcc/config/alpha/alpha.cc +++ b/gcc/config/alpha/alpha.cc @@ -7564,6 +7564,75 @@ alpha_does_function_need_gp (void) return 0; } +/* Helper function for alpha_store_data_bypass_p, handle just a single SET + IN_SET. */ + +static bool +alpha_store_data_bypass_p_1 (rtx_insn *out_insn, rtx in_set) +{ + if (!MEM_P (SET_DEST (in_set))) + return false; + + rtx out_set = single_set (out_insn); + if (out_set) + return !reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set)); + + rtx out_pat = PATTERN (out_insn); + if (GET_CODE (out_pat) != PARALLEL) + return false; + + for (int i = 0; i < XVECLEN (out_pat, 0); i++) + { + rtx out_exp = XVECEXP (out_pat, 0, i); + + if (GET_CODE (out_exp) == CLOBBER || GET_CODE (out_exp) == USE + || GET_CODE (out_exp) == TRAP_IF) + continue; + + gcc_assert (GET_CODE (out_exp) == SET); + + if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set))) + return false; + } + + return true; +} + +/* True if the dependency between OUT_INSN and IN_INSN is on the store + data not the address operand(s) of the store. IN_INSN and OUT_INSN + must be either a single_set or a PARALLEL with SETs inside. + + This alpha-specific version of store_data_bypass_p ignores TRAP_IF + that would result in assertion failure (and internal compiler error) + in the generic store_data_bypass_p function. */ + +int +alpha_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn) +{ + rtx in_set = single_set (in_insn); + if (in_set) + return alpha_store_data_bypass_p_1 (out_insn, in_set); + + rtx in_pat = PATTERN (in_insn); + if (GET_CODE (in_pat) != PARALLEL) + return false; + + for (int i = 0; i < XVECLEN (in_pat, 0); i++) + { + rtx in_exp = XVECEXP (in_pat, 0, i); + + if (GET_CODE (in_exp) == CLOBBER || GET_CODE (in_exp) == USE + || GET_CODE (in_exp) == TRAP_IF) + continue; + + gcc_assert (GET_CODE (in_exp) == SET); + + if (!alpha_store_data_bypass_p_1 (out_insn, in_exp)) + return false; + } + + return true; +} /* Helper function to set RTX_FRAME_RELATED_P on instructions, including sequences. */ diff --git a/gcc/config/alpha/ev4.md b/gcc/config/alpha/ev4.md index 01b9a72..c8ff4ed 100644 --- a/gcc/config/alpha/ev4.md +++ b/gcc/config/alpha/ev4.md @@ -44,14 +44,7 @@ ; Stores can issue before the data (but not address) is ready. (define_insn_reservation "ev4_ist" 1 (and (eq_attr "tune" "ev4") - (eq_attr "type" "ist")) - "ev4_ib1+ev4_abox") - -; ??? Separate from ev4_ist because store_data_bypass_p can't handle -; the patterns with multiple sets, like store-conditional. -(define_insn_reservation "ev4_ist_c" 1 - (and (eq_attr "tune" "ev4") - (eq_attr "type" "st_c")) + (eq_attr "type" "ist,st_c")) "ev4_ib1+ev4_abox") (define_insn_reservation "ev4_fst" 1 @@ -110,7 +103,7 @@ (define_bypass 0 "ev4_iaddlog,ev4_shiftcm,ev4_icmp" "ev4_ist" - "store_data_bypass_p") + "alpha_store_data_bypass_p") ; Multiplies use a non-pipelined imul unit. Also, "no [ebox] insn can ; be issued exactly three cycles before an integer multiply completes". @@ -121,7 +114,7 @@ (eq_attr "opsize" "si"))) "ev4_ib0+ev4_imul,ev4_imul*18,ev4_ebox") -(define_bypass 20 "ev4_imulsi" "ev4_ist" "store_data_bypass_p") +(define_bypass 20 "ev4_imulsi" "ev4_ist" "alpha_store_data_bypass_p") (define_insn_reservation "ev4_imuldi" 23 (and (eq_attr "tune" "ev4") @@ -129,7 +122,7 @@ (eq_attr "opsize" "!si"))) "ev4_ib0+ev4_imul,ev4_imul*20,ev4_ebox") -(define_bypass 22 "ev4_imuldi" "ev4_ist" "store_data_bypass_p") +(define_bypass 22 "ev4_imuldi" "ev4_ist" "alpha_store_data_bypass_p") ; Most FP insns have a 6 cycle latency, but with a 4 cycle bypass back in. (define_insn_reservation "ev4_fpop" 6 |