From: Evan Cheng Date: Tue, 28 Sep 2010 23:50:49 +0000 (+0000) Subject: Add support to model pipeline bypass / forwarding. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=63d66eed16a6ee4e838f2f7a4c8299def0722c20;p=oota-llvm.git Add support to model pipeline bypass / forwarding. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115005 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td index d771cdd4de8..c55ebd84003 100644 --- a/include/llvm/Target/TargetSchedule.td +++ b/include/llvm/Target/TargetSchedule.td @@ -22,6 +22,14 @@ // class FuncUnit; +//===----------------------------------------------------------------------===// +// Pipeline bypass / forwarding - These values specifies the symbolic names of +// pipeline bypasses which can be used to forward results of instructions +// that are forwarded to uses. +class Bypass; + +def NoBypass : Bypass; + class ReservationKind val> { int Value = val; } @@ -81,22 +89,26 @@ def NoItinerary : InstrItinClass; // instruction itinerary class (name) to its itinerary data. // class InstrItinData stages, - list operandcycles = []> { + list operandcycles = [], + list bypasses = []> { InstrItinClass TheClass = Class; list Stages = stages; list OperandCycles = operandcycles; + list Bypasses = bypasses; } //===----------------------------------------------------------------------===// // Processor itineraries - These values represent the set of all itinerary // classes for a given chip set. // -class ProcessorItineraries fu, list iid> { +class ProcessorItineraries fu, list bp, + list iid> { list FU = fu; + list BP = bp; list IID = iid; } // NoItineraries - A marker that can be used by processors without schedule // info. -def NoItineraries : ProcessorItineraries<[], []>; +def NoItineraries : ProcessorItineraries<[], [], []>; diff --git a/lib/Target/ARM/ARMSchedule.td b/lib/Target/ARM/ARMSchedule.td index c64c4392a3b..96c9fa0d0b9 100644 --- a/lib/Target/ARM/ARMSchedule.td +++ b/lib/Target/ARM/ARMSchedule.td @@ -156,7 +156,7 @@ def IIC_VTBX4 : InstrItinClass; //===----------------------------------------------------------------------===// // Processor instruction itineraries. -def GenericItineraries : ProcessorItineraries<[], []>; +def GenericItineraries : ProcessorItineraries<[], [], []>; include "ARMScheduleV6.td" include "ARMScheduleA8.td" diff --git a/lib/Target/ARM/ARMScheduleA8.td b/lib/Target/ARM/ARMScheduleA8.td index 864ada01629..6bec63734d0 100644 --- a/lib/Target/ARM/ARMScheduleA8.td +++ b/lib/Target/ARM/ARMScheduleA8.td @@ -25,7 +25,8 @@ def A8_NLSPipe : FuncUnit; // NEON LS pipe // Dual issue pipeline represented by A8_Pipe0 | A8_Pipe1 // def CortexA8Itineraries : ProcessorItineraries< - [A8_Issue, A8_Pipe0, A8_Pipe1, A8_LdSt0, A8_LdSt1, A8_NPipe, A8_NLSPipe], [ + [A8_Issue, A8_Pipe0, A8_Pipe1, A8_LdSt0, A8_LdSt1, A8_NPipe, A8_NLSPipe], + [], [ // Two fully-pipelined integer ALU pipelines // // No operand cycles diff --git a/lib/Target/ARM/ARMScheduleA9.td b/lib/Target/ARM/ARMScheduleA9.td index 165ecbcbac4..1deb846f2d1 100644 --- a/lib/Target/ARM/ARMScheduleA9.td +++ b/lib/Target/ARM/ARMScheduleA9.td @@ -26,7 +26,7 @@ def A9_DRegsN : FuncUnit; // FP register set, NEON side // Dual issue pipeline represented by A9_Pipe0 | A9_Pipe1 // def CortexA9Itineraries : ProcessorItineraries< - [A9_NPipe, A9_DRegsN, A9_DRegsVFP, A9_LSPipe, A9_Pipe0, A9_Pipe1], [ + [A9_NPipe, A9_DRegsN, A9_DRegsVFP, A9_LSPipe, A9_Pipe0, A9_Pipe1], [], [ // Two fully-pipelined integer ALU pipelines // FIXME: There are no operand latencies for these instructions at all! // diff --git a/lib/Target/ARM/ARMScheduleV6.td b/lib/Target/ARM/ARMScheduleV6.td index 866e2e1e237..2e8a6a34055 100644 --- a/lib/Target/ARM/ARMScheduleV6.td +++ b/lib/Target/ARM/ARMScheduleV6.td @@ -19,7 +19,7 @@ def V6_Pipe : FuncUnit; // pipeline // Scheduling information derived from "ARM1176JZF-S Technical Reference Manual" // def ARMV6Itineraries : ProcessorItineraries< - [V6_Pipe], [ + [V6_Pipe], [], [ // // No operand cycles InstrItinData]>, diff --git a/lib/Target/Alpha/AlphaSchedule.td b/lib/Target/Alpha/AlphaSchedule.td index 3723a07e877..3703dd4fa9f 100644 --- a/lib/Target/Alpha/AlphaSchedule.td +++ b/lib/Target/Alpha/AlphaSchedule.td @@ -54,7 +54,7 @@ def s_pseudo : InstrItinClass; //modified some def Alpha21264Itineraries : ProcessorItineraries< - [L0, L1, FST0, FST1, U0, U1, FA, FM], [ + [L0, L1, FST0, FST1, U0, U1, FA, FM], [], [ InstrItinData]>, InstrItinData]>, InstrItinData]>, diff --git a/lib/Target/CellSPU/SPUSchedule.td b/lib/Target/CellSPU/SPUSchedule.td index a0b581f1632..f4d082c8b3b 100644 --- a/lib/Target/CellSPU/SPUSchedule.td +++ b/lib/Target/CellSPU/SPUSchedule.td @@ -36,7 +36,7 @@ def RotateShift : InstrItinClass; // EVEN_UNIT def ImmLoad : InstrItinClass; // EVEN_UNIT /* Note: The itinerary for the Cell SPU is somewhat contrived... */ -def SPUItineraries : ProcessorItineraries<[ODD_UNIT, EVEN_UNIT], [ +def SPUItineraries : ProcessorItineraries<[ODD_UNIT, EVEN_UNIT], [], [ InstrItinData]>, InstrItinData]>, InstrItinData]>, diff --git a/lib/Target/MBlaze/MBlazeSchedule.td b/lib/Target/MBlaze/MBlazeSchedule.td index 4a65542a447..a9bf27d5c09 100644 --- a/lib/Target/MBlaze/MBlazeSchedule.td +++ b/lib/Target/MBlaze/MBlazeSchedule.td @@ -41,7 +41,7 @@ def IIPseudo : InstrItinClass; // MBlaze Generic instruction itineraries. //===----------------------------------------------------------------------===// def MBlazeGenericItineraries : ProcessorItineraries< - [ALU, IMULDIV], [ + [ALU, IMULDIV], [], [ InstrItinData]>, InstrItinData]>, InstrItinData]>, diff --git a/lib/Target/Mips/MipsSchedule.td b/lib/Target/Mips/MipsSchedule.td index 055ff323721..49ca5d19c9c 100644 --- a/lib/Target/Mips/MipsSchedule.td +++ b/lib/Target/Mips/MipsSchedule.td @@ -40,7 +40,7 @@ def IIPseudo : InstrItinClass; //===----------------------------------------------------------------------===// // Mips Generic instruction itineraries. //===----------------------------------------------------------------------===// -def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [ +def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [ InstrItinData]>, InstrItinData]>, InstrItinData]>, diff --git a/lib/Target/PowerPC/PPCScheduleG3.td b/lib/Target/PowerPC/PPCScheduleG3.td index 73447631b2a..ad4da1fe224 100644 --- a/lib/Target/PowerPC/PPCScheduleG3.td +++ b/lib/Target/PowerPC/PPCScheduleG3.td @@ -13,7 +13,7 @@ def G3Itineraries : ProcessorItineraries< - [IU1, IU2, FPU1, BPU, SRU, SLU], [ + [IU1, IU2, FPU1, BPU, SRU, SLU], [], [ InstrItinData]>, InstrItinData]>, InstrItinData]>, diff --git a/lib/Target/PowerPC/PPCScheduleG4.td b/lib/Target/PowerPC/PPCScheduleG4.td index 7efc693fa8c..03c3b29cc10 100644 --- a/lib/Target/PowerPC/PPCScheduleG4.td +++ b/lib/Target/PowerPC/PPCScheduleG4.td @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// def G4Itineraries : ProcessorItineraries< - [IU1, IU2, SLU, SRU, BPU, FPU1, VIU1, VIU2, VPU, VFPU], [ + [IU1, IU2, SLU, SRU, BPU, FPU1, VIU1, VIU2, VPU, VFPU], [], [ InstrItinData]>, InstrItinData]>, InstrItinData]>, diff --git a/lib/Target/PowerPC/PPCScheduleG4Plus.td b/lib/Target/PowerPC/PPCScheduleG4Plus.td index 15056c0cfe4..00cac3c7cab 100644 --- a/lib/Target/PowerPC/PPCScheduleG4Plus.td +++ b/lib/Target/PowerPC/PPCScheduleG4Plus.td @@ -15,7 +15,7 @@ def IU3 : FuncUnit; // integer unit 3 (7450 simple) def IU4 : FuncUnit; // integer unit 4 (7450 simple) def G4PlusItineraries : ProcessorItineraries< - [IU1, IU2, IU3, IU4, BPU, SLU, FPU1, VFPU, VIU1, VIU2, VPU], [ + [IU1, IU2, IU3, IU4, BPU, SLU, FPU1, VFPU, VIU1, VIU2, VPU], [], [ InstrItinData]>, InstrItinData]>, InstrItinData]>, diff --git a/lib/Target/PowerPC/PPCScheduleG5.td b/lib/Target/PowerPC/PPCScheduleG5.td index 2dffc48b238..1671f22b30a 100644 --- a/lib/Target/PowerPC/PPCScheduleG5.td +++ b/lib/Target/PowerPC/PPCScheduleG5.td @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// def G5Itineraries : ProcessorItineraries< - [IU1, IU2, SLU, BPU, FPU1, FPU2, VFPU, VIU1, VIU2, VPU], [ + [IU1, IU2, SLU, BPU, FPU1, FPU2, VFPU, VIU1, VIU2, VPU], [], [ InstrItinData]>, InstrItinData]>, InstrItinData]>, diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp index 21870b1f5b1..03a813d939d 100644 --- a/utils/TableGen/SubtargetEmitter.cpp +++ b/utils/TableGen/SubtargetEmitter.cpp @@ -262,6 +262,24 @@ void SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData, } } +void SubtargetEmitter::FormItineraryBypassString(const std::string &Name, + Record *ItinData, + std::string &ItinString, + unsigned NOperandCycles) { + const std::vector &BypassList = + ItinData->getValueAsListOfDefs("Bypasses"); + unsigned N = BypassList.size(); + for (unsigned i = 0; i < N;) { + ItinString += Name + "Bypass::" + BypassList[i]->getName(); + if (++i < N) ItinString += ", "; + } + + for (; N < NOperandCycles;) { + ItinString += " 0"; + if (++N < NOperandCycles) ItinString += ", "; + } +} + // // EmitStageAndOperandCycleData - Generate unique itinerary stages and // operand cycle tables. Record itineraries for processors. @@ -296,6 +314,16 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, << " = 1 << " << j << ";\n"; OS << "}\n"; + + std::vector BPs = Proc->getValueAsListOfDefs("BP"); + OS << "\n// Pipeline bypasses for itineraries \"" << Name << "\"\n" + << "namespace " << Name << "Bypass {\n"; + + for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j) + OS << " const unsigned " << BPs[j]->getName() + << " = 1 << " << j << ";\n"; + + OS << "}\n"; } // Begin stages table @@ -305,6 +333,10 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, // Begin operand cycle table std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n"; OperandCycleTable += " 0, // No itinerary\n"; + + // Begin pipeline bypass table + std::string BypassTable = "static const unsigned Bypasses[] = {\n"; + BypassTable += " 0, // No itinerary\n"; unsigned StageCount = 1, OperandCycleCount = 1; unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1; @@ -342,6 +374,10 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, FormItineraryOperandCycleString(ItinData, ItinOperandCycleString, NOperandCycles); + std::string ItinBypassString; + FormItineraryBypassString(Name, ItinData, ItinBypassString, + NOperandCycles); + // Check to see if stage already exists and create if it doesn't unsigned FindStage = 0; if (NStages > 0) { @@ -367,6 +403,11 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, // Record Itin class number. ItinOperandCycleMap[ItinOperandCycleString] = FindOperandCycle = OperandCycleCount; + + // Emit as bypass, // index + BypassTable += ItinBypassString + ", // " + + itostr(ItinOperandCycleEnum) + "\n"; + OperandCycleCount += NOperandCycles; ItinOperandCycleEnum++; } @@ -389,7 +430,7 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, // Add process itinerary to list ProcList.push_back(ItinList); } - + // Closing stage StageTable += " { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n"; StageTable += "};\n"; @@ -398,9 +439,13 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, OperandCycleTable += " 0 // End itinerary\n"; OperandCycleTable += "};\n"; + BypassTable += " 0 // End itinerary\n"; + BypassTable += "};\n"; + // Emit tables. OS << StageTable; OS << OperandCycleTable; + OS << BypassTable; // Emit size of tables OS<<"\nenum {\n"; diff --git a/utils/TableGen/SubtargetEmitter.h b/utils/TableGen/SubtargetEmitter.h index 4edf6485697..3abec3b2409 100644 --- a/utils/TableGen/SubtargetEmitter.h +++ b/utils/TableGen/SubtargetEmitter.h @@ -40,6 +40,9 @@ class SubtargetEmitter : public TableGenBackend { unsigned &NStages); void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString, unsigned &NOperandCycles); + void FormItineraryBypassString(const std::string &Names, + Record *ItinData, + std::string &ItinString, unsigned NOperandCycles); void EmitStageAndOperandCycleData(raw_ostream &OS, unsigned NItinClasses, std::map &ItinClassesMap, std::vector &ItinClassList,