Add support to model pipeline bypass / forwarding.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115005 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng
2010-09-28 23:50:49 +00:00
parent e48155b25a
commit 63d66eed16
15 changed files with 77 additions and 16 deletions

View File

@@ -22,6 +22,14 @@
// //
class FuncUnit; 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<bits<1> val> { class ReservationKind<bits<1> val> {
int Value = val; int Value = val;
} }
@@ -81,22 +89,26 @@ def NoItinerary : InstrItinClass;
// instruction itinerary class (name) to its itinerary data. // instruction itinerary class (name) to its itinerary data.
// //
class InstrItinData<InstrItinClass Class, list<InstrStage> stages, class InstrItinData<InstrItinClass Class, list<InstrStage> stages,
list<int> operandcycles = []> { list<int> operandcycles = [],
list<Bypass> bypasses = []> {
InstrItinClass TheClass = Class; InstrItinClass TheClass = Class;
list<InstrStage> Stages = stages; list<InstrStage> Stages = stages;
list<int> OperandCycles = operandcycles; list<int> OperandCycles = operandcycles;
list<Bypass> Bypasses = bypasses;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Processor itineraries - These values represent the set of all itinerary // Processor itineraries - These values represent the set of all itinerary
// classes for a given chip set. // classes for a given chip set.
// //
class ProcessorItineraries<list<FuncUnit> fu, list<InstrItinData> iid> { class ProcessorItineraries<list<FuncUnit> fu, list<Bypass> bp,
list<InstrItinData> iid> {
list<FuncUnit> FU = fu; list<FuncUnit> FU = fu;
list<Bypass> BP = bp;
list<InstrItinData> IID = iid; list<InstrItinData> IID = iid;
} }
// NoItineraries - A marker that can be used by processors without schedule // NoItineraries - A marker that can be used by processors without schedule
// info. // info.
def NoItineraries : ProcessorItineraries<[], []>; def NoItineraries : ProcessorItineraries<[], [], []>;

View File

@@ -156,7 +156,7 @@ def IIC_VTBX4 : InstrItinClass;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Processor instruction itineraries. // Processor instruction itineraries.
def GenericItineraries : ProcessorItineraries<[], []>; def GenericItineraries : ProcessorItineraries<[], [], []>;
include "ARMScheduleV6.td" include "ARMScheduleV6.td"
include "ARMScheduleA8.td" include "ARMScheduleA8.td"

View File

@@ -25,7 +25,8 @@ def A8_NLSPipe : FuncUnit; // NEON LS pipe
// Dual issue pipeline represented by A8_Pipe0 | A8_Pipe1 // Dual issue pipeline represented by A8_Pipe0 | A8_Pipe1
// //
def CortexA8Itineraries : ProcessorItineraries< 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 // Two fully-pipelined integer ALU pipelines
// //
// No operand cycles // No operand cycles

View File

@@ -26,7 +26,7 @@ def A9_DRegsN : FuncUnit; // FP register set, NEON side
// Dual issue pipeline represented by A9_Pipe0 | A9_Pipe1 // Dual issue pipeline represented by A9_Pipe0 | A9_Pipe1
// //
def CortexA9Itineraries : ProcessorItineraries< 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 // Two fully-pipelined integer ALU pipelines
// FIXME: There are no operand latencies for these instructions at all! // FIXME: There are no operand latencies for these instructions at all!
// //

View File

@@ -19,7 +19,7 @@ def V6_Pipe : FuncUnit; // pipeline
// Scheduling information derived from "ARM1176JZF-S Technical Reference Manual" // Scheduling information derived from "ARM1176JZF-S Technical Reference Manual"
// //
def ARMV6Itineraries : ProcessorItineraries< def ARMV6Itineraries : ProcessorItineraries<
[V6_Pipe], [ [V6_Pipe], [], [
// //
// No operand cycles // No operand cycles
InstrItinData<IIC_iALUx , [InstrStage<1, [V6_Pipe]>]>, InstrItinData<IIC_iALUx , [InstrStage<1, [V6_Pipe]>]>,

View File

@@ -54,7 +54,7 @@ def s_pseudo : InstrItinClass;
//modified some //modified some
def Alpha21264Itineraries : ProcessorItineraries< def Alpha21264Itineraries : ProcessorItineraries<
[L0, L1, FST0, FST1, U0, U1, FA, FM], [ [L0, L1, FST0, FST1, U0, U1, FA, FM], [], [
InstrItinData<s_ild , [InstrStage<3, [L0, L1]>]>, InstrItinData<s_ild , [InstrStage<3, [L0, L1]>]>,
InstrItinData<s_fld , [InstrStage<4, [L0, L1]>]>, InstrItinData<s_fld , [InstrStage<4, [L0, L1]>]>,
InstrItinData<s_ist , [InstrStage<0, [L0, L1]>]>, InstrItinData<s_ist , [InstrStage<0, [L0, L1]>]>,

View File

@@ -36,7 +36,7 @@ def RotateShift : InstrItinClass; // EVEN_UNIT
def ImmLoad : InstrItinClass; // EVEN_UNIT def ImmLoad : InstrItinClass; // EVEN_UNIT
/* Note: The itinerary for the Cell SPU is somewhat contrived... */ /* 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<LoadStore , [InstrStage<6, [ODD_UNIT]>]>, InstrItinData<LoadStore , [InstrStage<6, [ODD_UNIT]>]>,
InstrItinData<BranchHints , [InstrStage<6, [ODD_UNIT]>]>, InstrItinData<BranchHints , [InstrStage<6, [ODD_UNIT]>]>,
InstrItinData<BranchResolv, [InstrStage<4, [ODD_UNIT]>]>, InstrItinData<BranchResolv, [InstrStage<4, [ODD_UNIT]>]>,

View File

@@ -41,7 +41,7 @@ def IIPseudo : InstrItinClass;
// MBlaze Generic instruction itineraries. // MBlaze Generic instruction itineraries.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
def MBlazeGenericItineraries : ProcessorItineraries< def MBlazeGenericItineraries : ProcessorItineraries<
[ALU, IMULDIV], [ [ALU, IMULDIV], [], [
InstrItinData<IIAlu , [InstrStage<1, [ALU]>]>, InstrItinData<IIAlu , [InstrStage<1, [ALU]>]>,
InstrItinData<IILoad , [InstrStage<3, [ALU]>]>, InstrItinData<IILoad , [InstrStage<3, [ALU]>]>,
InstrItinData<IIStore , [InstrStage<1, [ALU]>]>, InstrItinData<IIStore , [InstrStage<1, [ALU]>]>,

View File

@@ -40,7 +40,7 @@ def IIPseudo : InstrItinClass;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Mips Generic instruction itineraries. // Mips Generic instruction itineraries.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [ def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [
InstrItinData<IIAlu , [InstrStage<1, [ALU]>]>, InstrItinData<IIAlu , [InstrStage<1, [ALU]>]>,
InstrItinData<IILoad , [InstrStage<3, [ALU]>]>, InstrItinData<IILoad , [InstrStage<3, [ALU]>]>,
InstrItinData<IIStore , [InstrStage<1, [ALU]>]>, InstrItinData<IIStore , [InstrStage<1, [ALU]>]>,

View File

@@ -13,7 +13,7 @@
def G3Itineraries : ProcessorItineraries< def G3Itineraries : ProcessorItineraries<
[IU1, IU2, FPU1, BPU, SRU, SLU], [ [IU1, IU2, FPU1, BPU, SRU, SLU], [], [
InstrItinData<IntGeneral , [InstrStage<1, [IU1, IU2]>]>, InstrItinData<IntGeneral , [InstrStage<1, [IU1, IU2]>]>,
InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2]>]>, InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2]>]>,
InstrItinData<IntDivW , [InstrStage<19, [IU1]>]>, InstrItinData<IntDivW , [InstrStage<19, [IU1]>]>,

View File

@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
def G4Itineraries : ProcessorItineraries< def G4Itineraries : ProcessorItineraries<
[IU1, IU2, SLU, SRU, BPU, FPU1, VIU1, VIU2, VPU, VFPU], [ [IU1, IU2, SLU, SRU, BPU, FPU1, VIU1, VIU2, VPU, VFPU], [], [
InstrItinData<IntGeneral , [InstrStage<1, [IU1, IU2]>]>, InstrItinData<IntGeneral , [InstrStage<1, [IU1, IU2]>]>,
InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2]>]>, InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2]>]>,
InstrItinData<IntDivW , [InstrStage<19, [IU1]>]>, InstrItinData<IntDivW , [InstrStage<19, [IU1]>]>,

View File

@@ -15,7 +15,7 @@ def IU3 : FuncUnit; // integer unit 3 (7450 simple)
def IU4 : FuncUnit; // integer unit 4 (7450 simple) def IU4 : FuncUnit; // integer unit 4 (7450 simple)
def G4PlusItineraries : ProcessorItineraries< 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<IntGeneral , [InstrStage<1, [IU1, IU2, IU3, IU4]>]>, InstrItinData<IntGeneral , [InstrStage<1, [IU1, IU2, IU3, IU4]>]>,
InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2, IU3, IU4]>]>, InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2, IU3, IU4]>]>,
InstrItinData<IntDivW , [InstrStage<23, [IU2]>]>, InstrItinData<IntDivW , [InstrStage<23, [IU2]>]>,

View File

@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
def G5Itineraries : ProcessorItineraries< def G5Itineraries : ProcessorItineraries<
[IU1, IU2, SLU, BPU, FPU1, FPU2, VFPU, VIU1, VIU2, VPU], [ [IU1, IU2, SLU, BPU, FPU1, FPU2, VFPU, VIU1, VIU2, VPU], [], [
InstrItinData<IntGeneral , [InstrStage<2, [IU1, IU2]>]>, InstrItinData<IntGeneral , [InstrStage<2, [IU1, IU2]>]>,
InstrItinData<IntCompare , [InstrStage<3, [IU1, IU2]>]>, InstrItinData<IntCompare , [InstrStage<3, [IU1, IU2]>]>,
InstrItinData<IntDivD , [InstrStage<68, [IU1]>]>, InstrItinData<IntDivD , [InstrStage<68, [IU1]>]>,

View File

@@ -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<Record*> &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 // EmitStageAndOperandCycleData - Generate unique itinerary stages and
// operand cycle tables. Record itineraries for processors. // operand cycle tables. Record itineraries for processors.
@@ -296,6 +314,16 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
<< " = 1 << " << j << ";\n"; << " = 1 << " << j << ";\n";
OS << "}\n"; OS << "}\n";
std::vector<Record*> 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 // Begin stages table
@@ -305,6 +333,10 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
// Begin operand cycle table // Begin operand cycle table
std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n"; std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n";
OperandCycleTable += " 0, // No itinerary\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 StageCount = 1, OperandCycleCount = 1;
unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1; unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1;
@@ -342,6 +374,10 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
FormItineraryOperandCycleString(ItinData, ItinOperandCycleString, FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
NOperandCycles); NOperandCycles);
std::string ItinBypassString;
FormItineraryBypassString(Name, ItinData, ItinBypassString,
NOperandCycles);
// Check to see if stage already exists and create if it doesn't // Check to see if stage already exists and create if it doesn't
unsigned FindStage = 0; unsigned FindStage = 0;
if (NStages > 0) { if (NStages > 0) {
@@ -367,6 +403,11 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
// Record Itin class number. // Record Itin class number.
ItinOperandCycleMap[ItinOperandCycleString] = ItinOperandCycleMap[ItinOperandCycleString] =
FindOperandCycle = OperandCycleCount; FindOperandCycle = OperandCycleCount;
// Emit as bypass, // index
BypassTable += ItinBypassString + ", // " +
itostr(ItinOperandCycleEnum) + "\n";
OperandCycleCount += NOperandCycles; OperandCycleCount += NOperandCycles;
ItinOperandCycleEnum++; ItinOperandCycleEnum++;
} }
@@ -389,7 +430,7 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
// Add process itinerary to list // Add process itinerary to list
ProcList.push_back(ItinList); ProcList.push_back(ItinList);
} }
// Closing stage // Closing stage
StageTable += " { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n"; StageTable += " { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n";
StageTable += "};\n"; StageTable += "};\n";
@@ -398,9 +439,13 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
OperandCycleTable += " 0 // End itinerary\n"; OperandCycleTable += " 0 // End itinerary\n";
OperandCycleTable += "};\n"; OperandCycleTable += "};\n";
BypassTable += " 0 // End itinerary\n";
BypassTable += "};\n";
// Emit tables. // Emit tables.
OS << StageTable; OS << StageTable;
OS << OperandCycleTable; OS << OperandCycleTable;
OS << BypassTable;
// Emit size of tables // Emit size of tables
OS<<"\nenum {\n"; OS<<"\nenum {\n";

View File

@@ -40,6 +40,9 @@ class SubtargetEmitter : public TableGenBackend {
unsigned &NStages); unsigned &NStages);
void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString, void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString,
unsigned &NOperandCycles); unsigned &NOperandCycles);
void FormItineraryBypassString(const std::string &Names,
Record *ItinData,
std::string &ItinString, unsigned NOperandCycles);
void EmitStageAndOperandCycleData(raw_ostream &OS, unsigned NItinClasses, void EmitStageAndOperandCycleData(raw_ostream &OS, unsigned NItinClasses,
std::map<std::string, unsigned> &ItinClassesMap, std::map<std::string, unsigned> &ItinClassesMap,
std::vector<Record*> &ItinClassList, std::vector<Record*> &ItinClassList,