[llvm-commits] [llvm] r79247 - in /llvm/trunk: include/llvm/Target/TargetInstrItineraries.h include/llvm/Target/TargetSchedule.td lib/CodeGen/ExactHazardRecognizer.cpp utils/TableGen/SubtargetEmitter.cpp utils/TableGen/SubtargetEmitter.h

David Goodwin david_goodwin at apple.com
Mon Aug 17 09:02:58 PDT 2009


Author: david_goodwin
Date: Mon Aug 17 11:02:57 2009
New Revision: 79247

URL: http://llvm.org/viewvc/llvm-project?rev=79247&view=rev
Log:
Extend the instruction itinerary model to include the ability to indicate the def and use cycle for each operand. This additional information is optional, so existing itineraries do not need to be changed.

Modified:
    llvm/trunk/include/llvm/Target/TargetInstrItineraries.h
    llvm/trunk/include/llvm/Target/TargetSchedule.td
    llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp
    llvm/trunk/utils/TableGen/SubtargetEmitter.cpp
    llvm/trunk/utils/TableGen/SubtargetEmitter.h

Modified: llvm/trunk/include/llvm/Target/TargetInstrItineraries.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrItineraries.h?rev=79247&r1=79246&r2=79247&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetInstrItineraries.h (original)
+++ llvm/trunk/include/llvm/Target/TargetInstrItineraries.h Mon Aug 17 11:02:57 2009
@@ -7,9 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file describes the structures used for instruction itineraries and
-// stages.  This is used by schedulers to determine instruction stages and
-// latencies.
+// This file describes the structures used for instruction
+// itineraries, stages, and operand reads/writes.  This is used by
+// schedulers to determine instruction stages and latencies.
 //
 //===----------------------------------------------------------------------===//
 
@@ -71,46 +71,50 @@
 
 
 //===----------------------------------------------------------------------===//
-/// Instruction itinerary - An itinerary represents a sequential series of steps
-/// required to complete an instruction.  Itineraries are represented as
-/// sequences of instruction stages.
+/// Instruction itinerary - An itinerary represents the scheduling
+/// information for an instruction. This includes a set of stages
+/// occupies by the instruction, and the pipeline cycle in which
+/// operands are read and written.
 ///
 struct InstrItinerary {
-  unsigned First;    ///< Index of first stage in itinerary
-  unsigned Last;     ///< Index of last + 1 stage in itinerary
+  unsigned FirstStage;         ///< Index of first stage in itinerary
+  unsigned LastStage;          ///< Index of last + 1 stage in itinerary
+  unsigned FirstOperandCycle;  ///< Index of first operand rd/wr
+  unsigned LastOperandCycle;   ///< Index of last + 1 operand rd/wr
 };
 
 
-
 //===----------------------------------------------------------------------===//
 /// Instruction itinerary Data - Itinerary data supplied by a subtarget to be
 /// used by a target.
 ///
 struct InstrItineraryData {
   const InstrStage     *Stages;         ///< Array of stages selected
+  const unsigned       *OperandCycles;  ///< Array of operand cycles selected
   const InstrItinerary *Itineratries;   ///< Array of itineraries selected
 
   /// Ctors.
   ///
-  InstrItineraryData() : Stages(0), Itineratries(0) {}
-  InstrItineraryData(const InstrStage *S, const InstrItinerary *I)
-    : Stages(S), Itineratries(I) {}
+  InstrItineraryData() : Stages(0), OperandCycles(0), Itineratries(0) {}
+  InstrItineraryData(const InstrStage *S, const unsigned *OS,
+                     const InstrItinerary *I)
+    : Stages(S), OperandCycles(OS), Itineratries(I) {}
   
   /// isEmpty - Returns true if there are no itineraries.
   ///
   bool isEmpty() const { return Itineratries == 0; }
   
-  /// begin - Return the first stage of the itinerary.
+  /// beginStage - Return the first stage of the itinerary.
   /// 
-  const InstrStage *begin(unsigned ItinClassIndx) const {
-    unsigned StageIdx = Itineratries[ItinClassIndx].First;
+  const InstrStage *beginStage(unsigned ItinClassIndx) const {
+    unsigned StageIdx = Itineratries[ItinClassIndx].FirstStage;
     return Stages + StageIdx;
   }
 
-  /// end - Return the last+1 stage of the itinerary.
+  /// endStage - Return the last+1 stage of the itinerary.
   /// 
-  const InstrStage *end(unsigned ItinClassIndx) const {
-    unsigned StageIdx = Itineratries[ItinClassIndx].Last;
+  const InstrStage *endStage(unsigned ItinClassIndx) const {
+    unsigned StageIdx = Itineratries[ItinClassIndx].LastStage;
     return Stages + StageIdx;
   }
 
@@ -129,8 +133,8 @@
     // first stage and that all outputs are produced at the end of the
     // latest completing last stage.
     unsigned Latency = 0, StartCycle = 0;
-    for (const InstrStage *IS = begin(ItinClassIndx), *E = end(ItinClassIndx);
-         IS != E; ++IS) {
+    for (const InstrStage *IS = beginStage(ItinClassIndx),
+           *E = endStage(ItinClassIndx); IS != E; ++IS) {
       Latency = std::max(Latency, StartCycle + IS->getCycles());
       StartCycle += IS->getNextCycles();
     }

Modified: llvm/trunk/include/llvm/Target/TargetSchedule.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSchedule.td?rev=79247&r1=79246&r2=79247&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetSchedule.td (original)
+++ llvm/trunk/include/llvm/Target/TargetSchedule.td Mon Aug 17 11:02:57 2009
@@ -62,9 +62,11 @@
 // Instruction itinerary data - These values provide a runtime map of an 
 // instruction itinerary class (name) to it's itinerary data.
 //
-class InstrItinData<InstrItinClass Class, list<InstrStage> stages> {
+class InstrItinData<InstrItinClass Class, list<InstrStage> stages,
+                    list<int> operandcycles = []> {
   InstrItinClass TheClass = Class;
   list<InstrStage> Stages = stages;
+  list<int> OperandCycles = operandcycles;
 }
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp?rev=79247&r1=79246&r2=79247&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp (original)
+++ llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp Mon Aug 17 11:02:57 2009
@@ -33,7 +33,8 @@
     for (unsigned idx = 0; ; ++idx) {
       // If the begin stage of an itinerary has 0 cycles and units,
       // then we have reached the end of the itineraries.
-      const InstrStage *IS = ItinData.begin(idx), *E = ItinData.end(idx);
+      const InstrStage *IS = ItinData.beginStage(idx);
+      const InstrStage *E = ItinData.endStage(idx);
       if ((IS->getCycles() == 0) && (IS->getUnits() == 0))
         break;
 
@@ -87,8 +88,8 @@
   // Use the itinerary for the underlying instruction to check for
   // free FU's in the scoreboard at the appropriate future cycles.
   unsigned idx = SU->getInstr()->getDesc().getSchedClass();
-  for (const InstrStage *IS = ItinData.begin(idx), *E = ItinData.end(idx);
-       IS != E; ++IS) {
+  for (const InstrStage *IS = ItinData.beginStage(idx),
+         *E = ItinData.endStage(idx); IS != E; ++IS) {
     // We must find one of the stage's units free for every cycle the
     // stage is occupied. FIXME it would be more accurate to find the
     // same unit free in all the cycles.
@@ -119,8 +120,8 @@
   // Use the itinerary for the underlying instruction to reserve FU's
   // in the scoreboard at the appropriate future cycles.
   unsigned idx = SU->getInstr()->getDesc().getSchedClass();
-  for (const InstrStage *IS = ItinData.begin(idx), *E = ItinData.end(idx);
-       IS != E; ++IS) {
+  for (const InstrStage *IS = ItinData.beginStage(idx), 
+         *E = ItinData.endStage(idx); IS != E; ++IS) {
     // We must reserve one of the stage's units for every cycle the
     // stage is occupied. FIXME it would be more accurate to reserve
     // the same unit free in all the cycles.

Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetEmitter.cpp?rev=79247&r1=79246&r2=79247&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp Mon Aug 17 11:02:57 2009
@@ -199,12 +199,13 @@
 }
 
 //
-// FormItineraryString - Compose a string containing the data initialization
-// for the specified itinerary.  N is the number of stages.
-//
-void SubtargetEmitter::FormItineraryString(Record *ItinData,
-                                           std::string &ItinString,
-                                           unsigned &NStages) {
+// FormItineraryStageString - Compose a string containing the stage
+// data initialization for the specified itinerary.  N is the number
+// of stages.
+//
+void SubtargetEmitter::FormItineraryStageString(Record *ItinData,
+                                                std::string &ItinString,
+                                                unsigned &NStages) {
   // Get states list
   const std::vector<Record*> &StageList =
     ItinData->getValueAsListOfDefs("Stages");
@@ -239,10 +240,32 @@
 }
 
 //
-// EmitStageData - Generate unique itinerary stages.  Record itineraries for 
-// processors.
+// FormItineraryOperandCycleString - Compose a string containing the
+// operand cycle initialization for the specified itinerary.  N is the
+// number of operands that has cycles specified.
+//
+void SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData,
+                         std::string &ItinString, unsigned &NOperandCycles) {
+  // Get operand cycle list
+  const std::vector<int64_t> &OperandCycleList =
+    ItinData->getValueAsListOfInts("OperandCycles");
+
+  // For each operand cycle
+  unsigned N = NOperandCycles = OperandCycleList.size();
+  for (unsigned i = 0; i < N;) {
+    // Next operand cycle
+    const int OCycle = OperandCycleList[i];
+  
+    ItinString += "  " + itostr(OCycle);
+    if (++i < N) ItinString += ", ";
+  }
+}
+
+//
+// EmitStageAndOperandCycleData - Generate unique itinerary stages and
+// operand cycle tables.  Record itineraries for processors.
 //
-void SubtargetEmitter::EmitStageData(raw_ostream &OS,
+void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
        unsigned NItinClasses,
        std::map<std::string, unsigned> &ItinClassesMap, 
        std::vector<std::vector<InstrItinerary> > &ProcList) {
@@ -254,12 +277,16 @@
   if (ProcItinList.size() < 2) return;
 
   // Begin stages table
-  OS << "static const llvm::InstrStage Stages[] = {\n"
-        "  { 0, 0, 0 }, // No itinerary\n";
+  std::string StageTable = "static const llvm::InstrStage Stages[] = {\n";
+  StageTable += "  { 0, 0, 0 }, // No itinerary\n";
         
-  unsigned StageCount = 1;
-  unsigned ItinEnum = 1;
-  std::map<std::string, unsigned> ItinMap;
+  // Begin operand cycle table
+  std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n";
+  OperandCycleTable += "  0, // No itinerary\n";
+        
+  unsigned StageCount = 1, OperandCycleCount = 1;
+  unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1;
+  std::map<std::string, unsigned> ItinStageMap, ItinOperandCycleMap;
   for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) {
     // Next record
     Record *Proc = ProcItinList[i];
@@ -283,29 +310,53 @@
       Record *ItinData = ItinDataList[j];
       
       // Get string and stage count
-      std::string ItinString;
+      std::string ItinStageString;
       unsigned NStages;
-      FormItineraryString(ItinData, ItinString, NStages);
+      FormItineraryStageString(ItinData, ItinStageString, NStages);
 
-      // Check to see if it already exists
-      unsigned Find = ItinMap[ItinString];
+      // Get string and operand cycle count
+      std::string ItinOperandCycleString;
+      unsigned NOperandCycles;
+      FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
+                                      NOperandCycles);
+
+      // Check to see if stage already exists and create if it doesn't
+      unsigned FindStage = 0;
+      if (NStages > 0) {
+        FindStage = ItinStageMap[ItinStageString];
+        if (FindStage == 0) {
+          // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // index
+          StageTable += ItinStageString + ", // " + itostr(ItinStageEnum) + "\n";
+          // Record Itin class number.
+          ItinStageMap[ItinStageString] = FindStage = StageCount;
+          StageCount += NStages;
+          ItinStageEnum++;
+        }
+      }
       
-      // If new itinerary
-      if (Find == 0) {
-        // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // index
-        OS << ItinString << ", // " << ItinEnum << "\n";
-        // Record Itin class number.
-        ItinMap[ItinString] = Find = StageCount;
-        StageCount += NStages;
-        ItinEnum++;
+      // Check to see if operand cycle already exists and create if it doesn't
+      unsigned FindOperandCycle = 0;
+      if (NOperandCycles > 0) {
+        FindOperandCycle = ItinOperandCycleMap[ItinOperandCycleString];
+        if (FindOperandCycle == 0) {
+          // Emit as  cycle, // index
+          OperandCycleTable += ItinOperandCycleString + ", // " + 
+            itostr(ItinOperandCycleEnum) + "\n";
+          // Record Itin class number.
+          ItinOperandCycleMap[ItinOperandCycleString] = 
+            FindOperandCycle = OperandCycleCount;
+          OperandCycleCount += NOperandCycles;
+          ItinOperandCycleEnum++;
+        }
       }
       
       // Set up itinerary as location and location + stage count
-      InstrItinerary Intinerary = { Find, Find + NStages };
+      InstrItinerary Intinerary = { FindStage, FindStage + NStages,
+                                    FindOperandCycle, FindOperandCycle + NOperandCycles};
 
       // Locate where to inject into processor itinerary table
       const std::string &Name = ItinData->getValueAsDef("TheClass")->getName();
-      Find = ItinClassesMap[Name];
+      unsigned Find = ItinClassesMap[Name];
       
       // Inject - empty slots will be 0, 0
       ItinList[Find] = Intinerary;
@@ -316,13 +367,21 @@
   }
   
   // Closing stage
-  OS << "  { 0, 0, 0 } // End itinerary\n";
-  // End stages table
-  OS << "};\n";
+  StageTable += "  { 0, 0, 0 } // End itinerary\n";
+  StageTable += "};\n";
+
+  // Closing operand cycles
+  OperandCycleTable += "  0 // End itinerary\n";
+  OperandCycleTable += "};\n";
+
+  // Emit tables.
+  OS << StageTable;
+  OS << OperandCycleTable;
   
-  // Emit size of table
+  // Emit size of tables
   OS<<"\nenum {\n";
-  OS<<"  StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage)\n";
+  OS<<"  StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage),\n";
+  OS<<"  OperandCyclesSize = sizeof(OperandCycles)/sizeof(unsigned)\n";
   OS<<"};\n";
 }
 
@@ -357,11 +416,15 @@
     for (unsigned j = 0, M = ItinList.size(); j < M;) {
       InstrItinerary &Intinerary = ItinList[j];
       
-      // Emit in the form of { first, last } // index
-      if (Intinerary.First == 0) {
-        OS << "  { 0, 0 }";
+      // Emit in the form of 
+      // { firstStage, lastStage, firstCycle, lastCycle } // index
+      if (Intinerary.FirstStage == 0) {
+        OS << "  { 0, 0, 0, 0 }";
       } else {
-        OS << "  { " << Intinerary.First << ", " << Intinerary.Last << " }";
+        OS << "  { " << Intinerary.FirstStage << ", " << 
+          Intinerary.LastStage << ", " << 
+          Intinerary.FirstOperandCycle << ", " << 
+          Intinerary.LastOperandCycle << " }";
       }
       
       // If more in list add comma
@@ -435,7 +498,7 @@
   
   if (HasItineraries) {
     // Emit the stage data
-    EmitStageData(OS, NItinClasses, ItinClassesMap, ProcList);
+    EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap, ProcList);
     // Emit the processor itinerary data
     EmitProcessorData(OS, ProcList);
     // Emit the processor lookup data
@@ -482,7 +545,7 @@
     OS << "\n"
        << "  InstrItinerary *Itinerary = (InstrItinerary *)"
        <<              "Features.getInfo(ProcItinKV, ProcItinKVSize);\n"
-       << "  InstrItins = InstrItineraryData(Stages, Itinerary);\n";
+       << "  InstrItins = InstrItineraryData(Stages, OperandCycles, Itinerary);\n";
   }
 
   OS << "  return Features.getCPU();\n"

Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetEmitter.h?rev=79247&r1=79246&r2=79247&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/SubtargetEmitter.h (original)
+++ llvm/trunk/utils/TableGen/SubtargetEmitter.h Mon Aug 17 11:02:57 2009
@@ -34,9 +34,11 @@
   void CPUKeyValues(raw_ostream &OS);
   unsigned CollectAllItinClasses(raw_ostream &OS,
                                std::map<std::string, unsigned> &ItinClassesMap);
-  void FormItineraryString(Record *ItinData, std::string &ItinString,
-                           unsigned &NStages);
-  void EmitStageData(raw_ostream &OS, unsigned NItinClasses,
+  void FormItineraryStageString(Record *ItinData, std::string &ItinString,
+                                unsigned &NStages);
+  void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString,
+                                       unsigned &NOperandCycles);
+  void EmitStageAndOperandCycleData(raw_ostream &OS, unsigned NItinClasses,
                      std::map<std::string, unsigned> &ItinClassesMap,
                      std::vector<std::vector<InstrItinerary> > &ProcList);
   void EmitProcessorData(raw_ostream &OS,





More information about the llvm-commits mailing list