Remove the FlaggedNodes member from SUnit. Instead of requiring each SUnit
authorDan Gohman <gohman@apple.com>
Thu, 13 Nov 2008 23:24:17 +0000 (23:24 +0000)
committerDan Gohman <gohman@apple.com>
Thu, 13 Nov 2008 23:24:17 +0000 (23:24 +0000)
to carry a SmallVector of flagged nodes, just calculate the flagged nodes
dynamically when they are needed.

The local-liveness change is due to a trivial scheduling change where
the scheduler arbitrary decision differently.

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

include/llvm/CodeGen/ScheduleDAG.h
include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp
lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp
lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
test/CodeGen/X86/local-liveness.ll

index 890dc0f149c0002d8e2974f4e5819de48f381ee1..2d4592bbe63cc2ca47f6132e581bddd141ac8d6a 100644 (file)
@@ -95,7 +95,6 @@ namespace llvm {
   private:
     SDNode *Node;                       // Representative node.
   public:
-    SmallVector<SDNode*,4> FlaggedNodes;// All nodes flagged to Node.
     SUnit *OrigNode;                    // If not this, the node from which
                                         // this node was cloned.
     
index 94bb2ae79b801f53d6621fbac5086b0156566c95..839db7d454c598372fd34f42a4351404b82e82a5 100644 (file)
@@ -1308,6 +1308,15 @@ public:
     SDVTList X = { ValueList, NumValues };
     return X;
   };
+
+  /// getFlaggedNode - If this node has a flag operand, return the node
+  /// to which the flag operand points. Otherwise return NULL.
+  SDNode *getFlaggedNode() const {
+    if (getNumOperands() != 0 &&
+        getOperand(getNumOperands()-1).getValueType() == MVT::Flag)
+      return getOperand(getNumOperands()-1).getNode();
+    return 0;
+  }
   
   /// getNumValues - Return the number of values defined/returned by this
   /// operator.
index 7dd8f501aa5dc6b865bece0026d076cc3d9f09f5..6d6b9c7c0f0c95b476b9d335d8abca393260d063 100644 (file)
@@ -60,7 +60,6 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
 SUnit *ScheduleDAG::Clone(SUnit *Old) {
   SUnit *SU = NewSUnit(Old->getNode());
   SU->OrigNode = Old->OrigNode;
-  SU->FlaggedNodes = Old->FlaggedNodes;
   SU->Latency = Old->Latency;
   SU->isTwoAddress = Old->isTwoAddress;
   SU->isCommutable = Old->isCommutable;
@@ -99,23 +98,19 @@ void ScheduleDAG::BuildSchedUnits() {
     // nodes.  Nodes can have at most one flag input and one flag output.  Flags
     // are required the be the last operand and result of a node.
     
-    // Scan up, adding flagged preds to FlaggedNodes.
+    // Scan up to find flagged preds.
     SDNode *N = NI;
     if (N->getNumOperands() &&
         N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) {
       do {
         N = N->getOperand(N->getNumOperands()-1).getNode();
-        NodeSUnit->FlaggedNodes.push_back(N);
         assert(N->getNodeId() == -1 && "Node already inserted!");
         N->setNodeId(NodeSUnit->NodeNum);
       } while (N->getNumOperands() &&
                N->getOperand(N->getNumOperands()-1).getValueType()== MVT::Flag);
-      std::reverse(NodeSUnit->FlaggedNodes.begin(),
-                   NodeSUnit->FlaggedNodes.end());
     }
     
-    // Scan down, adding this node and any flagged succs to FlaggedNodes if they
-    // have a user of the flag operand.
+    // Scan down to find any flagged succs.
     N = NI;
     while (N->getValueType(N->getNumValues()-1) == MVT::Flag) {
       SDValue FlagVal(N, N->getNumValues()-1);
@@ -126,7 +121,6 @@ void ScheduleDAG::BuildSchedUnits() {
            UI != E; ++UI)
         if (FlagVal.isOperandOf(*UI)) {
           HasFlagUse = true;
-          NodeSUnit->FlaggedNodes.push_back(N);
           assert(N->getNodeId() == -1 && "Node already inserted!");
           N->setNodeId(NodeSUnit->NodeNum);
           N = *UI;
@@ -135,8 +129,9 @@ void ScheduleDAG::BuildSchedUnits() {
       if (!HasFlagUse) break;
     }
     
-    // Now all flagged nodes are in FlaggedNodes and N is the bottom-most node.
-    // Update the SUnit
+    // If there are flag operands involved, N is now the bottom-most node
+    // of the sequence of nodes that are flagged together.
+    // Update the SUnit.
     NodeSUnit->setNode(N);
     assert(N->getNodeId() == -1 && "Node already inserted!");
     N->setNodeId(NodeSUnit->NodeNum);
@@ -163,11 +158,7 @@ void ScheduleDAG::BuildSchedUnits() {
     }
     
     // Find all predecessors and successors of the group.
-    // Temporarily add N to make code simpler.
-    SU->FlaggedNodes.push_back(MainNode);
-    
-    for (unsigned n = 0, e = SU->FlaggedNodes.size(); n != e; ++n) {
-      SDNode *N = SU->FlaggedNodes[n];
+    for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
       if (N->isMachineOpcode() &&
           TII->get(N->getMachineOpcode()).getImplicitDefs() &&
           CountResults(N) > TII->get(N->getMachineOpcode()).getNumDefs())
@@ -191,9 +182,6 @@ void ScheduleDAG::BuildSchedUnits() {
         SU->addPred(OpSU, isChain, false, PhysReg, Cost);
       }
     }
-    
-    // Remove MainNode from FlaggedNodes again.
-    SU->FlaggedNodes.pop_back();
   }
 }
 
@@ -209,17 +197,9 @@ void ScheduleDAG::ComputeLatency(SUnit *SU) {
   }
 
   SU->Latency = 0;
-  if (SU->getNode()->isMachineOpcode()) {
-    unsigned SchedClass = TII->get(SU->getNode()->getMachineOpcode()).getSchedClass();
-    const InstrStage *S = InstrItins.begin(SchedClass);
-    const InstrStage *E = InstrItins.end(SchedClass);
-    for (; S != E; ++S)
-      SU->Latency += S->Cycles;
-  }
-  for (unsigned i = 0, e = SU->FlaggedNodes.size(); i != e; ++i) {
-    SDNode *FNode = SU->FlaggedNodes[i];
-    if (FNode->isMachineOpcode()) {
-      unsigned SchedClass = TII->get(FNode->getMachineOpcode()).getSchedClass();
+  for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
+    if (N->isMachineOpcode()) {
+      unsigned SchedClass = TII->get(N->getMachineOpcode()).getSchedClass();
       const InstrStage *S = InstrItins.begin(SchedClass);
       const InstrStage *E = InstrItins.end(SchedClass);
       for (; S != E; ++S)
@@ -397,17 +377,19 @@ void ScheduleDAG::Run() {
 /// a group of nodes flagged together.
 void SUnit::dump(const SelectionDAG *G) const {
   cerr << "SU(" << NodeNum << "): ";
-  if (Node)
-    Node->dump(G);
+  if (getNode())
+    getNode()->dump(G);
   else
     cerr << "CROSS RC COPY ";
   cerr << "\n";
-  if (FlaggedNodes.size() != 0) {
-    for (unsigned i = 0, e = FlaggedNodes.size(); i != e; i++) {
-      cerr << "    ";
-      FlaggedNodes[i]->dump(G);
-      cerr << "\n";
-    }
+  SmallVector<SDNode *, 4> FlaggedNodes;
+  for (SDNode *N = getNode()->getFlaggedNode(); N; N = N->getFlaggedNode())
+    FlaggedNodes.push_back(N);
+  while (!FlaggedNodes.empty()) {
+    cerr << "    ";
+    FlaggedNodes.back()->dump(G);
+    cerr << "\n";
+    FlaggedNodes.pop_back();
   }
 }
 
index 7d5822faaee06f332655685ffe539f5e15e1b846..2c40d97a7ea0975130a734f08675451f684aabfe 100644 (file)
@@ -684,8 +684,13 @@ MachineBasicBlock *ScheduleDAG::EmitSchedule() {
       EmitNoop();
       continue;
     }
-    for (unsigned j = 0, ee = SU->FlaggedNodes.size(); j != ee; ++j)
-      EmitNode(SU->FlaggedNodes[j], SU->OrigNode != SU, VRBaseMap);
+    SmallVector<SDNode *, 4> FlaggedNodes;
+    for (SDNode *N = SU->getNode()->getFlaggedNode(); N; N = N->getFlaggedNode())
+      FlaggedNodes.push_back(N);
+    while (!FlaggedNodes.empty()) {
+      EmitNode(FlaggedNodes.back(), SU->OrigNode != SU, VRBaseMap);
+      FlaggedNodes.pop_back();
+    }
     if (!SU->getNode())
       EmitCrossRCCopy(SU, CopyVRBaseMap);
     else
index 51a784e64323ff444acb26d775905ea0e994a8b3..ae20774dcf605b0f57a9b98df8f593c40c27f599 100644 (file)
@@ -221,7 +221,7 @@ bool ScheduleDAGFast::RemovePred(SUnit *M, SUnit *N,
 /// CopyAndMoveSuccessors - Clone the specified node and move its scheduled
 /// successors to the newly created node.
 SUnit *ScheduleDAGFast::CopyAndMoveSuccessors(SUnit *SU) {
-  if (SU->FlaggedNodes.size())
+  if (SU->getNode()->getFlaggedNode())
     return NULL;
 
   SDNode *N = SU->getNode();
@@ -485,9 +485,8 @@ bool ScheduleDAGFast::DelayForLiveRegsBottomUp(SUnit *SU,
     }
   }
 
-  for (unsigned i = 0, e = SU->FlaggedNodes.size()+1; i != e; ++i) {
-    SDNode *Node = (i == 0) ? SU->getNode() : SU->FlaggedNodes[i-1];
-    if (!Node || !Node->isMachineOpcode())
+  for (SDNode *Node = SU->getNode(); Node; Node = Node->getFlaggedNode()) {
+    if (!Node->isMachineOpcode())
       continue;
     const TargetInstrDesc &TID = TII->get(Node->getMachineOpcode());
     if (!TID.ImplicitDefs)
index 8921545e1ab3b3feb803f6e8d559621420060360..14042ed602a51c6f09720f05c1373dc0df856c38 100644 (file)
@@ -205,9 +205,11 @@ void ScheduleDAGList::ListScheduleTopDown() {
       
       // 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 = CurSUnit->FlaggedNodes.size(); 
-           !FoundNode->isMachineOpcode() && i != e; ++i)
-        FoundNode = CurSUnit->FlaggedNodes[i];
+      while (!FoundNode->isMachineOpcode()) {
+        SDNode *N = FoundNode->getFlaggedNode();
+        if (!N) break;
+        FoundNode = N;
+      }
       
       HazardRecognizer::HazardType HT = HazardRec->getHazardType(FoundNode);
       if (HT == HazardRecognizer::NoHazard) {
index 15fffdfeea1d16c6d45bd0ae1db34f631b6213d7..15ba26679ccbceacb24e4c3823dee558a6b95ed0 100644 (file)
@@ -626,7 +626,7 @@ void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle,
 /// CopyAndMoveSuccessors - Clone the specified node and move its scheduled
 /// successors to the newly created node.
 SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) {
-  if (SU->FlaggedNodes.size())
+  if (SU->getNode()->getFlaggedNode())
     return NULL;
 
   SDNode *N = SU->getNode();
@@ -903,9 +903,8 @@ bool ScheduleDAGRRList::DelayForLiveRegsBottomUp(SUnit *SU,
     }
   }
 
-  for (unsigned i = 0, e = SU->FlaggedNodes.size()+1; i != e; ++i) {
-    SDNode *Node = (i == 0) ? SU->getNode() : SU->FlaggedNodes[i-1];
-    if (!Node || !Node->isMachineOpcode())
+  for (SDNode *Node = SU->getNode(); Node; Node = Node->getFlaggedNode()) {
+    if (!Node->isMachineOpcode())
       continue;
     const TargetInstrDesc &TID = TII->get(Node->getMachineOpcode());
     if (!TID.ImplicitDefs)
@@ -1736,7 +1735,7 @@ void BURegReductionPriorityQueue::AddPseudoTwoAddrDeps() {
       continue;
 
     SDNode *Node = SU->getNode();
-    if (!Node || !Node->isMachineOpcode() || SU->FlaggedNodes.size() > 0)
+    if (!Node || !Node->isMachineOpcode() || SU->getNode()->getFlaggedNode())
       continue;
 
     unsigned Opc = Node->getMachineOpcode();
index 1f45729462b5fa67af4063355802980dd0b35875..a356b6d471caf2d3227ef70c65d1f4b1906daab7 100644 (file)
@@ -433,16 +433,19 @@ std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU,
                                                        const ScheduleDAG *G) {
   std::string Op;
 
-  for (unsigned i = 0; i < SU->FlaggedNodes.size(); ++i) {
-    Op += DOTGraphTraits<SelectionDAG*>::getNodeLabel(SU->FlaggedNodes[i],
-                                                      G->DAG) + "\n";
+  if (!SU->getNode())
+    Op = "<CROSS RC COPY>";
+  else {
+    SmallVector<SDNode *, 4> FlaggedNodes;
+    for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode())
+      FlaggedNodes.push_back(N);
+    while (!FlaggedNodes.empty()) {
+      Op += DOTGraphTraits<SelectionDAG*>::getNodeLabel(FlaggedNodes.back(),
+                                                        G->DAG) + "\n";
+      FlaggedNodes.pop_back();
+    }
   }
 
-  if (SU->getNode())
-    Op += DOTGraphTraits<SelectionDAG*>::getNodeLabel(SU->getNode(), G->DAG);
-  else
-    Op += "<CROSS RC COPY>";
-
   return Op;
 }
 
index f176ec2c56b981e88499cf25bf76be06122e0d01..18d999b7d47eb8fb825db098783a239424a765ef 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc -march=x86 -regalloc=local | grep {subl      %eax, %esi}
+; RUN: llvm-as < %s | llc -march=x86 -regalloc=local | grep {subl      %eax, %edx}
 
 ; Local regalloc shouldn't assume that both the uses of the
 ; sub instruction are kills, because one of them is tied