The ev6 has two clusters, {U0,L0} and {U1,L1}, whose register files are
resynchronized once a cycle, so a value produced in one cluster and
consumed in the other arrives a cycle late. ev6.md carried a note
suggesting that this be modeled by duplicating every EBOX reservation,
raising all latencies by one and adding bypasses within each cluster.
On an EV68AL that would be wrong. Cluster assignment happens
dynamically at issue, and the hardware puts a dependent consumer in its
producer's cluster whenever it can: a dependent add chain costs 1.008
cycles per link, not the 2 that duplicated reservations would give.
The delay is only forced between units that exist in a single cluster.
The count/MVI unit is U0 only and the multiplier is U1 only, so a
dependence between them has to cross. A ctpop chain costs 3 cycles per
link and a mulq chain 7, and a chain alternating between them costs
24.2 cycles per four links, against 20 with no penalty and 24 with a
one-cycle penalty on each crossing.
Add a bypass in each direction and replace the note.
gcc/ChangeLog:
* config/alpha/ev6.md: Add bypasses between ev6_mvi and ev6_imul
for the cross-cluster delay. Replace the note about modeling it
by duplicating the EBOX reservations.
---
gcc/config/alpha/ev6.md | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/gcc/config/alpha/ev6.md b/gcc/config/alpha/ev6.md
index 3c1e6cafb38..edc2c9e0eff 100644
--- a/gcc/config/alpha/ev6.md
+++ b/gcc/config/alpha/ev6.md
@@ -24,11 +24,13 @@
; EV6 has two symmetric pairs ("clusters") of two asymmetric integer
; units ("upper" and "lower"), yielding pipe names U0, U1, L0, L1.
;
-; ??? The clusters have independent register files that are re-synced
-; every cycle. Thus there is one additional cycle of latency between
-; insns issued on different clusters. Possibly model that by duplicating
-; all EBOX insn_reservations that can issue to either cluster, increasing
-; all latencies by one, and adding bypasses within the cluster.
+; The clusters have independent register files that are re-synced every cycle,
+; so there is one additional cycle of latency between insns issued on different
+; clusters. Duplicating every EBOX reservation to model that would be wrong:
+; the hardware issues a dependent consumer into its producer's cluster whenever
+; it can, and a dependent add chain measures one cycle per link on an EV68AL,
+; not two. The delay is only forced between units that exist in a single
+; cluster, and is modeled below as bypasses between them.
;
; ??? In addition, instruction order affects cluster issue.
@@ -107,6 +109,13 @@
(eq_attr "type" "imul"))
"ev6_u1")
+; The count/MVI unit exists only in U0 and the multiplier only in U1, so a
+; dependence between them always crosses clusters. On an EV68AL a ctpop chain
+; costs 3 per link and a mulq chain 7, and a chain alternating between them
+; costs 24.2 per four links, which is 20 plus one cycle per crossing.
+(define_bypass 4 "ev6_mvi" "ev6_imul")
+(define_bypass 8 "ev6_imul" "ev6_mvi")
+
; Conditional moves decompose into two independent primitives, each taking
; one cycle. Since ev6 is out-of-order, we can't see anything but two cycles.
(define_insn_reservation "ev6_icmov" 2
--
2.56.1