@@ -1793,21 +1793,16 @@ ValueNumStore::Chunk* ValueNumStore::GetAllocChunk(var_types typ, ChunkExtraAttr
17931793template <typename T, typename NumMap>
17941794ValueNum ValueNumStore::VnForConst (T cnsVal, NumMap* numMap, var_types varType)
17951795{
1796- ValueNum res;
1797- if (numMap->Lookup (cnsVal, &res))
1798- {
1799- return res;
1800- }
1801- else
1796+ ValueNum* res = numMap->LookupPointerOrAdd (cnsVal, NoVN);
1797+ if (*res == NoVN)
18021798 {
18031799 Chunk* chunk = GetAllocChunk (varType, CEA_Const);
18041800 unsigned offsetWithinChunk = chunk->AllocVN ();
1805- res = chunk->m_baseVN + offsetWithinChunk;
1801+ * res = chunk->m_baseVN + offsetWithinChunk;
18061802 T* chunkDefs = reinterpret_cast <T*>(chunk->m_defs );
18071803 chunkDefs[offsetWithinChunk] = cnsVal;
1808- numMap->Set (cnsVal, res);
1809- return res;
18101804 }
1805+ return *res;
18111806}
18121807
18131808ValueNum ValueNumStore::VNForIntCon (INT32 cnsVal)
@@ -2046,12 +2041,12 @@ ValueNum ValueNumStore::VNForHandle(ssize_t cnsVal, GenTreeFlags handleFlags)
20462041{
20472042 assert ((handleFlags & ~GTF_ICON_HDL_MASK) == 0 );
20482043
2049- ValueNum res;
20502044 VNHandle handle;
20512045 VNHandle::Initialize (&handle, cnsVal, handleFlags);
2052- if (GetHandleMap ()->Lookup (handle, &res))
2046+ ValueNum* res = GetHandleMap ()->LookupPointerOrAdd (handle, NoVN);
2047+ if (*res != NoVN)
20532048 {
2054- return res;
2049+ return * res;
20552050 }
20562051
20572052 var_types type = Compiler::gtGetTypeForIconFlags (handleFlags);
@@ -2060,10 +2055,9 @@ ValueNum ValueNumStore::VNForHandle(ssize_t cnsVal, GenTreeFlags handleFlags)
20602055 VNHandle* const chunkSlots = reinterpret_cast <VNHandle*>(c->m_defs );
20612056
20622057 chunkSlots[offsetWithinChunk] = handle;
2063- res = c->m_baseVN + offsetWithinChunk;
2058+ * res = c->m_baseVN + offsetWithinChunk;
20642059
2065- GetHandleMap ()->Set (handle, res);
2066- return res;
2060+ return *res;
20672061}
20682062
20692063ValueNum ValueNumStore::VNZeroForType (var_types typ)
@@ -2507,22 +2501,20 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func)
25072501{
25082502 assert (VNFuncArity (func) == 0 );
25092503
2510- ValueNum resultVN;
2511-
25122504 // Have we already assigned a ValueNum for 'func' ?
25132505 //
2514- if (!GetVNFunc0Map ()->Lookup (func, &resultVN))
2506+ ValueNum* resultVN = GetVNFunc0Map ()->LookupPointerOrAdd (func, NoVN);
2507+ if (*resultVN == NoVN)
25152508 {
25162509 // Allocate a new ValueNum for 'func'
25172510 Chunk* const c = GetAllocChunk (typ, CEA_Func0);
25182511 unsigned const offsetWithinChunk = c->AllocVN ();
25192512 VNFunc* const chunkSlots = reinterpret_cast <VNFunc*>(c->m_defs );
25202513
25212514 chunkSlots[offsetWithinChunk] = func;
2522- resultVN = c->m_baseVN + offsetWithinChunk;
2523- GetVNFunc0Map ()->Set (func, resultVN);
2515+ *resultVN = c->m_baseVN + offsetWithinChunk;
25242516 }
2525- return resultVN;
2517+ return * resultVN;
25262518}
25272519
25282520// ----------------------------------------------------------------------------------------
@@ -2544,16 +2536,11 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN)
25442536 assert (func != VNF_MemOpaque);
25452537 assert (arg0VN == VNNormalValue (arg0VN)); // Arguments don't carry exceptions.
25462538
2547- ValueNum resultVN = NoVN;
2548-
25492539 // Have we already assigned a ValueNum for 'func'('arg0VN') ?
25502540 //
25512541 VNDefFuncApp<1 > fstruct (func, arg0VN);
2552- if (GetVNFunc1Map ()->Lookup (fstruct, &resultVN))
2553- {
2554- assert (resultVN != NoVN);
2555- }
2556- else
2542+ ValueNum* resultVN = GetVNFunc1Map ()->LookupPointerOrAdd (fstruct, NoVN);
2543+ if (*resultVN == NoVN)
25572544 {
25582545 // Check if we can fold GT_ARR_LENGTH on top of a known array (immutable)
25592546 if (func == VNFunc (GT_ARR_LENGTH))
@@ -2566,13 +2553,13 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN)
25662553 int len = m_pComp->info .compCompHnd ->getArrayOrStringLength ((CORINFO_OBJECT_HANDLE)handle);
25672554 if (len >= 0 )
25682555 {
2569- resultVN = VNForIntCon (len);
2556+ * resultVN = VNForIntCon (len);
25702557 }
25712558 }
25722559
25732560 // Case 2: ARR_LENGTH(static-readonly-field)
25742561 VNFuncApp funcApp;
2575- if ((resultVN == NoVN) && GetVNFunc (addressVN, &funcApp) && (funcApp.m_func == VNF_InvariantNonNullLoad))
2562+ if ((* resultVN == NoVN) && GetVNFunc (addressVN, &funcApp) && (funcApp.m_func == VNF_InvariantNonNullLoad))
25762563 {
25772564 ValueNum fieldSeqVN = VNNormalValue (funcApp.m_args [0 ]);
25782565 if (IsVNHandle (fieldSeqVN, GTF_ICON_FIELD_SEQ))
@@ -2595,7 +2582,7 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN)
25952582 int len = m_pComp->info .compCompHnd ->getArrayOrStringLength (objHandle);
25962583 if (len >= 0 )
25972584 {
2598- resultVN = VNForIntCon (len);
2585+ * resultVN = VNForIntCon (len);
25992586 }
26002587 }
26012588 }
@@ -2606,36 +2593,33 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN)
26062593 // Case 3: ARR_LENGTH(new T[cns])
26072594 // TODO: Add support for MD arrays
26082595 int knownSize;
2609- if ((resultVN == NoVN) && TryGetNewArrSize (addressVN, &knownSize))
2596+ if ((* resultVN == NoVN) && TryGetNewArrSize (addressVN, &knownSize))
26102597 {
2611- resultVN = VNForIntCon (knownSize);
2598+ * resultVN = VNForIntCon (knownSize);
26122599 }
26132600 }
26142601
26152602 // Try to perform constant-folding.
26162603 //
2617- if ((resultVN == NoVN) && VNEvalCanFoldUnaryFunc (typ, func, arg0VN))
2604+ if ((* resultVN == NoVN) && VNEvalCanFoldUnaryFunc (typ, func, arg0VN))
26182605 {
2619- resultVN = EvalFuncForConstantArgs (typ, func, arg0VN);
2606+ * resultVN = EvalFuncForConstantArgs (typ, func, arg0VN);
26202607 }
26212608
26222609 // Otherwise, Allocate a new ValueNum for 'func'('arg0VN')
26232610 //
2624- if (resultVN == NoVN)
2611+ if (* resultVN == NoVN)
26252612 {
26262613 Chunk* const c = GetAllocChunk (typ, CEA_Func1);
26272614 unsigned const offsetWithinChunk = c->AllocVN ();
26282615 VNDefFuncAppFlexible* fapp = c->PointerToFuncApp (offsetWithinChunk, 1 );
26292616 fapp->m_func = func;
26302617 fapp->m_args [0 ] = arg0VN;
2631- resultVN = c->m_baseVN + offsetWithinChunk;
2618+ * resultVN = c->m_baseVN + offsetWithinChunk;
26322619 }
2633-
2634- // Record 'resultVN' in the Func1Map
2635- //
2636- GetVNFunc1Map ()->Set (fstruct, resultVN);
26372620 }
2638- return resultVN;
2621+
2622+ return *resultVN;
26392623}
26402624
26412625// ----------------------------------------------------------------------------------------
@@ -2744,8 +2728,6 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
27442728 assert ((VNFuncArity (func) == 0 ) || (VNFuncArity (func) == 2 ));
27452729 assert (func != VNF_MapSelect); // Precondition: use the special function VNForMapSelect defined for that.
27462730
2747- ValueNum resultVN = NoVN;
2748-
27492731 // Even if the argVNs differ, if both operands runtime types constructed from handles,
27502732 // we can sometimes also fold.
27512733 //
@@ -2755,7 +2737,7 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
27552737 const genTreeOps oper = genTreeOps (func);
27562738 if ((arg0VN != arg1VN) && GenTree::StaticOperIs (oper, GT_EQ, GT_NE))
27572739 {
2758- resultVN = VNEvalFoldTypeCompare (typ, func, arg0VN, arg1VN);
2740+ ValueNum resultVN = VNEvalFoldTypeCompare (typ, func, arg0VN, arg1VN);
27592741 if (resultVN != NoVN)
27602742 {
27612743 return resultVN;
@@ -2776,15 +2758,13 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
27762758 // Have we already assigned a ValueNum for 'func'('arg0VN','arg1VN') ?
27772759 //
27782760 VNDefFuncApp<2 > fstruct (func, arg0VN, arg1VN);
2779- if (GetVNFunc2Map ()->Lookup (fstruct, &resultVN))
2780- {
2781- assert (resultVN != NoVN);
2782- }
2783- else
2761+
2762+ ValueNum* resultVN = GetVNFunc2Map ()->LookupPointerOrAdd (fstruct, NoVN);
2763+ if (*resultVN == NoVN)
27842764 {
27852765 if ((func == VNF_CastClass) || (func == VNF_IsInstanceOf))
27862766 {
2787- resultVN = VNForCast (func, arg0VN, arg1VN);
2767+ * resultVN = VNForCast (func, arg0VN, arg1VN);
27882768 }
27892769 else
27902770 {
@@ -2795,20 +2775,20 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
27952775 bool folded = false ;
27962776 if (VNEvalCanFoldBinaryFunc (typ, func, arg0VN, arg1VN) && VNEvalShouldFold (typ, func, arg0VN, arg1VN))
27972777 {
2798- resultVN = EvalFuncForConstantArgs (typ, func, arg0VN, arg1VN);
2778+ * resultVN = EvalFuncForConstantArgs (typ, func, arg0VN, arg1VN);
27992779 }
28002780
2801- if (resultVN != NoVN)
2781+ if (* resultVN != NoVN)
28022782 {
28032783 folded = true ;
28042784 }
28052785 else
28062786 {
2807- resultVN = EvalUsingMathIdentity (typ, func, arg0VN, arg1VN);
2787+ * resultVN = EvalUsingMathIdentity (typ, func, arg0VN, arg1VN);
28082788 }
28092789
28102790 // Do we have a valid resultVN?
2811- if ((resultVN == NoVN) || (!folded && (genActualType (TypeOfVN (resultVN)) != genActualType (typ))))
2791+ if ((* resultVN == NoVN) || (!folded && (genActualType (TypeOfVN (* resultVN)) != genActualType (typ))))
28122792 {
28132793 // Otherwise, Allocate a new ValueNum for 'func'('arg0VN','arg1VN')
28142794 //
@@ -2818,14 +2798,11 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
28182798 fapp->m_func = func;
28192799 fapp->m_args [0 ] = arg0VN;
28202800 fapp->m_args [1 ] = arg1VN;
2821- resultVN = c->m_baseVN + offsetWithinChunk;
2801+ * resultVN = c->m_baseVN + offsetWithinChunk;
28222802 }
28232803 }
2824-
2825- // Record 'resultVN' in the Func2Map
2826- GetVNFunc2Map ()->Set (fstruct, resultVN);
28272804 }
2828- return resultVN;
2805+ return * resultVN;
28292806}
28302807
28312808// ----------------------------------------------------------------------------------------
@@ -2849,12 +2826,11 @@ ValueNum ValueNumStore::VNForFuncNoFolding(var_types typ, VNFunc func, ValueNum
28492826 assert (arg1VN == VNNormalValue (arg1VN));
28502827 assert (VNFuncArity (func) == 2 );
28512828
2852- ValueNum resultVN;
2853-
28542829 // Have we already assigned a ValueNum for 'func'('arg0VN','arg1VN') ?
28552830 //
28562831 VNDefFuncApp<2 > fstruct (func, arg0VN, arg1VN);
2857- if (!GetVNFunc2Map ()->Lookup (fstruct, &resultVN))
2832+ ValueNum* resultVN = GetVNFunc2Map ()->LookupPointerOrAdd (fstruct, NoVN);
2833+ if (*resultVN == NoVN)
28582834 {
28592835 // Otherwise, Allocate a new ValueNum for 'func'('arg0VN','arg1VN')
28602836 //
@@ -2864,13 +2840,10 @@ ValueNum ValueNumStore::VNForFuncNoFolding(var_types typ, VNFunc func, ValueNum
28642840 fapp->m_func = func;
28652841 fapp->m_args [0 ] = arg0VN;
28662842 fapp->m_args [1 ] = arg1VN;
2867- resultVN = c->m_baseVN + offsetWithinChunk;
2868-
2869- // Record 'resultVN' in the Func2Map
2870- GetVNFunc2Map ()->Set (fstruct, resultVN);
2843+ *resultVN = c->m_baseVN + offsetWithinChunk;
28712844 }
28722845
2873- return resultVN;
2846+ return * resultVN;
28742847}
28752848
28762849// ----------------------------------------------------------------------------------------
@@ -2913,12 +2886,12 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
29132886 assert (arg2VN == VNNormalValue (arg2VN));
29142887#endif
29152888
2916- ValueNum resultVN;
2917-
29182889 // Have we already assigned a ValueNum for 'func'('arg0VN','arg1VN','arg2VN') ?
29192890 //
29202891 VNDefFuncApp<3 > fstruct (func, arg0VN, arg1VN, arg2VN);
2921- if (!GetVNFunc3Map ()->Lookup (fstruct, &resultVN))
2892+ ValueNum* resultVN = GetVNFunc3Map ()->LookupPointerOrAdd (fstruct, NoVN);
2893+
2894+ if (*resultVN == NoVN)
29222895 {
29232896 // Otherwise, Allocate a new ValueNum for 'func'('arg0VN','arg1VN','arg2VN')
29242897 //
@@ -2929,12 +2902,9 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
29292902 fapp->m_args [0 ] = arg0VN;
29302903 fapp->m_args [1 ] = arg1VN;
29312904 fapp->m_args [2 ] = arg2VN;
2932- resultVN = c->m_baseVN + offsetWithinChunk;
2933-
2934- // Record 'resultVN' in the Func3Map
2935- GetVNFunc3Map ()->Set (fstruct, resultVN);
2905+ *resultVN = c->m_baseVN + offsetWithinChunk;
29362906 }
2937- return resultVN;
2907+ return * resultVN;
29382908}
29392909
29402910// ----------------------------------------------------------------------------------------
@@ -2966,12 +2936,12 @@ ValueNum ValueNumStore::VNForFunc(
29662936 assert ((func == VNF_MapStore) || (arg3VN == VNNormalValue (arg3VN)));
29672937 assert (VNFuncArity (func) == 4 );
29682938
2969- ValueNum resultVN;
2970-
29712939 // Have we already assigned a ValueNum for 'func'('arg0VN','arg1VN','arg2VN','arg3VN') ?
29722940 //
29732941 VNDefFuncApp<4 > fstruct (func, arg0VN, arg1VN, arg2VN, arg3VN);
2974- if (!GetVNFunc4Map ()->Lookup (fstruct, &resultVN))
2942+ ValueNum* resultVN = GetVNFunc4Map ()->LookupPointerOrAdd (fstruct, NoVN);
2943+
2944+ if (*resultVN == NoVN)
29752945 {
29762946 // Otherwise, Allocate a new ValueNum for 'func'('arg0VN','arg1VN','arg2VN','arg3VN')
29772947 //
@@ -2983,12 +2953,9 @@ ValueNum ValueNumStore::VNForFunc(
29832953 fapp->m_args [1 ] = arg1VN;
29842954 fapp->m_args [2 ] = arg2VN;
29852955 fapp->m_args [3 ] = arg3VN;
2986- resultVN = c->m_baseVN + offsetWithinChunk;
2987-
2988- // Record 'resultVN' in the Func4Map
2989- GetVNFunc4Map ()->Set (fstruct, resultVN);
2956+ *resultVN = c->m_baseVN + offsetWithinChunk;
29902957 }
2991- return resultVN;
2958+ return * resultVN;
29922959}
29932960
29942961// ------------------------------------------------------------------------------
0 commit comments