@@ -71,7 +71,7 @@ ObjectAllocator::ObjectAllocator(Compiler* comp)
7171//
7272bool ObjectAllocator::IsTrackedType (var_types type)
7373{
74- const bool isTrackableScalar = (type == TYP_REF) || (genActualType (type) == TYP_I_IMPL) || ( type == TYP_BYREF);
74+ const bool isTrackableScalar = (type == TYP_REF) || (type == TYP_BYREF);
7575 return isTrackableScalar;
7676}
7777
@@ -1579,12 +1579,19 @@ bool ObjectAllocator::CanLclVarEscapeViaParentStack(ArrayStack<GenTree*>* parent
15791579
15801580 switch (parent->OperGet ())
15811581 {
1582- // Update the connection graph if we are storing to a local.
1583- // For all other stores we mark the local as escaping.
15841582 case GT_STORE_LCL_VAR:
15851583 {
1586- // Add an edge to the connection graph.
15871584 const unsigned int dstLclNum = parent->AsLclVar ()->GetLclNum ();
1585+
1586+ // If we're not tracking stores to this local, the value
1587+ // does not escape.
1588+ if (!IsTrackedLocal (dstLclNum))
1589+ {
1590+ canLclVarEscapeViaParentStack = false ;
1591+ break ;
1592+ }
1593+
1594+ // Add an edge to the connection graph.
15881595 const unsigned int srcLclNum = lclNum;
15891596
15901597 AddConnGraphEdge (dstLclNum, srcLclNum);
@@ -1626,13 +1633,25 @@ bool ObjectAllocator::CanLclVarEscapeViaParentStack(ArrayStack<GenTree*>* parent
16261633 case GT_COLON:
16271634 case GT_QMARK:
16281635 case GT_ADD:
1629- case GT_SUB:
16301636 case GT_FIELD_ADDR:
16311637 // Check whether the local escapes via its grandparent.
16321638 ++parentIndex;
16331639 keepChecking = true ;
16341640 break ;
16351641
1642+ case GT_SUB:
1643+ // Sub of two GC refs is no longer a GC ref.
1644+ if (!parent->TypeIs (TYP_BYREF, TYP_REF))
1645+ {
1646+ canLclVarEscapeViaParentStack = false ;
1647+ break ;
1648+ }
1649+
1650+ // Check whether the local escapes higher up
1651+ ++parentIndex;
1652+ keepChecking = true ;
1653+ break ;
1654+
16361655 case GT_BOX:
16371656 isCopy = wasCopy;
16381657 ++parentIndex;
@@ -1787,7 +1806,6 @@ void ObjectAllocator::UpdateAncestorTypes(GenTree* tree, ArrayStack<GenTree*>* p
17871806 FALLTHROUGH;
17881807 case GT_QMARK:
17891808 case GT_ADD:
1790- case GT_SUB:
17911809 case GT_FIELD_ADDR:
17921810 case GT_INDEX_ADDR:
17931811 case GT_BOX:
@@ -1799,6 +1817,33 @@ void ObjectAllocator::UpdateAncestorTypes(GenTree* tree, ArrayStack<GenTree*>* p
17991817 keepChecking = true ;
18001818 break ;
18011819
1820+ case GT_SUB:
1821+ {
1822+ // Parent type can be TYP_I_IMPL, TYP_BYREF.
1823+ // But not TYP_REF.
1824+ //
1825+ var_types parentType = parent->TypeGet ();
1826+ assert (parentType != TYP_REF);
1827+
1828+ // New type can be TYP_I_IMPL, TYP_BYREF.
1829+ // But TYP_BYREF only if parent is also
1830+ //
1831+ if (parentType != newType)
1832+ {
1833+ // We must be retyping TYP_BYREF to TYP_I_IMPL.
1834+ //
1835+ assert (newType == TYP_I_IMPL);
1836+ assert (parentType == TYP_BYREF);
1837+ parent->ChangeType (newType);
1838+
1839+ // Propgate that upwards.
1840+ //
1841+ ++parentIndex;
1842+ keepChecking = true ;
1843+ }
1844+ break ;
1845+ }
1846+
18021847 case GT_COLON:
18031848 {
18041849 GenTree* const lhs = parent->AsOp ()->gtGetOp1 ();
0 commit comments