@@ -3317,102 +3317,89 @@ void ObjectAllocator::CheckForGuardedAllocationOrCopy(BasicBlock* block,
33173317 //
33183318 if (data->OperIs (GT_ALLOCOBJ))
33193319 {
3320- // See if this store is made under a successful GDV test .
3320+ // This may be an allocation of a concrete class under GDV .
33213321 //
3322- GuardInfo controllingGDV;
3323- if (IsGuarded (block, tree, &controllingGDV, /* testOutcome */ true ))
3322+ // Find the local that will ultimately represent its uses (we have kept track of
3323+ // this during importation and GDV expansion). Note it is usually *not* lclNum.
3324+ //
3325+ // We will keep special track of all accesses to this local.
3326+ //
3327+ Compiler::NodeToUnsignedMap* const map = comp->getImpEnumeratorGdvLocalMap ();
3328+ unsigned enumeratorLocal = BAD_VAR_NUM;
3329+ if (map->Lookup (data, &enumeratorLocal))
33243330 {
3325- // This is the allocation of concrete class under GDV.
3326- //
3327- // Find the local that will ultimately represent its uses (we have kept track of
3328- // this during importation and GDV expansion). Note it is usually *not* lclNum.
3329- //
3330- // We will keep special track of all accesses to this local.
3331+ // If it turns out we can't stack allocate this new object even if it does not escape,
3332+ // then don't bother setting up tracking. Note length here is just set to a nominal
3333+ // value that won't cause failure. We will do the real length check later if we decide to allocate.
33313334 //
3332- Compiler::NodeToUnsignedMap* const map = comp->getImpEnumeratorGdvLocalMap ();
3333- unsigned enumeratorLocal = BAD_VAR_NUM;
3334- if (map->Lookup (data, &enumeratorLocal))
3335+ CORINFO_CLASS_HANDLE clsHnd = data->AsAllocObj ()->gtAllocObjClsHnd ;
3336+ const char * reason = nullptr ;
3337+ unsigned size = 0 ;
3338+ unsigned length = TARGET_POINTER_SIZE;
3339+ ObjectAllocationType oat = AllocationKind (data);
3340+ if (CanAllocateLclVarOnStack (enumeratorLocal, clsHnd, oat, length, &size, &reason,
3341+ /* preliminaryCheck */ true ))
33353342 {
3336- // If it turns out we can't stack allocate this new object even if it does not escape,
3337- // then don't bother setting up tracking. Note length here is just set to a nominal
3338- // value that won't cause failure. We will do the real length check later if we decide to allocate.
3343+ // We are going to conditionally track accesses to the enumerator local via a pseudo.
33393344 //
3340- CORINFO_CLASS_HANDLE clsHnd = data->AsAllocObj ()->gtAllocObjClsHnd ;
3341- const char * reason = nullptr ;
3342- unsigned size = 0 ;
3343- unsigned length = TARGET_POINTER_SIZE;
3344- ObjectAllocationType oat = AllocationKind (data);
3345- if (CanAllocateLclVarOnStack (enumeratorLocal, clsHnd, oat, length, &size, &reason,
3346- /* preliminaryCheck */ true ))
3345+ const unsigned pseudoIndex = NewPseudoIndex ();
3346+ assert (pseudoIndex != BAD_VAR_NUM);
3347+ bool added = m_EnumeratorLocalToPseudoIndexMap.AddOrUpdate (enumeratorLocal, pseudoIndex);
3348+
3349+ if (!added)
33473350 {
3348- // We are going to conditionally track accesses to the enumerator local via a pseudo.
3351+ // Seems like we have multiple GDVs that can define this local.
3352+ // Carry on for now, but later we may see these collide
3353+ // and end up not cloning any of them.
33493354 //
3350- const unsigned pseudoIndex = NewPseudoIndex ();
3351- assert (pseudoIndex != BAD_VAR_NUM);
3352- bool added = m_EnumeratorLocalToPseudoIndexMap.AddOrUpdate (enumeratorLocal, pseudoIndex);
3353-
3354- if (!added)
3355- {
3356- // Seems like we have multiple GDVs that can define this local.
3357- // Carry on for now, but later we may see these collide
3358- // and end up not cloning any of them.
3359- //
3360- // Since we are walking in RPO we may also be able to see that
3361- // they are properly disjoint and things will work out just fine.
3362- //
3363- JITDUMP (" Looks like enumerator var re-use (multiple defining GDVs)\n " );
3364- }
3365-
3366- // We will query this info if we see CALL(enumeratorLocal)
3367- // during subsequent analysis, to verify that access is
3368- // under the same guard conditions.
3355+ // Since we are walking in RPO we may also be able to see that
3356+ // they are properly disjoint and things will work out just fine.
33693357 //
3370- CompAllocator alloc (comp->getAllocator (CMK_ObjectAllocator));
3371- CloneInfo* info = new (alloc) CloneInfo ();
3372- info->m_local = enumeratorLocal;
3373- info->m_type = clsHnd;
3374- info->m_pseudoIndex = pseudoIndex;
3375- info->m_appearanceMap = new (alloc) EnumeratorVarMap (alloc);
3376- info->m_allocBlock = block;
3377- info->m_allocStmt = stmt;
3378- info->m_allocTree = data;
3379- info->m_domBlock = controllingGDV.m_block ;
3380- m_CloneMap.Set (pseudoIndex, info);
3381-
3382- JITDUMP (" Enumerator allocation [%06u]: will track accesses to V%02u guarded by type %s via" ,
3383- comp->dspTreeID (data), enumeratorLocal, comp->eeGetClassName (clsHnd));
3384- JITDUMPEXEC (DumpIndex (pseudoIndex));
3385- JITDUMP (" \n " );
3386-
3387- // If this is not a direct assignment to the enumerator var we also need to
3388- // track the temps that will appear in between. Later we will rewrite these
3389- // to a fresh set of temps.
3390- //
3391- if (lclNum != enumeratorLocal)
3392- {
3393- CheckForEnumeratorUse (enumeratorLocal, lclNum);
3394- RecordAppearance (lclNum, block, stmt, use);
3395- }
3358+ JITDUMP (" Looks like enumerator var re-use (multiple defining GDVs)\n " );
33963359 }
3397- else
3360+
3361+ // We will query this info if we see CALL(enumeratorLocal)
3362+ // during subsequent analysis, to verify that access is
3363+ // under the same guard conditions.
3364+ //
3365+ CompAllocator alloc (comp->getAllocator (CMK_ObjectAllocator));
3366+ CloneInfo* info = new (alloc) CloneInfo ();
3367+ info->m_local = enumeratorLocal;
3368+ info->m_type = clsHnd;
3369+ info->m_pseudoIndex = pseudoIndex;
3370+ info->m_appearanceMap = new (alloc) EnumeratorVarMap (alloc);
3371+ info->m_allocBlock = block;
3372+ info->m_allocStmt = stmt;
3373+ info->m_allocTree = data;
3374+ m_CloneMap.Set (pseudoIndex, info);
3375+
3376+ JITDUMP (" Enumerator allocation [%06u]: will track accesses to V%02u guarded by type %s via" ,
3377+ comp->dspTreeID (data), enumeratorLocal, comp->eeGetClassName (clsHnd));
3378+ JITDUMPEXEC (DumpIndex (pseudoIndex));
3379+ JITDUMP (" \n " );
3380+
3381+ // If this is not a direct assignment to the enumerator var we also need to
3382+ // track the temps that will appear in between. Later we will rewrite these
3383+ // to a fresh set of temps.
3384+ //
3385+ if (lclNum != enumeratorLocal)
33983386 {
3399- JITDUMP (
3400- " Enumerator allocation [%06u]: enumerator type %s cannot be stack allocated, so not tracking enumerator local V%02u\n " ,
3401- comp->dspTreeID (data), comp->eeGetClassName (clsHnd), enumeratorLocal);
3387+ CheckForEnumeratorUse (enumeratorLocal, lclNum);
3388+ RecordAppearance (lclNum, block, stmt, use);
34023389 }
34033390 }
34043391 else
34053392 {
3406- // This allocation is not currently of interest
3407- //
3408- JITDUMP ( " Allocation [%06u] was not flagged for conditional escape tracking \n " , comp->dspTreeID (data));
3393+ JITDUMP (
3394+ " Enumerator allocation [%06u]: enumerator type %s cannot be stack allocated, so not tracking enumerator local V%02u \n " ,
3395+ comp->dspTreeID (data), comp-> eeGetClassName (clsHnd), enumeratorLocal );
34093396 }
34103397 }
34113398 else
34123399 {
3413- // This allocation was not done under a GDV guard
3400+ // This allocation is not currently of interest
34143401 //
3415- JITDUMP (" Allocation [%06u] is not under a GDV guard \n " , comp->dspTreeID (data));
3402+ JITDUMP (" Allocation [%06u] was not flagged for conditional escape tracking \n " , comp->dspTreeID (data));
34163403 }
34173404 }
34183405 else if (data->OperIs (GT_LCL_VAR, GT_BOX))
0 commit comments