Handle contained nodes earlier in buildRefPositionsForNode.
authorPat Gavlin <pagavlin@microsoft.com>
Wed, 15 Feb 2017 01:08:44 +0000 (17:08 -0800)
committerPat Gavlin <pagavlin@microsoft.com>
Tue, 28 Feb 2017 23:18:08 +0000 (15:18 -0800)
These nodes never produce ref positions. Handling them earlier in this function
avoids a rather large amount of unnecessary work (e.g. this decreases overall
compile time by about 0.5% for `crossgen System.Private.CoreLib`).

Commit migrated from https://github.com/dotnet/coreclr/commit/aa910800a204edff57b51d1cb3e7960dd0f98656

src/coreclr/src/jit/lsra.cpp
src/coreclr/src/jit/lsra.h

index 2d317a7..00c1b7b 100644 (file)
@@ -3563,6 +3563,39 @@ void LinearScan::buildRefPositionsForNode(GenTree*                  tree,
     }
 #endif // DEBUG
 
+    const bool isContainedNode = !info.isLocalDefUse && consume == 0 && produce == 0 && tree->canBeContained();
+    if (isContainedNode)
+    {
+        assert(info.internalIntCount == 0);
+        assert(info.internalFloatCount == 0);
+
+        // Contained nodes map to the concatenated lists of their operands.
+        LocationInfoList locationInfoList;
+        for (GenTree* op : tree->Operands())
+        {
+            if (!op->gtLsraInfo.definesAnyRegisters)
+            {
+                assert(ComputeOperandDstCount(op) == 0);
+                continue;
+            }
+
+            LocationInfoList operandList;
+            bool             removed = operandToLocationInfoMap.TryRemove(op, &operandList);
+            assert(removed);
+
+            locationInfoList.Append(operandList);
+        }
+
+        if (!locationInfoList.IsEmpty())
+        {
+            bool added = operandToLocationInfoMap.AddOrUpdate(tree, locationInfoList);
+            assert(added);
+            tree->gtLsraInfo.definesAnyRegisters = true;
+        }
+
+        return;
+    }
+
     // Handle the case of local variable assignment
     Interval* varDefInterval = nullptr;
     RefType   defRefType     = RefTypeDef;
@@ -4071,27 +4104,6 @@ void LinearScan::buildRefPositionsForNode(GenTree*                  tree,
     buildUpperVectorRestoreRefPositions(tree, defLocation, liveLargeVectors);
 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
 
-    bool isContainedNode = !noAdd && consume == 0 && produce == 0 &&
-                           (tree->OperIsFieldListHead() || ((tree->TypeGet() != TYP_VOID) && !tree->OperIsStore()));
-    if (isContainedNode)
-    {
-        // Contained nodes map to the concatenated lists of their operands.
-        for (GenTree* op : tree->Operands())
-        {
-            if (!op->gtLsraInfo.definesAnyRegisters)
-            {
-                assert(ComputeOperandDstCount(op) == 0);
-                continue;
-            }
-
-            LocationInfoList operandList;
-            bool             removed = operandToLocationInfoMap.TryRemove(op, &operandList);
-            assert(removed);
-
-            locationInfoList.Append(operandList);
-        }
-    }
-
     if (!locationInfoList.IsEmpty())
     {
         bool added = operandToLocationInfoMap.AddOrUpdate(tree, locationInfoList);
index c8a3fb4..f3f9336 100644 (file)
@@ -744,6 +744,9 @@ private:
         TreeNodeInfo& info = tree->gtLsraInfo;
         info.srcCount      = 0;
         info.dstCount      = 0;
+
+        info.internalIntCount   = 0;
+        info.internalFloatCount = 0;
     }
 
     inline bool isLocalDefUse(GenTree* tree)