@@ -1686,16 +1686,16 @@ ValueNumStore::Chunk::Chunk(CompAllocator alloc, ValueNum* pNextBaseVN, var_type
1686
1686
break ;
1687
1687
1688
1688
case CEA_Func1:
1689
- m_defs = new (alloc) VNDefFunc1Arg[ ChunkSize] ;
1689
+ m_defs = alloc. allocate < char >(( sizeof (VNDefFuncAppFlexible) + sizeof (ValueNum) * 1 ) * ChunkSize) ;
1690
1690
break ;
1691
1691
case CEA_Func2:
1692
- m_defs = new (alloc) VNDefFunc2Arg[ ChunkSize] ;
1692
+ m_defs = alloc. allocate < char >(( sizeof (VNDefFuncAppFlexible) + sizeof (ValueNum) * 2 ) * ChunkSize) ;
1693
1693
break ;
1694
1694
case CEA_Func3:
1695
- m_defs = new (alloc) VNDefFunc3Arg[ ChunkSize] ;
1695
+ m_defs = alloc. allocate < char >(( sizeof (VNDefFuncAppFlexible) + sizeof (ValueNum) * 3 ) * ChunkSize) ;
1696
1696
break ;
1697
1697
case CEA_Func4:
1698
- m_defs = new (alloc) VNDefFunc4Arg[ ChunkSize] ;
1698
+ m_defs = alloc. allocate < char >(( sizeof (VNDefFuncAppFlexible) + sizeof (ValueNum) * 4 ) * ChunkSize) ;
1699
1699
break ;
1700
1700
default :
1701
1701
unreached ();
@@ -2009,17 +2009,17 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN)
2009
2009
ValueNum resultVN;
2010
2010
2011
2011
// Have we already assigned a ValueNum for 'func'('arg0VN') ?
2012
- VNDefFunc1Arg fstruct (func, arg0VN);
2012
+ VNDefFuncApp< 1 > fstruct (func, arg0VN);
2013
2013
if (!GetVNFunc1Map ()->Lookup (fstruct, &resultVN))
2014
2014
{
2015
2015
// Otherwise, Allocate a new ValueNum for 'func'('arg0VN')
2016
2016
//
2017
- Chunk* const c = GetAllocChunk (typ, CEA_Func1);
2018
- unsigned const offsetWithinChunk = c->AllocVN ();
2019
- VNDefFunc1Arg* const chunkSlots = reinterpret_cast <VNDefFunc1Arg*>( c->m_defs );
2020
-
2021
- chunkSlots[offsetWithinChunk] = fstruct ;
2022
- resultVN = c->m_baseVN + offsetWithinChunk;
2017
+ Chunk* const c = GetAllocChunk (typ, CEA_Func1);
2018
+ unsigned const offsetWithinChunk = c->AllocVN ();
2019
+ VNDefFuncAppFlexible* fapp = c->PointerToFuncApp (offsetWithinChunk, 1 );
2020
+ fapp-> m_func = func;
2021
+ fapp-> m_args [ 0 ] = arg0VN ;
2022
+ resultVN = c->m_baseVN + offsetWithinChunk;
2023
2023
2024
2024
// Record 'resultVN' in the Func1Map
2025
2025
GetVNFunc1Map ()->Set (fstruct, resultVN);
@@ -2117,7 +2117,7 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
2117
2117
2118
2118
// Have we already assigned a ValueNum for 'func'('arg0VN','arg1VN') ?
2119
2119
//
2120
- VNDefFunc2Arg fstruct (func, arg0VN, arg1VN);
2120
+ VNDefFuncApp< 2 > fstruct (func, arg0VN, arg1VN);
2121
2121
if (!GetVNFunc2Map ()->Lookup (fstruct, &resultVN))
2122
2122
{
2123
2123
if (func == VNF_CastClass)
@@ -2136,12 +2136,13 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
2136
2136
{
2137
2137
// Otherwise, Allocate a new ValueNum for 'func'('arg0VN','arg1VN')
2138
2138
//
2139
- Chunk* const c = GetAllocChunk (typ, CEA_Func2);
2140
- unsigned const offsetWithinChunk = c->AllocVN ();
2141
- VNDefFunc2Arg* const chunkSlots = reinterpret_cast <VNDefFunc2Arg*>(c->m_defs );
2142
-
2143
- chunkSlots[offsetWithinChunk] = fstruct;
2144
- resultVN = c->m_baseVN + offsetWithinChunk;
2139
+ Chunk* const c = GetAllocChunk (typ, CEA_Func2);
2140
+ unsigned const offsetWithinChunk = c->AllocVN ();
2141
+ VNDefFuncAppFlexible* fapp = c->PointerToFuncApp (offsetWithinChunk, 2 );
2142
+ fapp->m_func = func;
2143
+ fapp->m_args [0 ] = arg0VN;
2144
+ fapp->m_args [1 ] = arg1VN;
2145
+ resultVN = c->m_baseVN + offsetWithinChunk;
2145
2146
// Record 'resultVN' in the Func2Map
2146
2147
GetVNFunc2Map ()->Set (fstruct, resultVN);
2147
2148
}
@@ -2194,17 +2195,19 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
2194
2195
2195
2196
// Have we already assigned a ValueNum for 'func'('arg0VN','arg1VN','arg2VN') ?
2196
2197
//
2197
- VNDefFunc3Arg fstruct (func, arg0VN, arg1VN, arg2VN);
2198
+ VNDefFuncApp< 3 > fstruct (func, arg0VN, arg1VN, arg2VN);
2198
2199
if (!GetVNFunc3Map ()->Lookup (fstruct, &resultVN))
2199
2200
{
2200
2201
// Otherwise, Allocate a new ValueNum for 'func'('arg0VN','arg1VN','arg2VN')
2201
2202
//
2202
- Chunk* const c = GetAllocChunk (typ, CEA_Func3);
2203
- unsigned const offsetWithinChunk = c->AllocVN ();
2204
- VNDefFunc3Arg* const chunkSlots = reinterpret_cast <VNDefFunc3Arg*>(c->m_defs );
2205
-
2206
- chunkSlots[offsetWithinChunk] = fstruct;
2207
- resultVN = c->m_baseVN + offsetWithinChunk;
2203
+ Chunk* const c = GetAllocChunk (typ, CEA_Func3);
2204
+ unsigned const offsetWithinChunk = c->AllocVN ();
2205
+ VNDefFuncAppFlexible* fapp = c->PointerToFuncApp (offsetWithinChunk, 3 );
2206
+ fapp->m_func = func;
2207
+ fapp->m_args [0 ] = arg0VN;
2208
+ fapp->m_args [1 ] = arg1VN;
2209
+ fapp->m_args [2 ] = arg2VN;
2210
+ resultVN = c->m_baseVN + offsetWithinChunk;
2208
2211
2209
2212
// Record 'resultVN' in the Func3Map
2210
2213
GetVNFunc3Map ()->Set (fstruct, resultVN);
@@ -2245,17 +2248,20 @@ ValueNum ValueNumStore::VNForFunc(
2245
2248
2246
2249
// Have we already assigned a ValueNum for 'func'('arg0VN','arg1VN','arg2VN','arg3VN') ?
2247
2250
//
2248
- VNDefFunc4Arg fstruct (func, arg0VN, arg1VN, arg2VN, arg3VN);
2251
+ VNDefFuncApp< 4 > fstruct (func, arg0VN, arg1VN, arg2VN, arg3VN);
2249
2252
if (!GetVNFunc4Map ()->Lookup (fstruct, &resultVN))
2250
2253
{
2251
2254
// Otherwise, Allocate a new ValueNum for 'func'('arg0VN','arg1VN','arg2VN','arg3VN')
2252
2255
//
2253
- Chunk* const c = GetAllocChunk (typ, CEA_Func4);
2254
- unsigned const offsetWithinChunk = c->AllocVN ();
2255
- VNDefFunc4Arg* const chunkSlots = reinterpret_cast <VNDefFunc4Arg*>(c->m_defs );
2256
-
2257
- chunkSlots[offsetWithinChunk] = fstruct;
2258
- resultVN = c->m_baseVN + offsetWithinChunk;
2256
+ Chunk* const c = GetAllocChunk (typ, CEA_Func4);
2257
+ unsigned const offsetWithinChunk = c->AllocVN ();
2258
+ VNDefFuncAppFlexible* fapp = c->PointerToFuncApp (offsetWithinChunk, 4 );
2259
+ fapp->m_func = func;
2260
+ fapp->m_args [0 ] = arg0VN;
2261
+ fapp->m_args [1 ] = arg1VN;
2262
+ fapp->m_args [2 ] = arg2VN;
2263
+ fapp->m_args [3 ] = arg3VN;
2264
+ resultVN = c->m_baseVN + offsetWithinChunk;
2259
2265
2260
2266
// Record 'resultVN' in the Func4Map
2261
2267
GetVNFunc4Map ()->Set (fstruct, resultVN);
@@ -2375,7 +2381,7 @@ ValueNum ValueNumStore::VNForMapSelectWork(
2375
2381
#endif
2376
2382
ValueNum res;
2377
2383
2378
- VNDefFunc2Arg fstruct (VNF_MapSelect, map, index);
2384
+ VNDefFuncApp< 2 > fstruct (VNF_MapSelect, map, index);
2379
2385
if (GetVNFunc2Map ()->Lookup (fstruct, &res))
2380
2386
{
2381
2387
return res;
@@ -2462,7 +2468,7 @@ ValueNum ValueNumStore::VNForMapSelectWork(
2462
2468
// Get the first argument of the phi.
2463
2469
2464
2470
// We need to be careful about breaking infinite recursion. Record the outer select.
2465
- m_fixedPointMapSels.Push (VNDefFunc2Arg (VNF_MapSelect, map, index));
2471
+ m_fixedPointMapSels.Push (VNDefFuncApp< 2 > (VNF_MapSelect, map, index));
2466
2472
2467
2473
assert (IsVNConstant (phiFuncApp.m_args [0 ]));
2468
2474
unsigned phiArgSsaNum = ConstantValue<unsigned >(phiFuncApp.m_args [0 ]);
@@ -2580,12 +2586,13 @@ ValueNum ValueNumStore::VNForMapSelectWork(
2580
2586
if (!GetVNFunc2Map ()->Lookup (fstruct, &res))
2581
2587
{
2582
2588
// Otherwise, assign a new VN for the function application.
2583
- Chunk* const c = GetAllocChunk (type, CEA_Func2);
2584
- unsigned const offsetWithinChunk = c->AllocVN ();
2585
- VNDefFunc2Arg* const chunkSlots = reinterpret_cast <VNDefFunc2Arg*>(c->m_defs );
2586
-
2587
- chunkSlots[offsetWithinChunk] = fstruct;
2588
- res = c->m_baseVN + offsetWithinChunk;
2589
+ Chunk* const c = GetAllocChunk (type, CEA_Func2);
2590
+ unsigned const offsetWithinChunk = c->AllocVN ();
2591
+ VNDefFuncAppFlexible* fapp = c->PointerToFuncApp (offsetWithinChunk, 2 );
2592
+ fapp->m_func = fstruct.m_func ;
2593
+ fapp->m_args [0 ] = fstruct.m_args [0 ];
2594
+ fapp->m_args [1 ] = fstruct.m_args [1 ];
2595
+ res = c->m_baseVN + offsetWithinChunk;
2589
2596
2590
2597
GetVNFunc2Map ()->Set (fstruct, res);
2591
2598
}
@@ -2697,25 +2704,72 @@ bool ValueNumStore::SelectIsBeingEvaluatedRecursively(ValueNum map, ValueNum ind
2697
2704
{
2698
2705
for (unsigned i = 0 ; i < m_fixedPointMapSels.Size (); i++)
2699
2706
{
2700
- VNDefFunc2Arg & elem = m_fixedPointMapSels.GetRef (i);
2707
+ VNDefFuncApp< 2 > & elem = m_fixedPointMapSels.GetRef (i);
2701
2708
assert (elem.m_func == VNF_MapSelect);
2702
- if (elem.m_arg0 == map && elem.m_arg1 == ind)
2709
+ if (elem.m_args [ 0 ] == map && elem.m_args [ 1 ] == ind)
2703
2710
{
2704
2711
return true ;
2705
2712
}
2706
2713
}
2707
2714
return false ;
2708
2715
}
2709
2716
2717
+ // Specialized here as MSVC does not do well with naive version with loop.
2718
+ template <>
2719
+ bool ValueNumStore::VNDefFuncApp<1 >::operator ==(const ValueNumStore::VNDefFuncApp<1 >& y) const
2720
+ {
2721
+ return m_func == y.m_func && m_args[0 ] == y.m_args [0 ];
2722
+ }
2723
+
2724
+ template <>
2725
+ bool ValueNumStore::VNDefFuncApp<2 >::operator ==(const ValueNumStore::VNDefFuncApp<2 >& y) const
2726
+ {
2727
+ return m_func == y.m_func && m_args[0 ] == y.m_args [0 ] && m_args[1 ] == y.m_args [1 ];
2728
+ }
2729
+
2730
+ template <>
2731
+ bool ValueNumStore::VNDefFuncApp<3 >::operator ==(const ValueNumStore::VNDefFuncApp<3 >& y) const
2732
+ {
2733
+ return m_func == y.m_func && m_args[0 ] == y.m_args [0 ] && m_args[1 ] == y.m_args [1 ] && m_args[2 ] == y.m_args [2 ];
2734
+ }
2735
+
2736
+ template <>
2737
+ bool ValueNumStore::VNDefFuncApp<4 >::operator ==(const ValueNumStore::VNDefFuncApp<4 >& y) const
2738
+ {
2739
+ return m_func == y.m_func && m_args[0 ] == y.m_args [0 ] && m_args[1 ] == y.m_args [1 ] && m_args[2 ] == y.m_args [2 ] &&
2740
+ m_args[3 ] == y.m_args [3 ];
2741
+ }
2742
+
2743
+ template <>
2744
+ unsigned ValueNumStore::VNDefFuncAppKeyFuncs<1 >::GetHashCode(const ValueNumStore::VNDefFuncApp<1 >& val)
2745
+ {
2746
+ return (val.m_func << 24 ) + val.m_args [0 ];
2747
+ }
2748
+ template <>
2749
+ unsigned ValueNumStore::VNDefFuncAppKeyFuncs<2 >::GetHashCode(const ValueNumStore::VNDefFuncApp<2 >& val)
2750
+ {
2751
+ return (val.m_func << 24 ) + (val.m_args [0 ] << 8 ) + val.m_args [1 ];
2752
+ }
2753
+ template <>
2754
+ unsigned ValueNumStore::VNDefFuncAppKeyFuncs<3 >::GetHashCode(const ValueNumStore::VNDefFuncApp<3 >& val)
2755
+ {
2756
+ return (val.m_func << 24 ) + (val.m_args [0 ] << 16 ) + (val.m_args [1 ] << 8 ) + val.m_args [2 ];
2757
+ }
2758
+ template <>
2759
+ unsigned ValueNumStore::VNDefFuncAppKeyFuncs<4 >::GetHashCode(const ValueNumStore::VNDefFuncApp<4 >& val)
2760
+ {
2761
+ return (val.m_func << 24 ) + (val.m_args [0 ] << 16 ) + (val.m_args [1 ] << 8 ) + val.m_args [2 ] + (val.m_args [3 ] << 12 );
2762
+ }
2763
+
2710
2764
#ifdef DEBUG
2711
2765
bool ValueNumStore::FixedPointMapSelsTopHasValue (ValueNum map, ValueNum index)
2712
2766
{
2713
2767
if (m_fixedPointMapSels.Size () == 0 )
2714
2768
{
2715
2769
return false ;
2716
2770
}
2717
- VNDefFunc2Arg & top = m_fixedPointMapSels.TopRef ();
2718
- return top.m_func == VNF_MapSelect && top.m_arg0 == map && top.m_arg1 == index;
2771
+ VNDefFuncApp< 2 > & top = m_fixedPointMapSels.TopRef ();
2772
+ return top.m_func == VNF_MapSelect && top.m_args [ 0 ] == map && top.m_args [ 1 ] == index;
2719
2773
}
2720
2774
#endif
2721
2775
@@ -3916,12 +3970,11 @@ ValueNum ValueNumStore::VNForExpr(BasicBlock* block, var_types typ)
3916
3970
3917
3971
// VNForFunc(typ, func, vn) but bypasses looking in the cache
3918
3972
//
3919
- VNDefFunc1Arg fstruct (VNF_MemOpaque, loopNum);
3920
- Chunk* const c = GetAllocChunk (typ, CEA_Func1);
3921
- unsigned const offsetWithinChunk = c->AllocVN ();
3922
- VNDefFunc1Arg* const chunkSlots = reinterpret_cast <VNDefFunc1Arg*>(c->m_defs );
3923
-
3924
- chunkSlots[offsetWithinChunk] = fstruct;
3973
+ Chunk* const c = GetAllocChunk (typ, CEA_Func1);
3974
+ unsigned const offsetWithinChunk = c->AllocVN ();
3975
+ VNDefFuncAppFlexible* fapp = c->PointerToFuncApp (offsetWithinChunk, 1 );
3976
+ fapp->m_func = VNF_MemOpaque;
3977
+ fapp->m_args [0 ] = loopNum;
3925
3978
3926
3979
ValueNum resultVN = c->m_baseVN + offsetWithinChunk;
3927
3980
return resultVN;
@@ -5916,56 +5969,19 @@ bool ValueNumStore::GetVNFunc(ValueNum vn, VNFuncApp* funcApp)
5916
5969
Chunk* c = m_chunks.GetNoExpand (GetChunkNum (vn));
5917
5970
unsigned offset = ChunkOffset (vn);
5918
5971
assert (offset < c->m_numUsed );
5919
- switch (c->m_attribs )
5920
- {
5921
- case CEA_Func4:
5922
- {
5923
- VNDefFunc4Arg* farg4 = &reinterpret_cast <VNDefFunc4Arg*>(c->m_defs )[offset];
5924
- funcApp->m_func = farg4->m_func ;
5925
- funcApp->m_arity = 4 ;
5926
- funcApp->m_args [0 ] = farg4->m_arg0 ;
5927
- funcApp->m_args [1 ] = farg4->m_arg1 ;
5928
- funcApp->m_args [2 ] = farg4->m_arg2 ;
5929
- funcApp->m_args [3 ] = farg4->m_arg3 ;
5930
- return true ;
5931
- }
5932
- case CEA_Func3:
5933
- {
5934
- VNDefFunc3Arg* farg3 = &reinterpret_cast <VNDefFunc3Arg*>(c->m_defs )[offset];
5935
- funcApp->m_func = farg3->m_func ;
5936
- funcApp->m_arity = 3 ;
5937
- funcApp->m_args [0 ] = farg3->m_arg0 ;
5938
- funcApp->m_args [1 ] = farg3->m_arg1 ;
5939
- funcApp->m_args [2 ] = farg3->m_arg2 ;
5940
- return true ;
5941
- }
5942
- case CEA_Func2:
5943
- {
5944
- VNDefFunc2Arg* farg2 = &reinterpret_cast <VNDefFunc2Arg*>(c->m_defs )[offset];
5945
- funcApp->m_func = farg2->m_func ;
5946
- funcApp->m_arity = 2 ;
5947
- funcApp->m_args [0 ] = farg2->m_arg0 ;
5948
- funcApp->m_args [1 ] = farg2->m_arg1 ;
5949
- return true ;
5950
- }
5951
- case CEA_Func1:
5952
- {
5953
- VNDefFunc1Arg* farg1 = &reinterpret_cast <VNDefFunc1Arg*>(c->m_defs )[offset];
5954
- funcApp->m_func = farg1->m_func ;
5955
- funcApp->m_arity = 1 ;
5956
- funcApp->m_args [0 ] = farg1->m_arg0 ;
5957
- return true ;
5958
- }
5959
- case CEA_Func0:
5960
- {
5961
- VNDefFunc0Arg* farg0 = &reinterpret_cast <VNDefFunc0Arg*>(c->m_defs )[offset];
5962
- funcApp->m_func = farg0->m_func ;
5963
- funcApp->m_arity = 0 ;
5964
- return true ;
5965
- }
5966
- default :
5967
- return false ;
5972
+ static_assert_no_msg (AreContiguous (CEA_Func0, CEA_Func1, CEA_Func2, CEA_Func3, CEA_Func4));
5973
+ unsigned arity = c->m_attribs - CEA_Func0;
5974
+ if (arity <= 4 )
5975
+ {
5976
+ static_assert_no_msg (sizeof (VNFunc) == sizeof (VNDefFuncAppFlexible));
5977
+ funcApp->m_arity = arity;
5978
+ VNDefFuncAppFlexible* farg = c->PointerToFuncApp (offset, arity);
5979
+ funcApp->m_func = farg->m_func ;
5980
+ funcApp->m_args = farg->m_args ;
5981
+ return true ;
5968
5982
}
5983
+
5984
+ return false ;
5969
5985
}
5970
5986
5971
5987
ValueNum ValueNumStore::VNForRefInAddr (ValueNum vn)
0 commit comments