[llvm-commits] [llvm] r49701 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/SelectionDAG/ScheduleDAG.cpp lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp test/CodeGen/X86/loop-hoist.ll

Dan Gohman gohman at apple.com
Mon Apr 14 18:22:24 PDT 2008


Author: djg
Date: Mon Apr 14 20:22:18 2008
New Revision: 49701

URL: http://llvm.org/viewvc/llvm-project?rev=49701&view=rev
Log:
Treat EntryToken nodes as "passive" so that they aren't added to the
ScheduleDAG; they don't correspond to any actual instructions so they
don't need to be scheduled.

This fixes a bug where the EntryToken was being scheduled multiple
times in some cases, though it ended up not causing any trouble because 
EntryToken doesn't expand into anything. With this fixed the schedulers
reliably schedule the expected number of units, so we can check this
with an assertion.

This requires a tweak to test/CodeGen/X86/loop-hoist.ll because it
ends up getting scheduled differently in a trivial way, though it was
enough to fool the prcontext+grep that the test does.

Modified:
    llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
    llvm/trunk/test/CodeGen/X86/loop-hoist.ll

Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=49701&r1=49700&r2=49701&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Mon Apr 14 20:22:18 2008
@@ -285,6 +285,7 @@
       if (isa<JumpTableSDNode>(Node))      return true;
       if (isa<ExternalSymbolSDNode>(Node)) return true;
       if (isa<MemOperandSDNode>(Node))     return true;
+      if (Node->getOpcode() == ISD::EntryToken) return true;
       return false;
     }
 

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=49701&r1=49700&r2=49701&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Mon Apr 14 20:22:18 2008
@@ -863,8 +863,11 @@
       Node->dump(&DAG);
 #endif
       assert(0 && "This target-independent node should have been selected!");
-    case ISD::EntryToken: // fall thru
-    case ISD::TokenFactor:
+      break;
+    case ISD::EntryToken:
+      assert(0 && "EntryToken should have been excluded from the schedule!");
+      break;
+    case ISD::TokenFactor: // fall thru
     case ISD::LABEL:
     case ISD::DECLARE:
     case ISD::SRCVALUE:

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp?rev=49701&r1=49700&r2=49701&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Mon Apr 14 20:22:18 2008
@@ -164,21 +164,16 @@
 /// schedulers.
 void ScheduleDAGList::ListScheduleTopDown() {
   unsigned CurCycle = 0;
-  SUnit *Entry = SUnitMap[DAG.getEntryNode().Val].front();
 
   // All leaves to Available queue.
   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
     // It is available if it has no predecessors.
-    if (SUnits[i].Preds.empty() && &SUnits[i] != Entry) {
+    if (SUnits[i].Preds.empty()) {
       AvailableQueue->push(&SUnits[i]);
       SUnits[i].isAvailable = SUnits[i].isPending = true;
     }
   }
   
-  // Emit the entry node first.
-  ScheduleNodeTopDown(Entry, CurCycle);
-  HazardRec->EmitInstruction(Entry->Node);
-  
   // While Available queue is not empty, grab the node with the highest
   // priority. If it is not ready put it back.  Schedule the node.
   std::vector<SUnit*> NotReady;

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=49701&r1=49700&r2=49701&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Apr 14 20:22:18 2008
@@ -239,7 +239,8 @@
 /// possible. It will be commuted when it is translated to a MI.
 void ScheduleDAGRRList::CommuteNodesToReducePressure() {
   SmallPtrSet<SUnit*, 4> OperandSeen;
-  for (unsigned i = Sequence.size()-1; i != 0; --i) {  // Ignore first node.
+  for (unsigned i = Sequence.size(); i != 0; ) {
+    --i;
     SUnit *SU = Sequence[i];
     if (!SU || !SU->Node) continue;
     if (SU->isCommutable) {
@@ -311,11 +312,8 @@
 #endif
   
   if (PredSU->NumSuccsLeft == 0) {
-    // EntryToken has to go last!  Special case it here.
-    if (!PredSU->Node || PredSU->Node->getOpcode() != ISD::EntryToken) {
-      PredSU->isAvailable = true;
-      AvailableQueue->push(PredSU);
-    }
+    PredSU->isAvailable = true;
+    AvailableQueue->push(PredSU);
   }
 }
 
@@ -735,9 +733,10 @@
                                  I->isCtrl, I->isSpecial));
     }
 
-    RemovePred(SU, ChainPred, true, false);
-    if (isNewLoad) {
-      AddPred(LoadSU,ChainPred, true, false);
+    if (ChainPred) {
+      RemovePred(SU, ChainPred, true, false);
+      if (isNewLoad)
+        AddPred(LoadSU, ChainPred, true, false);
     }
     for (unsigned i = 0, e = LoadPreds.size(); i != e; ++i) {
       SDep *Pred = &LoadPreds[i];
@@ -941,9 +940,12 @@
 void ScheduleDAGRRList::ListScheduleBottomUp() {
   unsigned CurCycle = 0;
   // Add root to Available queue.
-  SUnit *RootSU = SUnitMap[DAG.getRoot().Val].front();
-  RootSU->isAvailable = true;
-  AvailableQueue->push(RootSU);
+  if (!SUnits.empty()) {
+    SUnit *RootSU = SUnitMap[DAG.getRoot().Val].front();
+    assert(RootSU->Succs.empty() && "Graph root shouldn't have successors!");
+    RootSU->isAvailable = true;
+    AvailableQueue->push(RootSU);
+  }
 
   // While Available queue is not empty, grab the node with the highest
   // priority. If it is not ready put it back.  Schedule the node.
@@ -1066,12 +1068,6 @@
     ++CurCycle;
   }
 
-  // Add entry node last
-  if (DAG.getEntryNode().Val != DAG.getRoot().Val) {
-    SUnit *Entry = SUnitMap[DAG.getEntryNode().Val].front();
-    Sequence.push_back(Entry);
-  }
-
   // Reverse the order if it is bottom up.
   std::reverse(Sequence.begin(), Sequence.end());
   
@@ -1079,16 +1075,30 @@
 #ifndef NDEBUG
   // Verify that all SUnits were scheduled.
   bool AnyNotSched = false;
+  unsigned DeadNodes = 0;
   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
-    if (SUnits[i].NumSuccsLeft != 0) {
+    if (!SUnits[i].isScheduled) {
+      if (SUnits[i].NumPreds == 0 && SUnits[i].NumSuccs == 0) {
+        ++DeadNodes;
+        continue;
+      }
       if (!AnyNotSched)
         cerr << "*** List scheduling failed! ***\n";
       SUnits[i].dump(&DAG);
       cerr << "has not been scheduled!\n";
       AnyNotSched = true;
     }
+    if (SUnits[i].NumSuccsLeft != 0) {
+      if (!AnyNotSched)
+        cerr << "*** List scheduling failed! ***\n";
+      SUnits[i].dump(&DAG);
+      cerr << "has successors left!\n";
+      AnyNotSched = true;
+    }
   }
   assert(!AnyNotSched);
+  assert(Sequence.size() + DeadNodes == SUnits.size() &&
+         "The number of nodes scheduled doesn't match the expected number!");
 #endif
 }
 
@@ -1145,22 +1155,16 @@
 /// schedulers.
 void ScheduleDAGRRList::ListScheduleTopDown() {
   unsigned CurCycle = 0;
-  SUnit *Entry = SUnitMap[DAG.getEntryNode().Val].front();
 
   // All leaves to Available queue.
   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
     // It is available if it has no predecessors.
-    if (SUnits[i].Preds.empty() && &SUnits[i] != Entry) {
+    if (SUnits[i].Preds.empty()) {
       AvailableQueue->push(&SUnits[i]);
       SUnits[i].isAvailable = true;
     }
   }
   
-  // Emit the entry node first.
-  ScheduleNodeTopDown(Entry, CurCycle);
-  Sequence.push_back(Entry);
-  ++CurCycle;
-
   // While Available queue is not empty, grab the node with the highest
   // priority. If it is not ready put it back.  Schedule the node.
   std::vector<SUnit*> NotReady;
@@ -1181,23 +1185,37 @@
       ScheduleNodeTopDown(CurSU, CurCycle);
       Sequence.push_back(CurSU);
     }
-    CurCycle++;
+    ++CurCycle;
   }
   
   
 #ifndef NDEBUG
   // Verify that all SUnits were scheduled.
   bool AnyNotSched = false;
+  unsigned DeadNodes = 0;
   for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
     if (!SUnits[i].isScheduled) {
+      if (SUnits[i].NumPreds == 0 && SUnits[i].NumSuccs == 0) {
+        ++DeadNodes;
+        continue;
+      }
       if (!AnyNotSched)
         cerr << "*** List scheduling failed! ***\n";
       SUnits[i].dump(&DAG);
       cerr << "has not been scheduled!\n";
       AnyNotSched = true;
     }
+    if (SUnits[i].NumPredsLeft != 0) {
+      if (!AnyNotSched)
+        cerr << "*** List scheduling failed! ***\n";
+      SUnits[i].dump(&DAG);
+      cerr << "has predecessors left!\n";
+      AnyNotSched = true;
+    }
   }
   assert(!AnyNotSched);
+  assert(Sequence.size() + DeadNodes == SUnits.size() &&
+         "The number of nodes scheduled doesn't match the expected number!");
 #endif
 }
 

Modified: llvm/trunk/test/CodeGen/X86/loop-hoist.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-hoist.ll?rev=49701&r1=49700&r2=49701&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/X86/loop-hoist.ll (original)
+++ llvm/trunk/test/CodeGen/X86/loop-hoist.ll Mon Apr 14 20:22:18 2008
@@ -7,13 +7,13 @@
 
 @Arr = external global [0 x i32]		; <[0 x i32]*> [#uses=1]
 
-define void @foo(i32 %N.in) {
+define void @foo(i32 %N.in, i32 %x) {
 entry:
 	%N = bitcast i32 %N.in to i32		; <i32> [#uses=1]
 	br label %cond_true
 
 cond_true:		; preds = %cond_true, %entry
-	%indvar = phi i32 [ 0, %entry ], [ %indvar.next, %cond_true ]		; <i32> [#uses=2]
+	%indvar = phi i32 [ %x, %entry ], [ %indvar.next, %cond_true ]		; <i32> [#uses=2]
 	%i.0.0 = bitcast i32 %indvar to i32		; <i32> [#uses=2]
 	%tmp = getelementptr [0 x i32]* @Arr, i32 0, i32 %i.0.0		; <i32*> [#uses=1]
 	store i32 %i.0.0, i32* %tmp





More information about the llvm-commits mailing list