mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-17 23:44:43 +00:00
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:
parent
e48155b25a
commit
63d66eed16
@ -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<bits<1> val> {
|
||||
int Value = val;
|
||||
}
|
||||
@ -81,22 +89,26 @@ def NoItinerary : InstrItinClass;
|
||||
// instruction itinerary class (name) to its itinerary data.
|
||||
//
|
||||
class InstrItinData<InstrItinClass Class, list<InstrStage> stages,
|
||||
list<int> operandcycles = []> {
|
||||
list<int> operandcycles = [],
|
||||
list<Bypass> bypasses = []> {
|
||||
InstrItinClass TheClass = Class;
|
||||
list<InstrStage> Stages = stages;
|
||||
list<int> OperandCycles = operandcycles;
|
||||
list<Bypass> Bypasses = bypasses;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Processor itineraries - These values represent the set of all itinerary
|
||||
// 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<Bypass> BP = bp;
|
||||
list<InstrItinData> IID = iid;
|
||||
}
|
||||
|
||||
// NoItineraries - A marker that can be used by processors without schedule
|
||||
// info.
|
||||
def NoItineraries : ProcessorItineraries<[], []>;
|
||||
def NoItineraries : ProcessorItineraries<[], [], []>;
|
||||
|
||||
|
@ -156,7 +156,7 @@ def IIC_VTBX4 : InstrItinClass;
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Processor instruction itineraries.
|
||||
|
||||
def GenericItineraries : ProcessorItineraries<[], []>;
|
||||
def GenericItineraries : ProcessorItineraries<[], [], []>;
|
||||
|
||||
include "ARMScheduleV6.td"
|
||||
include "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
|
||||
|
@ -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!
|
||||
//
|
||||
|
@ -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<IIC_iALUx , [InstrStage<1, [V6_Pipe]>]>,
|
||||
|
@ -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<s_ild , [InstrStage<3, [L0, L1]>]>,
|
||||
InstrItinData<s_fld , [InstrStage<4, [L0, L1]>]>,
|
||||
InstrItinData<s_ist , [InstrStage<0, [L0, L1]>]>,
|
||||
|
@ -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<LoadStore , [InstrStage<6, [ODD_UNIT]>]>,
|
||||
InstrItinData<BranchHints , [InstrStage<6, [ODD_UNIT]>]>,
|
||||
InstrItinData<BranchResolv, [InstrStage<4, [ODD_UNIT]>]>,
|
||||
|
@ -41,7 +41,7 @@ def IIPseudo : InstrItinClass;
|
||||
// MBlaze Generic instruction itineraries.
|
||||
//===----------------------------------------------------------------------===//
|
||||
def MBlazeGenericItineraries : ProcessorItineraries<
|
||||
[ALU, IMULDIV], [
|
||||
[ALU, IMULDIV], [], [
|
||||
InstrItinData<IIAlu , [InstrStage<1, [ALU]>]>,
|
||||
InstrItinData<IILoad , [InstrStage<3, [ALU]>]>,
|
||||
InstrItinData<IIStore , [InstrStage<1, [ALU]>]>,
|
||||
|
@ -40,7 +40,7 @@ def IIPseudo : InstrItinClass;
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Mips Generic instruction itineraries.
|
||||
//===----------------------------------------------------------------------===//
|
||||
def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [
|
||||
def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [
|
||||
InstrItinData<IIAlu , [InstrStage<1, [ALU]>]>,
|
||||
InstrItinData<IILoad , [InstrStage<3, [ALU]>]>,
|
||||
InstrItinData<IIStore , [InstrStage<1, [ALU]>]>,
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
|
||||
def G3Itineraries : ProcessorItineraries<
|
||||
[IU1, IU2, FPU1, BPU, SRU, SLU], [
|
||||
[IU1, IU2, FPU1, BPU, SRU, SLU], [], [
|
||||
InstrItinData<IntGeneral , [InstrStage<1, [IU1, IU2]>]>,
|
||||
InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2]>]>,
|
||||
InstrItinData<IntDivW , [InstrStage<19, [IU1]>]>,
|
||||
|
@ -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<IntGeneral , [InstrStage<1, [IU1, IU2]>]>,
|
||||
InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2]>]>,
|
||||
InstrItinData<IntDivW , [InstrStage<19, [IU1]>]>,
|
||||
|
@ -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<IntGeneral , [InstrStage<1, [IU1, IU2, IU3, IU4]>]>,
|
||||
InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2, IU3, IU4]>]>,
|
||||
InstrItinData<IntDivW , [InstrStage<23, [IU2]>]>,
|
||||
|
@ -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<IntGeneral , [InstrStage<2, [IU1, IU2]>]>,
|
||||
InstrItinData<IntCompare , [InstrStage<3, [IU1, IU2]>]>,
|
||||
InstrItinData<IntDivD , [InstrStage<68, [IU1]>]>,
|
||||
|
@ -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
|
||||
// operand cycle tables. Record itineraries for processors.
|
||||
@ -296,6 +314,16 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
|
||||
<< " = 1 << " << j << ";\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
|
||||
@ -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";
|
||||
|
@ -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<std::string, unsigned> &ItinClassesMap,
|
||||
std::vector<Record*> &ItinClassList,
|
||||
|
Loading…
x
Reference in New Issue
Block a user