@@ -992,7 +992,7 @@ int ValueNumStore::EvalComparison(VNFunc vnf, T v0, T v1)
992992//
993993ValueNum ValueNumStore::VNExcSetSingleton (ValueNum x)
994994{
995- return VNForFunc (TYP_REF, VNF_ExcSetCons, x, VNForEmptyExcSet ());
995+ return VNForFuncNoFolding (TYP_REF, VNF_ExcSetCons, x, VNForEmptyExcSet ());
996996}
997997// Create a ValueNumPair for an exception set singleton for 'xp'
998998//
@@ -1071,24 +1071,24 @@ ValueNum ValueNumStore::VNExcSetUnion(ValueNum xs0, ValueNum xs1)
10711071 assert (VNCheckAscending (funcXs0.m_args [0 ], funcXs0.m_args [1 ]));
10721072
10731073 // add the lower one (from xs0) to the result, advance xs0
1074- res = VNForFunc (TYP_REF, VNF_ExcSetCons, funcXs0.m_args [0 ], VNExcSetUnion (funcXs0.m_args [1 ], xs1));
1074+ res = VNForFuncNoFolding (TYP_REF, VNF_ExcSetCons, funcXs0.m_args [0 ], VNExcSetUnion (funcXs0.m_args [1 ], xs1));
10751075 }
10761076 else if (funcXs0.m_args [0 ] == funcXs1.m_args [0 ])
10771077 {
10781078 assert (VNCheckAscending (funcXs0.m_args [0 ], funcXs0.m_args [1 ]));
10791079 assert (VNCheckAscending (funcXs1.m_args [0 ], funcXs1.m_args [1 ]));
10801080
10811081 // Equal elements; add one (from xs0) to the result, advance both sets
1082- res = VNForFunc (TYP_REF, VNF_ExcSetCons, funcXs0.m_args [0 ],
1083- VNExcSetUnion (funcXs0.m_args [1 ], funcXs1.m_args [1 ]));
1082+ res = VNForFuncNoFolding (TYP_REF, VNF_ExcSetCons, funcXs0.m_args [0 ],
1083+ VNExcSetUnion (funcXs0.m_args [1 ], funcXs1.m_args [1 ]));
10841084 }
10851085 else
10861086 {
10871087 assert (funcXs0.m_args [0 ] > funcXs1.m_args [0 ]);
10881088 assert (VNCheckAscending (funcXs1.m_args [0 ], funcXs1.m_args [1 ]));
10891089
10901090 // add the lower one (from xs1) to the result, advance xs1
1091- res = VNForFunc (TYP_REF, VNF_ExcSetCons, funcXs1.m_args [0 ], VNExcSetUnion (xs0, funcXs1.m_args [1 ]));
1091+ res = VNForFuncNoFolding (TYP_REF, VNF_ExcSetCons, funcXs1.m_args [0 ], VNExcSetUnion (xs0, funcXs1.m_args [1 ]));
10921092 }
10931093
10941094 return res;
@@ -1610,7 +1610,7 @@ ValueNum ValueNumStore::VNWithExc(ValueNum vn, ValueNum excSet)
16101610 ValueNum vnNorm;
16111611 ValueNum vnX;
16121612 VNUnpackExc (vn, &vnNorm, &vnX);
1613- return VNForFunc (TypeOfVN (vnNorm), VNF_ValWithExc, vnNorm, VNExcSetUnion (vnX, excSet));
1613+ return VNForFuncNoFolding (TypeOfVN (vnNorm), VNF_ValWithExc, vnNorm, VNExcSetUnion (vnX, excSet));
16141614 }
16151615}
16161616
@@ -2176,7 +2176,7 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
21762176 {
21772177 // In terms of values, a castclass always returns its second argument, the object being cast.
21782178 // The operation may also throw an exception
2179- ValueNum vnExcSet = VNExcSetSingleton (VNForFunc (TYP_REF, VNF_InvalidCastExc, arg1VN, arg0VN));
2179+ ValueNum vnExcSet = VNExcSetSingleton (VNForFuncNoFolding (TYP_REF, VNF_InvalidCastExc, arg1VN, arg0VN));
21802180 resultVN = VNWithExc (arg1VN, vnExcSet);
21812181 }
21822182 else
@@ -2221,6 +2221,51 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
22212221 return resultVN;
22222222}
22232223
2224+ // ----------------------------------------------------------------------------------------
2225+ // VNForFuncNoFolding - Returns the ValueNum associated with
2226+ // 'func'('arg0VN','arg1VN') without doing any folding.
2227+ //
2228+ // Arguments:
2229+ // typ - The type of the resulting ValueNum produced by 'func'
2230+ // func - Any binary VNFunc
2231+ // arg0VN - The ValueNum of the first argument to 'func'
2232+ // arg1VN - The ValueNum of the second argument to 'func'
2233+ //
2234+ // Return Value: - Returns the ValueNum associated with 'func'('arg0VN','arg1VN')
2235+ //
2236+ ValueNum ValueNumStore::VNForFuncNoFolding (var_types typ, VNFunc func, ValueNum arg0VN, ValueNum arg1VN)
2237+ {
2238+ assert (arg0VN != NoVN && arg1VN != NoVN);
2239+
2240+ // Function arguments carry no exceptions.
2241+ assert (arg0VN == VNNormalValue (arg0VN));
2242+ assert (arg1VN == VNNormalValue (arg1VN));
2243+ assert (VNFuncArity (func) == 2 );
2244+
2245+ ValueNum resultVN;
2246+
2247+ // Have we already assigned a ValueNum for 'func'('arg0VN','arg1VN') ?
2248+ //
2249+ VNDefFuncApp<2 > fstruct (func, arg0VN, arg1VN);
2250+ if (!GetVNFunc2Map ()->Lookup (fstruct, &resultVN))
2251+ {
2252+ // Otherwise, Allocate a new ValueNum for 'func'('arg0VN','arg1VN')
2253+ //
2254+ Chunk* const c = GetAllocChunk (typ, CEA_Func2);
2255+ unsigned const offsetWithinChunk = c->AllocVN ();
2256+ VNDefFuncAppFlexible* fapp = c->PointerToFuncApp (offsetWithinChunk, 2 );
2257+ fapp->m_func = func;
2258+ fapp->m_args [0 ] = arg0VN;
2259+ fapp->m_args [1 ] = arg1VN;
2260+ resultVN = c->m_baseVN + offsetWithinChunk;
2261+
2262+ // Record 'resultVN' in the Func2Map
2263+ GetVNFunc2Map ()->Set (fstruct, resultVN);
2264+ }
2265+
2266+ return resultVN;
2267+ }
2268+
22242269// ----------------------------------------------------------------------------------------
22252270// VNForFunc - Returns the ValueNum associated with 'func'('arg0VN','arg1VN','arg2VN')
22262271// There is a one-to-one relationship between the ValueNum
@@ -7571,8 +7616,8 @@ void Compiler::fgValueNumberBlock(BasicBlock* blk)
75717616 }
75727617 else
75737618 {
7574- phiVNP = vnStore->VNPairForFunc (newSsaDef->TypeGet (), VNF_Phi,
7575- ValueNumPair (phiArgSsaNumVN, phiArgSsaNumVN), phiVNP);
7619+ phiVNP = vnStore->VNPairForFuncNoFolding (newSsaDef->TypeGet (), VNF_Phi,
7620+ ValueNumPair (phiArgSsaNumVN, phiArgSsaNumVN), phiVNP);
75767621
75777622 if ((sameVNP.GetLiberal () != phiArgVNP.GetLiberal ()) ||
75787623 (sameVNP.GetConservative () != phiArgVNP.GetConservative ()))
@@ -7681,7 +7726,7 @@ void Compiler::fgValueNumberBlock(BasicBlock* blk)
76817726 unsigned phiArgSSANum = phiArgs->GetSsaNum ();
76827727 ValueNum phiArgSSANumVN = vnStore->VNForIntCon (phiArgSSANum);
76837728 JITDUMP (" Building phi application: $%x = SSA# %d.\n " , phiArgSSANumVN, phiArgSSANum);
7684- phiAppVN = vnStore->VNForFunc (TYP_HEAP, VNF_Phi, phiArgSSANumVN, phiAppVN);
7729+ phiAppVN = vnStore->VNForFuncNoFolding (TYP_HEAP, VNF_Phi, phiArgSSANumVN, phiAppVN);
76857730 JITDUMP (" Building phi application: $%x = phi($%x, $%x).\n " , phiAppVN, phiArgSSANumVN,
76867731 oldPhiAppVN);
76877732 phiArgs = phiArgs->m_nextArg ;
@@ -7692,8 +7737,8 @@ void Compiler::fgValueNumberBlock(BasicBlock* blk)
76927737 }
76937738 else
76947739 {
7695- newMemoryVN = vnStore->VNForFunc (TYP_HEAP, VNF_PhiMemoryDef,
7696- vnStore->VNForHandle (ssize_t (blk), GTF_EMPTY), phiAppVN);
7740+ newMemoryVN = vnStore->VNForFuncNoFolding (TYP_HEAP, VNF_PhiMemoryDef,
7741+ vnStore->VNForHandle (ssize_t (blk), GTF_EMPTY), phiAppVN);
76977742 }
76987743 }
76997744 GetMemoryPerSsaData (blk->bbMemorySsaNumIn [memoryKind])->m_vnPair .SetLiberal (newMemoryVN);
@@ -10659,13 +10704,13 @@ void Compiler::fgValueNumberAddExceptionSetForDivision(GenTree* tree)
1065910704 }
1066010705 if (needArithmeticExcLib)
1066110706 {
10662- vnpArithmExc.SetLiberal (
10663- vnStore->VNExcSetSingleton (vnStore-> VNForFunc (TYP_REF, VNF_ArithmeticExc, vnOp1NormLib, vnOp2NormLib)));
10707+ vnpArithmExc.SetLiberal (vnStore-> VNExcSetSingleton (
10708+ vnStore->VNForFuncNoFolding (TYP_REF, VNF_ArithmeticExc, vnOp1NormLib, vnOp2NormLib)));
1066410709 }
1066510710 if (needArithmeticExcCon)
1066610711 {
10667- vnpArithmExc.SetConservative (
10668- vnStore->VNExcSetSingleton (vnStore-> VNForFunc (TYP_REF, VNF_ArithmeticExc, vnOp1NormLib, vnOp2NormCon)));
10712+ vnpArithmExc.SetConservative (vnStore-> VNExcSetSingleton (
10713+ vnStore->VNForFuncNoFolding (TYP_REF, VNF_ArithmeticExc, vnOp1NormLib, vnOp2NormCon)));
1066910714 }
1067010715
1067110716 // Combine vnpDivZeroExc with the exception set of tree
@@ -10776,8 +10821,8 @@ void Compiler::fgValueNumberAddExceptionSetForBoundsCheck(GenTree* tree)
1077610821
1077710822 // Construct the exception set for bounds check
1077810823 ValueNumPair boundsChkExcSet = vnStore->VNPExcSetSingleton (
10779- vnStore->VNPairForFunc (TYP_REF, VNF_IndexOutOfRangeExc, vnStore->VNPNormalPair (vnpIndex),
10780- vnStore->VNPNormalPair (vnpArrLen)));
10824+ vnStore->VNPairForFuncNoFolding (TYP_REF, VNF_IndexOutOfRangeExc, vnStore->VNPNormalPair (vnpIndex),
10825+ vnStore->VNPNormalPair (vnpArrLen)));
1078110826
1078210827 // Combine the new Overflow exception with the original exception set of tree
1078310828 ValueNumPair newExcSet = vnStore->VNPExcSetUnion (vnpTreeExc, boundsChkExcSet);
0 commit comments