Don't advance the hazard recognizer when there are no hazards and no instructions
authorChris Lattner <sabre@nondot.org>
Sun, 12 Mar 2006 09:01:41 +0000 (09:01 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 12 Mar 2006 09:01:41 +0000 (09:01 +0000)
to be emitted.

Don't add one to the latency of a completed instruction if the latency of the
op is 0.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26718 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp

index f3d97fe18c5521353417be159eaee37ed3c1387d..d09622fd6bfcc70940d08dc5b3a3e053b3594126 100644 (file)
@@ -357,6 +357,8 @@ void ScheduleDAGList::BuildSchedUnits() {
     // Remove MainNode from FlaggedNodes again.
     SU->FlaggedNodes.pop_back();
   }
+  
+  return;
   DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
         SUnits[su].dumpAll(&DAG));
 }
@@ -550,14 +552,14 @@ void ScheduleDAGList::ReleaseSucc(SUnit *SuccSU, bool isChain) {
     unsigned AvailableCycle = 0;
     for (std::set<std::pair<SUnit*, bool> >::iterator I = SuccSU->Preds.begin(),
          E = SuccSU->Preds.end(); I != E; ++I) {
-      // If this is a token edge, we don't need to wait for the full latency of
-      // the preceeding instruction (e.g. a long-latency load) unless there is
-      // also some other data dependence.
+      // If this is a token edge, we don't need to wait for the latency of the
+      // preceeding instruction (e.g. a long-latency load) unless there is also
+      // some other data dependence.
       unsigned PredDoneCycle = I->first->Cycle;
       if (!I->second)
         PredDoneCycle += I->first->Latency;
-      else
-        PredDoneCycle += 1;  
+      else if (I->first->Latency)
+        PredDoneCycle += 1;
 
       AvailableCycle = std::max(AvailableCycle, PredDoneCycle);
     }
@@ -608,7 +610,7 @@ void ScheduleDAGList::ListScheduleTopDown() {
   while (!AvailableQueue->empty() || !PendingQueue.empty()) {
     // Check to see if any of the pending instructions are ready to issue.  If
     // so, add them to the available queue.
-    for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i)
+    for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) {
       if (PendingQueue[i].first == CurCycle) {
         AvailableQueue->push(PendingQueue[i].second);
         PendingQueue[i].second->isAvailable = true;
@@ -618,54 +620,67 @@ void ScheduleDAGList::ListScheduleTopDown() {
       } else {
         assert(PendingQueue[i].first > CurCycle && "Negative latency?");
       }
+    }
     
-    SUnit *FoundNode = 0;
+    // If there are no instructions available, don't try to issue anything, and
+    // don't advance the hazard recognizer.
+    if (AvailableQueue->empty()) {
+      ++CurCycle;
+      continue;
+    }
 
+    SUnit *FoundSUnit = 0;
+    SDNode *FoundNode = 0;
+    
     bool HasNoopHazards = false;
     while (!AvailableQueue->empty()) {
-      SUnit *CurNode = AvailableQueue->pop();
+      SUnit *CurSUnit = AvailableQueue->pop();
       
       // Get the node represented by this SUnit.
-      SDNode *N = CurNode->Node;
+      FoundNode = CurSUnit->Node;
+      
       // If this is a pseudo op, like copyfromreg, look to see if there is a
       // real target node flagged to it.  If so, use the target node.
-      for (unsigned i = 0, e = CurNode->FlaggedNodes.size(); 
-           N->getOpcode() < ISD::BUILTIN_OP_END && i != e; ++i)
-        N = CurNode->FlaggedNodes[i];
+      for (unsigned i = 0, e = CurSUnit->FlaggedNodes.size(); 
+           FoundNode->getOpcode() < ISD::BUILTIN_OP_END && i != e; ++i)
+        FoundNode = CurSUnit->FlaggedNodes[i];
       
-      HazardRecognizer::HazardType HT = HazardRec->getHazardType(N);
+      HazardRecognizer::HazardType HT = HazardRec->getHazardType(FoundNode);
       if (HT == HazardRecognizer::NoHazard) {
-        FoundNode = CurNode;
+        FoundSUnit = CurSUnit;
         break;
       }
       
       // Remember if this is a noop hazard.
       HasNoopHazards |= HT == HazardRecognizer::NoopHazard;
       
-      NotReady.push_back(CurNode);
+      NotReady.push_back(CurSUnit);
     }
     
     // Add the nodes that aren't ready back onto the available list.
-    AvailableQueue->push_all(NotReady);
-    NotReady.clear();
+    if (!NotReady.empty()) {
+      AvailableQueue->push_all(NotReady);
+      NotReady.clear();
+    }
 
     // If we found a node to schedule, do it now.
-    if (FoundNode) {
-      ScheduleNodeTopDown(FoundNode, CurCycle);
-      HazardRec->EmitInstruction(FoundNode->Node);
-      FoundNode->isScheduled = true;
-      AvailableQueue->ScheduledNode(FoundNode);
+    if (FoundSUnit) {
+      ScheduleNodeTopDown(FoundSUnit, CurCycle);
+      HazardRec->EmitInstruction(FoundNode);
+      FoundSUnit->isScheduled = true;
+      AvailableQueue->ScheduledNode(FoundSUnit);
 
       // If this is a pseudo-op node, we don't want to increment the current
       // cycle.
-      if (FoundNode->Latency == 0)
-        continue;   // Don't increment for pseudo-ops!
+      if (FoundSUnit->Latency)  // Don't increment CurCycle for pseudo-ops!
+        ++CurCycle;        
     } else if (!HasNoopHazards) {
       // Otherwise, we have a pipeline stall, but no other problem, just advance
       // the current cycle and try again.
       DEBUG(std::cerr << "*** Advancing cycle, no work to do\n");
       HazardRec->AdvanceCycle();
       ++NumStalls;
+      ++CurCycle;
     } else {
       // Otherwise, we have no instructions to issue and we have instructions
       // that will fault if we don't do this right.  This is the case for
@@ -674,8 +689,8 @@ void ScheduleDAGList::ListScheduleTopDown() {
       HazardRec->EmitNoop();
       Sequence.push_back(0);   // NULL SUnit* -> noop
       ++NumNoops;
+      ++CurCycle;
     }
-    ++CurCycle;
   }
 
 #ifndef NDEBUG