aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/alpha
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2022-06-17 17:19:44 +0200
committerUros Bizjak <ubizjak@gmail.com>2022-06-17 17:20:41 +0200
commitcc378e655740e93743e7f43e14faaff707aef6c1 (patch)
treeebc5a99a346a71fd13642ef74806936c6111c251 /gcc/config/alpha
parent1f8278bfcfc7f7157bf2b405471e67dd5097636b (diff)
downloadgcc-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.h2
-rw-r--r--gcc/config/alpha/alpha.cc69
-rw-r--r--gcc/config/alpha/ev4.md15
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