From ec716cecdadd25ddd31d58bd2ece2ae161f945d0 Mon Sep 17 00:00:00 2001 From: Hal Finkel Date: Sun, 1 Feb 2015 17:52:16 +0000 Subject: [PATCH] [PowerPC] Better scheduling for isel on P7/P8 isel is actually a cracked instruction on the P7/P8, and must start a dispatch group. The scheduling model should reflect this so that we don't bunch too many of them together when possible. Thanks to Bill Schmidt and Pat Haugen for helping to sort this out. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227758 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCInstr64Bit.td | 2 +- lib/Target/PowerPC/PPCInstrInfo.td | 2 +- lib/Target/PowerPC/PPCSchedule.td | 2 ++ lib/Target/PowerPC/PPCSchedule440.td | 8 ++++++ lib/Target/PowerPC/PPCScheduleA2.td | 2 ++ lib/Target/PowerPC/PPCScheduleE500mc.td | 6 +++++ lib/Target/PowerPC/PPCScheduleE5500.td | 6 +++++ lib/Target/PowerPC/PPCScheduleP7.td | 4 +++ lib/Target/PowerPC/PPCScheduleP8.td | 4 +++ test/CodeGen/PowerPC/p8-isel-sched.ll | 33 +++++++++++++++++++++++++ 10 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/PowerPC/p8-isel-sched.ll diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index 19c33942bf4..0ba6ecb5a60 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -686,7 +686,7 @@ defm RLWIMI8 : MForm_2r<20, (outs g8rc:$rA), let isSelect = 1 in def ISEL8 : AForm_4<31, 15, (outs g8rc:$rT), (ins g8rc_nox0:$rA, g8rc:$rB, crbitrc:$cond), - "isel $rT, $rA, $rB, $cond", IIC_IntGeneral, + "isel $rT, $rA, $rB, $cond", IIC_IntISEL, []>; } // Interpretation64Bit } // hasSideEffects = 0 diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 8027e8307fd..65a71e4cc5c 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -2377,7 +2377,7 @@ let PPC970_Unit = 1 in { // FXU Operations. let isSelect = 1 in def ISEL : AForm_4<31, 15, (outs gprc:$rT), (ins gprc_nor0:$rA, gprc:$rB, crbitrc:$cond), - "isel $rT, $rA, $rB, $cond", IIC_IntGeneral, + "isel $rT, $rA, $rB, $cond", IIC_IntISEL, []>; } diff --git a/lib/Target/PowerPC/PPCSchedule.td b/lib/Target/PowerPC/PPCSchedule.td index 3ae3793f1a8..2f3a1f983bc 100644 --- a/lib/Target/PowerPC/PPCSchedule.td +++ b/lib/Target/PowerPC/PPCSchedule.td @@ -13,6 +13,7 @@ def IIC_IntSimple : InstrItinClass; def IIC_IntGeneral : InstrItinClass; def IIC_IntCompare : InstrItinClass; +def IIC_IntISEL : InstrItinClass; def IIC_IntDivD : InstrItinClass; def IIC_IntDivW : InstrItinClass; def IIC_IntMFFS : InstrItinClass; @@ -217,6 +218,7 @@ include "PPCScheduleE5500.td" // fsub IIC_FPAddSub // fsubs IIC_FPGeneral // icbi IIC_LdStICBI +// isel IIC_IntISEL // isync IIC_SprISYNC // lbz IIC_LdStLoad // lbzu IIC_LdStLoadUpd diff --git a/lib/Target/PowerPC/PPCSchedule440.td b/lib/Target/PowerPC/PPCSchedule440.td index 218fed248a3..04a43bc0325 100644 --- a/lib/Target/PowerPC/PPCSchedule440.td +++ b/lib/Target/PowerPC/PPCSchedule440.td @@ -121,6 +121,14 @@ def PPC440Itineraries : ProcessorItineraries< [2, 0, 0], [P440_GPR_Bypass, P440_GPR_Bypass, P440_GPR_Bypass]>, + InstrItinData, + InstrStage<1, [P440_IRACC, P440_LRACC]>, + InstrStage<1, [P440_IEXE1, P440_JEXE1]>, + InstrStage<1, [P440_IEXE2, P440_JEXE2]>, + InstrStage<1, [P440_IWB, P440_JWB]>], + [2, 0, 0, 0], + [P440_GPR_Bypass, + P440_GPR_Bypass, P440_GPR_Bypass, NoBypass]>, InstrItinData, InstrStage<1, [P440_IRACC, P440_LRACC]>, InstrStage<1, [P440_IEXE1, P440_JEXE1]>, diff --git a/lib/Target/PowerPC/PPCScheduleA2.td b/lib/Target/PowerPC/PPCScheduleA2.td index 14476963bad..21a357a2efc 100644 --- a/lib/Target/PowerPC/PPCScheduleA2.td +++ b/lib/Target/PowerPC/PPCScheduleA2.td @@ -29,6 +29,8 @@ def PPCA2Itineraries : ProcessorItineraries< [1, 0, 0]>, InstrItinData], [2, 0, 0]>, + InstrItinData], + [2, 0, 0, 0]>, InstrItinData], [2, 0, 0]>, InstrItinData], diff --git a/lib/Target/PowerPC/PPCScheduleE500mc.td b/lib/Target/PowerPC/PPCScheduleE500mc.td index dab89e3db35..36b8517dabf 100644 --- a/lib/Target/PowerPC/PPCScheduleE500mc.td +++ b/lib/Target/PowerPC/PPCScheduleE500mc.td @@ -54,6 +54,12 @@ def PPCE500mcItineraries : ProcessorItineraries< [4, 1, 1], // Latency = 1 [E500_GPR_Bypass, E500_GPR_Bypass, E500_GPR_Bypass]>, + InstrItinData, + InstrStage<1, [E500_SFX0, E500_SFX1]>], + [4, 1, 1, 1], // Latency = 1 + [E500_GPR_Bypass, + E500_GPR_Bypass, E500_GPR_Bypass, + E500_CR_Bypass]>, InstrItinData, InstrStage<1, [E500_SFX0, E500_SFX1]>], [5, 1, 1], // Latency = 1 or 2 diff --git a/lib/Target/PowerPC/PPCScheduleE5500.td b/lib/Target/PowerPC/PPCScheduleE5500.td index de097d9d8cf..7c2693ef0d4 100644 --- a/lib/Target/PowerPC/PPCScheduleE5500.td +++ b/lib/Target/PowerPC/PPCScheduleE5500.td @@ -58,6 +58,12 @@ def PPCE5500Itineraries : ProcessorItineraries< [5, 2, 2], // Latency = 1 [E5500_GPR_Bypass, E5500_GPR_Bypass, E5500_GPR_Bypass]>, + InstrItinData, + InstrStage<1, [E5500_SFX0, E5500_SFX1]>], + [5, 2, 2, 2], // Latency = 1 + [E5500_GPR_Bypass, + E5500_GPR_Bypass, E5500_GPR_Bypass, + E5500_CR_Bypass]>, InstrItinData, InstrStage<1, [E5500_SFX0, E5500_SFX1]>], [6, 2, 2], // Latency = 1 or 2 diff --git a/lib/Target/PowerPC/PPCScheduleP7.td b/lib/Target/PowerPC/PPCScheduleP7.td index 03693cbeada..635d154d10b 100644 --- a/lib/Target/PowerPC/PPCScheduleP7.td +++ b/lib/Target/PowerPC/PPCScheduleP7.td @@ -89,6 +89,10 @@ def P7Itineraries : ProcessorItineraries< P7_DU3, P7_DU4], 0>, InstrStage<1, [P7_FX1, P7_FX2]>], [1, 1, 1]>, + InstrItinData, + InstrStage<1, [P7_FX1, P7_FX2], 0>, + InstrStage<1, [P7_BRU]>], + [1, 1, 1, 1]>, InstrItinData, InstrStage<1, [P7_FX1, P7_FX2]>], diff --git a/lib/Target/PowerPC/PPCScheduleP8.td b/lib/Target/PowerPC/PPCScheduleP8.td index 07971809c87..020739baec3 100644 --- a/lib/Target/PowerPC/PPCScheduleP8.td +++ b/lib/Target/PowerPC/PPCScheduleP8.td @@ -66,6 +66,10 @@ def P8Itineraries : ProcessorItineraries< InstrStage<1, [P8_FXU1, P8_FXU2, P8_LU1, P8_LU2, P8_LSU1, P8_LSU2]>], [1, 1, 1]>, + InstrItinData, + InstrStage<1, [P8_FXU1, P8_FXU2], 0>, + InstrStage<1, [P8_BRU]>], + [1, 1, 1, 1]>, InstrItinData, InstrStage<1, [P8_FXU1, P8_FXU2]>], diff --git a/test/CodeGen/PowerPC/p8-isel-sched.ll b/test/CodeGen/PowerPC/p8-isel-sched.ll new file mode 100644 index 00000000000..034fe3c5fcb --- /dev/null +++ b/test/CodeGen/PowerPC/p8-isel-sched.ll @@ -0,0 +1,33 @@ +; RUN: llc -mcpu=pwr8 < %s | FileCheck %s +target datalayout = "E-m:e-i64:64-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +; Function Attrs: nounwind +define void @foo(i32* nocapture %r1, i32* nocapture %r2, i32* nocapture %r3, i32* nocapture %r4, i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d) #0 { +entry: + %tobool = icmp ne i32 %a, 0 + %cond = select i1 %tobool, i32 %b, i32 %c + store i32 %cond, i32* %r1, align 4 + %cond5 = select i1 %tobool, i32 %b, i32 %d + store i32 %cond5, i32* %r2, align 4 + %add = add nsw i32 %b, 1 + %sub = add nsw i32 %d, -2 + %cond10 = select i1 %tobool, i32 %add, i32 %sub + store i32 %cond10, i32* %r3, align 4 + %add13 = add nsw i32 %b, 3 + %sub15 = add nsw i32 %d, -5 + %cond17 = select i1 %tobool, i32 %add13, i32 %sub15 + store i32 %cond17, i32* %r4, align 4 + ret void +} + +; Make sure that we don't schedule all of the isels together, they should be +; intermixed with the adds because each isel starts a new dispatch group. +; CHECK-LABEL: @foo +; CHECK: isel +; CHECK: addi +; CHECK: isel +; CHECK: blr + +attributes #0 = { nounwind } + -- 2.34.1