Propagate DAG node ordering during type legalization and instruction selection

A node's ordering is only propagated during legalization if (a) the new node does
not have an ordering (is not a CSE'd node), or (b) the new node has an ordering
that is higher than the node being legalized.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177465 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
index e26d165..1d6a981 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
@@ -619,6 +619,17 @@
   }
 }
 
+/// PropagateOrdering - Propagate SDNode ordering information from \p Old to
+/// \p New. Generally, this just means copying the ordering value, but if the
+/// new node is actually a recycled node with a lower ordering already, then
+/// we do not want to propagate the new (higher) ordering.
+void DAGTypeLegalizer::PropagateOrdering(SDNode *Old, SDNode *New) {
+  unsigned OldOrder = DAG.GetOrdering(Old);
+  unsigned NewOrder = DAG.GetOrdering(New);
+  if (NewOrder == 0 || (NewOrder > 0 && OldOrder < NewOrder))
+    DAG.AssignOrdering(New, OldOrder);
+}
+
 namespace {
   /// NodeUpdateListener - This class is a DAGUpdateListener that listens for
   /// updates to nodes and recomputes their ready state.
@@ -735,6 +746,9 @@
   SDValue &OpEntry = PromotedIntegers[Op];
   assert(OpEntry.getNode() == 0 && "Node is already promoted!");
   OpEntry = Result;
+
+  // Propagate node ordering
+  PropagateOrdering(Op.getNode(), Result.getNode());
 }
 
 void DAGTypeLegalizer::SetSoftenedFloat(SDValue Op, SDValue Result) {
@@ -746,6 +760,9 @@
   SDValue &OpEntry = SoftenedFloats[Op];
   assert(OpEntry.getNode() == 0 && "Node is already converted to integer!");
   OpEntry = Result;
+
+  // Propagate node ordering
+  PropagateOrdering(Op.getNode(), Result.getNode());
 }
 
 void DAGTypeLegalizer::SetScalarizedVector(SDValue Op, SDValue Result) {
@@ -760,6 +777,9 @@
   SDValue &OpEntry = ScalarizedVectors[Op];
   assert(OpEntry.getNode() == 0 && "Node is already scalarized!");
   OpEntry = Result;
+
+  // Propagate node ordering
+  PropagateOrdering(Op.getNode(), Result.getNode());
 }
 
 void DAGTypeLegalizer::GetExpandedInteger(SDValue Op, SDValue &Lo,
@@ -787,6 +807,10 @@
   assert(Entry.first.getNode() == 0 && "Node already expanded");
   Entry.first = Lo;
   Entry.second = Hi;
+
+  // Propagate ordering
+  PropagateOrdering(Op.getNode(), Lo.getNode());
+  PropagateOrdering(Op.getNode(), Hi.getNode());
 }
 
 void DAGTypeLegalizer::GetExpandedFloat(SDValue Op, SDValue &Lo,
@@ -814,6 +838,10 @@
   assert(Entry.first.getNode() == 0 && "Node already expanded");
   Entry.first = Lo;
   Entry.second = Hi;
+
+  // Propagate ordering
+  PropagateOrdering(Op.getNode(), Lo.getNode());
+  PropagateOrdering(Op.getNode(), Hi.getNode());
 }
 
 void DAGTypeLegalizer::GetSplitVector(SDValue Op, SDValue &Lo,
@@ -843,6 +871,10 @@
   assert(Entry.first.getNode() == 0 && "Node already split");
   Entry.first = Lo;
   Entry.second = Hi;
+
+  // Propagate ordering
+  PropagateOrdering(Op.getNode(), Lo.getNode());
+  PropagateOrdering(Op.getNode(), Hi.getNode());
 }
 
 void DAGTypeLegalizer::SetWidenedVector(SDValue Op, SDValue Result) {
@@ -854,6 +886,9 @@
   SDValue &OpEntry = WidenedVectors[Op];
   assert(OpEntry.getNode() == 0 && "Node already widened!");
   OpEntry = Result;
+
+  // Propagate node ordering
+  PropagateOrdering(Op.getNode(), Result.getNode());
 }
 
 
@@ -919,8 +954,11 @@
   // Make everything that once used N's values now use those in Results instead.
   assert(Results.size() == N->getNumValues() &&
          "Custom lowering returned the wrong number of results!");
-  for (unsigned i = 0, e = Results.size(); i != e; ++i)
+  for (unsigned i = 0, e = Results.size(); i != e; ++i) {
     ReplaceValueWith(SDValue(N, i), Results[i]);
+    // Propagate node ordering
+    DAG.AssignOrdering(Results[i].getNode(), DAG.GetOrdering(N));
+  }
   return true;
 }
 
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 27b3cf2..b8b5ba8 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -143,6 +143,7 @@
   void ExpungeNode(SDNode *N);
   void PerformExpensiveChecks();
   void RemapValue(SDValue &N);
+  void PropagateOrdering(SDNode *Old, SDNode *New);
 
   // Common routines.
   SDValue BitConvertToInteger(SDValue Op);
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index c3b6276..15001f5 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -785,8 +785,10 @@
       if (ResNode == Node || Node->getOpcode() == ISD::DELETED_NODE)
         continue;
       // Replace node.
-      if (ResNode)
+      if (ResNode) {
+        CurDAG->AssignOrdering(ResNode, CurDAG->GetOrdering(Node));
         ReplaceUses(Node, ResNode);
+      }
 
       // If after the replacement this node is not used any more,
       // remove this dead node.