If a node that defines a physical register that is expensive to copy. The
scheduler will try a number of tricks in order to avoid generating the
copies. This may not be possible in case the node produces a chain value
that prevent movement. Try unfolding the load from the node before to allow
it to be moved / cloned.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42625 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
index bd5c598..b616b7e 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
@@ -68,6 +68,7 @@
   return SU;
 }
 
+
 /// BuildSchedUnits - Build SUnits from the selection dag that we are input.
 /// This SUnit graph is similar to the SelectionDAG, but represents flagged
 /// together nodes with a single SUnit.
@@ -77,8 +78,6 @@
   // invalidated.
   SUnits.reserve(std::distance(DAG.allnodes_begin(), DAG.allnodes_end()));
   
-  const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
-  
   for (SelectionDAG::allnodes_iterator NI = DAG.allnodes_begin(),
        E = DAG.allnodes_end(); NI != E; ++NI) {
     if (isPassiveNode(NI))  // Leaf node, e.g. a TargetImmediate.
@@ -131,32 +130,8 @@
     // Update the SUnit
     NodeSUnit->Node = N;
     SUnitMap[N].push_back(NodeSUnit);
-    
-    // Compute the latency for the node.  We use the sum of the latencies for
-    // all nodes flagged together into this SUnit.
-    if (InstrItins.isEmpty()) {
-      // No latency information.
-      NodeSUnit->Latency = 1;
-    } else {
-      NodeSUnit->Latency = 0;
-      if (N->isTargetOpcode()) {
-        unsigned SchedClass = TII->getSchedClass(N->getTargetOpcode());
-        InstrStage *S = InstrItins.begin(SchedClass);
-        InstrStage *E = InstrItins.end(SchedClass);
-        for (; S != E; ++S)
-          NodeSUnit->Latency += S->Cycles;
-      }
-      for (unsigned i = 0, e = NodeSUnit->FlaggedNodes.size(); i != e; ++i) {
-        SDNode *FNode = NodeSUnit->FlaggedNodes[i];
-        if (FNode->isTargetOpcode()) {
-          unsigned SchedClass = TII->getSchedClass(FNode->getTargetOpcode());
-          InstrStage *S = InstrItins.begin(SchedClass);
-          InstrStage *E = InstrItins.end(SchedClass);
-          for (; S != E; ++S)
-            NodeSUnit->Latency += S->Cycles;
-        }
-      }
-    }
+
+    ComputeLatency(NodeSUnit);
   }
   
   // Pass 2: add the preds, succs, etc.
@@ -214,6 +189,36 @@
   return;
 }
 
+void ScheduleDAG::ComputeLatency(SUnit *SU) {
+  const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
+  
+  // Compute the latency for the node.  We use the sum of the latencies for
+  // all nodes flagged together into this SUnit.
+  if (InstrItins.isEmpty()) {
+    // No latency information.
+    SU->Latency = 1;
+  } else {
+    SU->Latency = 0;
+    if (SU->Node->isTargetOpcode()) {
+      unsigned SchedClass = TII->getSchedClass(SU->Node->getTargetOpcode());
+      InstrStage *S = InstrItins.begin(SchedClass);
+      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->isTargetOpcode()) {
+        unsigned SchedClass = TII->getSchedClass(FNode->getTargetOpcode());
+        InstrStage *S = InstrItins.begin(SchedClass);
+        InstrStage *E = InstrItins.end(SchedClass);
+        for (; S != E; ++S)
+          SU->Latency += S->Cycles;
+      }
+    }
+  }
+}
+
 void ScheduleDAG::CalculateDepths() {
   std::vector<std::pair<SUnit*, unsigned> > WorkList;
   for (unsigned i = 0, e = SUnits.size(); i != e; ++i)