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

Anton Korobeynikov asl at math.spbu.ru
Wed Apr 7 11:19:32 PDT 2010


Author: asl
Date: Wed Apr  7 13:19:32 2010
New Revision: 100645

URL: http://llvm.org/viewvc/llvm-project?rev=100645&view=rev
Log:
Initial support for different kinds of FU reservation.

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

Modified: llvm/trunk/include/llvm/Target/TargetInstrItineraries.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrItineraries.h?rev=100645&r1=100644&r2=100645&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetInstrItineraries.h (original)
+++ llvm/trunk/include/llvm/Target/TargetInstrItineraries.h Wed Apr  7 13:19:32 2010
@@ -47,10 +47,24 @@
 ///      indicate that the instruction requires multiple stages at the
 ///      same time.
 ///
+/// FU reservation can be of two different kinds:
+///  - FUs which instruction actually requires
+///  - FUs which instruction just reserves. Reserved unit is not available for
+///    execution of other instruction. However, several instructions can reserve
+///    the same unit several times.
+/// Such two types of units reservation is used to model instruction domain
+/// change stalls, FUs using the same resource (e.g. same register file), etc.
+
 struct InstrStage {
+  enum ReservationKinds {
+    Required = 0,
+    Reserved = 1
+  };
+
   unsigned Cycles_;  ///< Length of stage in machine cycles
   unsigned Units_;   ///< Choice of functional units
-  int NextCycles_;   ///< Number of machine cycles to next stage 
+  int NextCycles_;   ///< Number of machine cycles to next stage
+  ReservationKinds Kind_; ///< Kind of the FU reservation
 
   /// getCycles - returns the number of cycles the stage is occupied
   unsigned getCycles() const {
@@ -62,6 +76,10 @@
     return Units_;
   }
 
+  ReservationKinds getReservationKind() const {
+    return Kind_;
+  }
+
   /// getNextCycles - returns the number of cycles from the start of
   /// this stage to the start of the next stage in the itinerary
   unsigned getNextCycles() const {

Modified: llvm/trunk/include/llvm/Target/TargetSchedule.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSchedule.td?rev=100645&r1=100644&r2=100645&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetSchedule.td (original)
+++ llvm/trunk/include/llvm/Target/TargetSchedule.td Wed Apr  7 13:19:32 2010
@@ -22,6 +22,13 @@
 //  
 class FuncUnit;
 
+class ReservationKind<bits<1> val> {
+  bits<1> Value = val;
+}
+
+def Required : ReservationKind<0>;
+def Reserved : ReservationKind<1>;
+
 //===----------------------------------------------------------------------===//
 // Instruction stage - These values represent a non-pipelined step in
 // the execution of an instruction.  Cycles represents the number of
@@ -36,10 +43,12 @@
 //   InstrStage<1, [FU_x, FU_y]>     - TimeInc defaults to Cycles
 //   InstrStage<1, [FU_x, FU_y], 0>  - TimeInc explicit
 //
-class InstrStage<int cycles, list<FuncUnit> units, int timeinc = -1> {
+class InstrStage<int cycles, list<FuncUnit> units,
+                 int timeinc = -1, ReservationKind kind = Required> {
   int Cycles          = cycles;       // length of stage in machine cycles
   list<FuncUnit> Units = units;       // choice of functional units
   int TimeInc         = timeinc;      // cycles till start of next stage
+  int Kind            = kind.Value;   // kind of FU reservation
 }
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp?rev=100645&r1=100644&r2=100645&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp (original)
+++ llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp Wed Apr  7 13:19:32 2010
@@ -45,14 +45,16 @@
     }
   }
 
-  Scoreboard.reset(ScoreboardDepth);
+  ReservedScoreboard.reset(ScoreboardDepth);
+  RequiredScoreboard.reset(ScoreboardDepth);
 
   DEBUG(dbgs() << "Using exact hazard recognizer: ScoreboardDepth = " 
                << ScoreboardDepth << '\n');
 }
 
 void ExactHazardRecognizer::Reset() {
-  Scoreboard.reset();
+  RequiredScoreboard.reset();
+  ReservedScoreboard.reset();
 }
 
 void ExactHazardRecognizer::ScoreBoard::dump() const {
@@ -86,10 +88,23 @@
     // stage is occupied. FIXME it would be more accurate to find the
     // same unit free in all the cycles.
     for (unsigned int i = 0; i < IS->getCycles(); ++i) {
-      assert(((cycle + i) < Scoreboard.getDepth()) &&
+      assert(((cycle + i) < RequiredScoreboard.getDepth()) &&
              "Scoreboard depth exceeded!");
 
-      unsigned freeUnits = IS->getUnits() & ~Scoreboard[cycle + i];
+      unsigned freeUnits = IS->getUnits();
+      switch (IS->getReservationKind()) {
+      default:
+       assert(0 && "Invalid FU reservation");
+      case InstrStage::Required:
+        // Required FUs conflict with both reserved and required ones
+        freeUnits &= ~ReservedScoreboard[cycle + i];
+        // FALLTHROUGH
+      case InstrStage::Reserved:
+        // Reserved FUs can conflict only with required ones.
+        freeUnits &= ~RequiredScoreboard[cycle + i];
+        break;
+      }
+
       if (!freeUnits) {
         DEBUG(dbgs() << "*** Hazard in cycle " << (cycle + i) << ", ");
         DEBUG(dbgs() << "SU(" << SU->NodeNum << "): ");
@@ -114,16 +129,28 @@
   // 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.beginStage(idx), 
+  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.
     for (unsigned int i = 0; i < IS->getCycles(); ++i) {
-      assert(((cycle + i) < Scoreboard.getDepth()) &&
+      assert(((cycle + i) < RequiredScoreboard.getDepth()) &&
              "Scoreboard depth exceeded!");
 
-      unsigned freeUnits = IS->getUnits() & ~Scoreboard[cycle + i];
+      unsigned freeUnits = IS->getUnits();
+      switch (IS->getReservationKind()) {
+      default:
+       assert(0 && "Invalid FU reservation");
+      case InstrStage::Required:
+        // Required FUs conflict with both reserved and required ones
+        freeUnits &= ~ReservedScoreboard[cycle + i];
+        // FALLTHROUGH
+      case InstrStage::Reserved:
+        // Reserved FUs can conflict only with required ones.
+        freeUnits &= ~RequiredScoreboard[cycle + i];
+        break;
+      }
 
       // reduce to a single unit
       unsigned freeUnit = 0;
@@ -133,17 +160,21 @@
       } while (freeUnits);
 
       assert(freeUnit && "No function unit available!");
-      Scoreboard[cycle + i] |= freeUnit;
+      if (IS->getReservationKind() == InstrStage::Required)
+        RequiredScoreboard[cycle + i] |= freeUnit;
+      else
+        ReservedScoreboard[cycle + i] |= freeUnit;
     }
 
     // Advance the cycle to the next stage.
     cycle += IS->getNextCycles();
   }
 
-  DEBUG(Scoreboard.dump());
+  DEBUG(ReservedScoreboard.dump());
+  DEBUG(RequiredScoreboard.dump());
 }
 
 void ExactHazardRecognizer::AdvanceCycle() {
-  Scoreboard[0] = 0;
-  Scoreboard.advance();
+  ReservedScoreboard[0] = 0; ReservedScoreboard.advance();
+  RequiredScoreboard[0] = 0; RequiredScoreboard.advance();
 }

Modified: llvm/trunk/lib/CodeGen/ExactHazardRecognizer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ExactHazardRecognizer.h?rev=100645&r1=100644&r2=100645&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/ExactHazardRecognizer.h (original)
+++ llvm/trunk/lib/CodeGen/ExactHazardRecognizer.h Wed Apr  7 13:19:32 2010
@@ -70,7 +70,8 @@
     // Itinerary data for the target.
     const InstrItineraryData &ItinData;
 
-    ScoreBoard Scoreboard;
+    ScoreBoard ReservedScoreboard;
+    ScoreBoard RequiredScoreboard;
 
   public:
     ExactHazardRecognizer(const InstrItineraryData &ItinData);

Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetEmitter.cpp?rev=100645&r1=100644&r2=100645&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp Wed Apr  7 13:19:32 2010
@@ -216,7 +216,7 @@
     // Next stage
     const Record *Stage = StageList[i];
   
-    // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc }
+    // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc, kind }
     int Cycles = Stage->getValueAsInt("Cycles");
     ItinString += "  { " + itostr(Cycles) + ", ";
     
@@ -233,6 +233,9 @@
     int TimeInc = Stage->getValueAsInt("TimeInc");
     ItinString += ", " + itostr(TimeInc);
 
+    int Kind = Stage->getValueAsInt("Kind");
+    ItinString += ", (llvm::InstrStage::ReservationKinds)" + itostr(Kind);
+
     // Close off stage
     ItinString += " }";
     if (++i < N) ItinString += ", ";
@@ -278,7 +281,7 @@
 
   // Begin stages table
   std::string StageTable = "static const llvm::InstrStage Stages[] = {\n";
-  StageTable += "  { 0, 0, 0 }, // No itinerary\n";
+  StageTable += "  { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n";
         
   // Begin operand cycle table
   std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n";
@@ -367,7 +370,7 @@
   }
   
   // Closing stage
-  StageTable += "  { 0, 0, 0 } // End itinerary\n";
+  StageTable += "  { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n";
   StageTable += "};\n";
 
   // Closing operand cycles





More information about the llvm-commits mailing list