Skip to content

Commit 9f8f653

Browse files
authored
Save 260k in InitValueNumStoreStatics (#85945)
It appears that the big #define for the intrinsics is causing InitValueNumStoreStatics to get big enough that C++ optimization ends up being disabled, which means a lot of constant operations aren't folded. This rewrites it as a const table. It adds some redundant information to the tables that we #include/#define in several places but currently includes many assertions that the old and new values match. Local size change of release clrjit_win_x64_x64.dll: 2,001,920 -> 1,735,680. InitValueNumStoreStatics (261k) is replaced by 1.2k of static data. Resolves #85953
1 parent 2bf8f1a commit 9f8f653

File tree

12 files changed

+2204
-2126
lines changed

12 files changed

+2204
-2126
lines changed

src/coreclr/jit/compiler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1329,7 +1329,7 @@ void Compiler::compStartup()
13291329
emitter::emitInit();
13301330

13311331
// Static vars of ValueNumStore
1332-
ValueNumStore::InitValueNumStoreStatics();
1332+
ValueNumStore::ValidateValueNumStoreStatics();
13331333

13341334
compDisplayStaticSizes(jitstdout);
13351335
}

src/coreclr/jit/gentree.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2121
/*****************************************************************************/
2222

2323
const unsigned char GenTree::gtOperKindTable[] = {
24-
#define GTNODE(en, st, cm, ok) ((ok)&GTK_MASK) + GTK_COMMUTE *cm,
24+
#define GTNODE(en, st, cm, ivn, ok) ((ok)&GTK_MASK) + GTK_COMMUTE *cm,
2525
#include "gtlist.h"
2626
};
2727

2828
#ifdef DEBUG
2929
const GenTreeDebugOperKind GenTree::gtDebugOperKindTable[] = {
30-
#define GTNODE(en, st, cm, ok) static_cast<GenTreeDebugOperKind>((ok)&DBK_MASK),
30+
#define GTNODE(en, st, cm, ivn, ok) static_cast<GenTreeDebugOperKind>((ok)&DBK_MASK),
3131
#include "gtlist.h"
3232
};
3333
#endif // DEBUG
@@ -171,7 +171,7 @@ static void printIndent(IndentStack* indentStack)
171171
#if defined(DEBUG) || NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS || DUMP_FLOWGRAPHS
172172

173173
static const char* opNames[] = {
174-
#define GTNODE(en, st, cm, ok) #en,
174+
#define GTNODE(en, st, cm, ivn, ok) #en,
175175
#include "gtlist.h"
176176
};
177177

@@ -187,7 +187,7 @@ const char* GenTree::OpName(genTreeOps op)
187187
#if MEASURE_NODE_SIZE
188188

189189
static const char* opStructNames[] = {
190-
#define GTNODE(en, st, cm, ok) #st,
190+
#define GTNODE(en, st, cm, ivn, ok) #st,
191191
#include "gtlist.h"
192192
};
193193

@@ -214,7 +214,7 @@ unsigned char GenTree::s_gtNodeSizes[GT_COUNT + 1];
214214
#if NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS
215215

216216
unsigned char GenTree::s_gtTrueSizes[GT_COUNT + 1]{
217-
#define GTNODE(en, st, cm, ok) sizeof(st),
217+
#define GTNODE(en, st, cm, ivn, ok) sizeof(st),
218218
#include "gtlist.h"
219219
};
220220

src/coreclr/jit/gentree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1087,7 +1087,7 @@ struct GenTree
10871087
return TypeIs(type) || TypeIs(rest...);
10881088
}
10891089

1090-
static bool StaticOperIs(genTreeOps operCompare, genTreeOps oper)
1090+
static constexpr bool StaticOperIs(genTreeOps operCompare, genTreeOps oper)
10911091
{
10921092
return operCompare == oper;
10931093
}

src/coreclr/jit/gentreeopsdef.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
enum genTreeOps : BYTE
1010
{
11-
#define GTNODE(en, st, cm, ok) GT_##en,
11+
#define GTNODE(en, st, cm, ivn, ok) GT_##en,
1212
#include "gtlist.h"
1313

1414
GT_COUNT,

src/coreclr/jit/gtlist.h

Lines changed: 145 additions & 144 deletions
Large diffs are not rendered by default.

src/coreclr/jit/hwintrinsic.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
static const HWIntrinsicInfo hwIntrinsicInfoArray[] = {
1010
// clang-format off
1111
#if defined(TARGET_XARCH)
12-
#define HARDWARE_INTRINSIC(isa, name, size, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, category, flag) \
12+
#define HARDWARE_INTRINSIC(isa, name, size, numarg, extra, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, category, flag) \
1313
{ \
1414
/* name */ #name, \
1515
/* flags */ static_cast<HWIntrinsicFlag>(flag), \
@@ -22,7 +22,7 @@ static const HWIntrinsicInfo hwIntrinsicInfoArray[] = {
2222
},
2323
#include "hwintrinsiclistxarch.h"
2424
#elif defined (TARGET_ARM64)
25-
#define HARDWARE_INTRINSIC(isa, name, size, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, category, flag) \
25+
#define HARDWARE_INTRINSIC(isa, name, size, numarg, extra, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, category, flag) \
2626
{ \
2727
/* name */ #name, \
2828
/* flags */ static_cast<HWIntrinsicFlag>(flag), \

src/coreclr/jit/hwintrinsiclistarm64.h

Lines changed: 686 additions & 686 deletions
Large diffs are not rendered by default.

src/coreclr/jit/hwintrinsiclistxarch.h

Lines changed: 1097 additions & 1095 deletions
Large diffs are not rendered by default.

src/coreclr/jit/namedintrinsiclist.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,11 @@ enum NamedIntrinsic : unsigned short
126126
#ifdef FEATURE_HW_INTRINSICS
127127
NI_HW_INTRINSIC_START,
128128
#if defined(TARGET_XARCH)
129-
#define HARDWARE_INTRINSIC(isa, name, size, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, category, flag) \
129+
#define HARDWARE_INTRINSIC(isa, name, size, numarg, extra, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, category, flag) \
130130
NI_##isa##_##name,
131131
#include "hwintrinsiclistxarch.h"
132132
#elif defined(TARGET_ARM64)
133-
#define HARDWARE_INTRINSIC(isa, name, size, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, category, flag) \
133+
#define HARDWARE_INTRINSIC(isa, name, size, numarg, extra, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, category, flag) \
134134
NI_##isa##_##name,
135135
#include "hwintrinsiclistarm64.h"
136136
#endif // !defined(TARGET_XARCH) && !defined(TARGET_ARM64)

src/coreclr/jit/valuenum.cpp

Lines changed: 82 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8852,7 +8852,65 @@ void ValueNumStore::vnDumpZeroObj(Compiler* comp, VNFuncApp* zeroObj)
88528852
#endif // DEBUG
88538853

88548854
// Static fields, methods.
8855-
static UINT8 vnfOpAttribs[VNF_COUNT];
8855+
8856+
#define ValueNumFuncDef(vnf, arity, commute, knownNonNull, sharedStatic, extra) \
8857+
static_assert((arity) >= 0 || !(extra), "valuenumfuncs.h has EncodesExtraTypeArg==true and arity<0 for " #vnf);
8858+
#include "valuenumfuncs.h"
8859+
8860+
#ifdef FEATURE_HW_INTRINSICS
8861+
8862+
#define HARDWARE_INTRINSIC(isa, name, size, argCount, extra, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, category, flag) \
8863+
static_assert((size) != 0 || !(extra), \
8864+
"hwintrinsicslist<arch>.h has EncodesExtraTypeArg==true and size==0 for " #isa " " #name);
8865+
#if defined(TARGET_XARCH)
8866+
#include "hwintrinsiclistxarch.h"
8867+
#elif defined(TARGET_ARM64)
8868+
#include "hwintrinsiclistarm64.h"
8869+
#else
8870+
#error Unsupported platform
8871+
#endif
8872+
8873+
#endif // FEATURE_HW_INTRINSICS
8874+
8875+
/* static */ constexpr uint8_t ValueNumStore::GetOpAttribsForArity(genTreeOps oper, GenTreeOperKind kind)
8876+
{
8877+
return ((GenTree::StaticOperIs(oper, GT_SELECT) ? 3 : (((kind & GTK_UNOP) >> 1) | ((kind & GTK_BINOP) >> 1)))
8878+
<< VNFOA_ArityShift) &
8879+
VNFOA_ArityMask;
8880+
}
8881+
8882+
/* static */ constexpr uint8_t ValueNumStore::GetOpAttribsForGenTree(genTreeOps oper,
8883+
bool commute,
8884+
bool illegalAsVNFunc,
8885+
GenTreeOperKind kind)
8886+
{
8887+
return GetOpAttribsForArity(oper, kind) | (static_cast<uint8_t>(commute) << VNFOA_CommutativeShift) |
8888+
(static_cast<uint8_t>(illegalAsVNFunc) << VNFOA_IllegalGenTreeOpShift);
8889+
}
8890+
8891+
/* static */ constexpr uint8_t ValueNumStore::GetOpAttribsForFunc(int arity,
8892+
bool commute,
8893+
bool knownNonNull,
8894+
bool sharedStatic)
8895+
{
8896+
return (static_cast<uint8_t>(commute) << VNFOA_CommutativeShift) |
8897+
(static_cast<uint8_t>(knownNonNull) << VNFOA_KnownNonNullShift) |
8898+
(static_cast<uint8_t>(sharedStatic) << VNFOA_SharedStaticShift) |
8899+
((static_cast<uint8_t>(arity & ~(arity >> 31)) << VNFOA_ArityShift) & VNFOA_ArityMask);
8900+
}
8901+
8902+
const uint8_t ValueNumStore::s_vnfOpAttribs[VNF_COUNT] = {
8903+
#define GTNODE(en, st, cm, ivn, ok) \
8904+
GetOpAttribsForGenTree(static_cast<genTreeOps>(GT_##en), cm, ivn, static_cast<GenTreeOperKind>(ok)),
8905+
#include "gtlist.h"
8906+
8907+
0, // VNF_Boundary
8908+
8909+
#define ValueNumFuncDef(vnf, arity, commute, knownNonNull, sharedStatic, extra) \
8910+
GetOpAttribsForFunc((arity) + static_cast<int>(extra), commute, knownNonNull, sharedStatic),
8911+
#include "valuenumfuncs.h"
8912+
};
8913+
88568914
static genTreeOps genTreeOpsIllegalAsVNFunc[] = {GT_IND, // When we do heap memory.
88578915
GT_NULLCHECK, GT_QMARK, GT_COLON, GT_LOCKADD, GT_XADD, GT_XCHG,
88588916
GT_CMPXCHG, GT_LCLHEAP, GT_BOX, GT_XORR, GT_XAND, GT_STORE_DYN_BLK,
@@ -8869,15 +8927,10 @@ static genTreeOps genTreeOpsIllegalAsVNFunc[] = {GT_IND, // When we do heap memo
88698927
// These control-flow operations need no values.
88708928
GT_JTRUE, GT_RETURN, GT_SWITCH, GT_RETFILT, GT_CKFINITE};
88718929

8872-
UINT8* ValueNumStore::s_vnfOpAttribs = nullptr;
8873-
8874-
void ValueNumStore::InitValueNumStoreStatics()
8930+
void ValueNumStore::ValidateValueNumStoreStatics()
88758931
{
8876-
// Make sure we have the constants right...
8877-
assert(unsigned(VNFOA_Arity1) == (1 << VNFOA_ArityShift));
8878-
assert(VNFOA_ArityMask == (VNFOA_MaxArity << VNFOA_ArityShift));
8879-
8880-
s_vnfOpAttribs = &vnfOpAttribs[0];
8932+
#if DEBUG
8933+
uint8_t arr[VNF_COUNT] = {};
88818934
for (unsigned i = 0; i < GT_COUNT; i++)
88828935
{
88838936
genTreeOps gtOper = static_cast<genTreeOps>(i);
@@ -8895,37 +8948,36 @@ void ValueNumStore::InitValueNumStoreStatics()
88958948
arity = 3;
88968949
}
88978950

8898-
vnfOpAttribs[i] |= ((arity << VNFOA_ArityShift) & VNFOA_ArityMask);
8951+
arr[i] |= ((arity << VNFOA_ArityShift) & VNFOA_ArityMask);
88998952

89008953
if (GenTree::OperIsCommutative(gtOper))
89018954
{
8902-
vnfOpAttribs[i] |= VNFOA_Commutative;
8955+
arr[i] |= VNFOA_Commutative;
89038956
}
89048957
}
89058958

89068959
// I so wish this wasn't the best way to do this...
89078960

89088961
int vnfNum = VNF_Boundary + 1; // The macro definition below will update this after using it.
89098962

8910-
#define ValueNumFuncDef(vnf, arity, commute, knownNonNull, sharedStatic) \
8963+
#define ValueNumFuncDef(vnf, arity, commute, knownNonNull, sharedStatic, extra) \
89118964
if (commute) \
8912-
vnfOpAttribs[vnfNum] |= VNFOA_Commutative; \
8965+
arr[vnfNum] |= VNFOA_Commutative; \
89138966
if (knownNonNull) \
8914-
vnfOpAttribs[vnfNum] |= VNFOA_KnownNonNull; \
8967+
arr[vnfNum] |= VNFOA_KnownNonNull; \
89158968
if (sharedStatic) \
8916-
vnfOpAttribs[vnfNum] |= VNFOA_SharedStatic; \
8969+
arr[vnfNum] |= VNFOA_SharedStatic; \
89178970
if (arity > 0) \
8918-
vnfOpAttribs[vnfNum] |= ((arity << VNFOA_ArityShift) & VNFOA_ArityMask); \
8971+
arr[vnfNum] |= ((arity << VNFOA_ArityShift) & VNFOA_ArityMask); \
89198972
vnfNum++;
89208973

89218974
#include "valuenumfuncs.h"
8922-
#undef ValueNumFuncDef
89238975

89248976
assert(vnfNum == VNF_COUNT);
89258977

89268978
#define ValueNumFuncSetArity(vnfNum, arity) \
8927-
vnfOpAttribs[vnfNum] &= ~VNFOA_ArityMask; /* clear old arity value */ \
8928-
vnfOpAttribs[vnfNum] |= ((arity << VNFOA_ArityShift) & VNFOA_ArityMask) /* set the new arity value */
8979+
arr[vnfNum] &= ~VNFOA_ArityMask; /* clear old arity value */ \
8980+
arr[vnfNum] |= ((arity << VNFOA_ArityShift) & VNFOA_ArityMask) /* set the new arity value */
89298981

89308982
#ifdef FEATURE_HW_INTRINSICS
89318983

@@ -8939,7 +8991,7 @@ void ValueNumStore::InitValueNumStoreStatics()
89398991
// These HW_Intrinsic's have an extra VNF_SimdType arg.
89408992
//
89418993
VNFunc func = VNFunc(VNF_HWI_FIRST + (id - NI_HW_INTRINSIC_START - 1));
8942-
unsigned oldArity = VNFuncArity(func);
8994+
unsigned oldArity = (arr[func] & VNFOA_ArityMask) >> VNFOA_ArityShift;
89438995
unsigned newArity = oldArity + 1;
89448996

89458997
ValueNumFuncSetArity(func, newArity);
@@ -8948,7 +9000,7 @@ void ValueNumStore::InitValueNumStoreStatics()
89489000
if (HWIntrinsicInfo::IsCommutative(id))
89499001
{
89509002
VNFunc func = VNFunc(VNF_HWI_FIRST + (id - NI_HW_INTRINSIC_START - 1));
8951-
vnfOpAttribs[func] |= VNFOA_Commutative;
9003+
arr[func] |= VNFOA_Commutative;
89529004
}
89539005
}
89549006

@@ -8958,17 +9010,23 @@ void ValueNumStore::InitValueNumStoreStatics()
89589010

89599011
for (unsigned i = 0; i < ArrLen(genTreeOpsIllegalAsVNFunc); i++)
89609012
{
8961-
vnfOpAttribs[genTreeOpsIllegalAsVNFunc[i]] |= VNFOA_IllegalGenTreeOp;
9013+
arr[genTreeOpsIllegalAsVNFunc[i]] |= VNFOA_IllegalGenTreeOp;
89629014
}
9015+
9016+
assert(ArrLen(arr) == ArrLen(s_vnfOpAttribs));
9017+
for (unsigned i = 0; i < ArrLen(arr); i++)
9018+
{
9019+
assert(arr[i] == s_vnfOpAttribs[i]);
9020+
}
9021+
#endif // DEBUG
89639022
}
89649023

89659024
#ifdef DEBUG
89669025
// Define the name array.
8967-
#define ValueNumFuncDef(vnf, arity, commute, knownNonNull, sharedStatic) #vnf,
9026+
#define ValueNumFuncDef(vnf, arity, commute, knownNonNull, sharedStatic, extra) #vnf,
89689027

89699028
const char* ValueNumStore::VNFuncNameArr[] = {
89709029
#include "valuenumfuncs.h"
8971-
#undef ValueNumFuncDef
89729030
};
89739031

89749032
/* static */ const char* ValueNumStore::VNFuncName(VNFunc vnf)

0 commit comments

Comments
 (0)