From 8636e6ab33418e95231e72cc06db9c94b7ebf188 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sat, 10 Jun 2023 15:49:47 -0700 Subject: [PATCH 1/9] Make idSmallCns signed on xarch --- src/coreclr/jit/emit.h | 86 +++++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 22 deletions(-) diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 9cab8e6fcea2ff..78e30d82d0b940 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -725,11 +725,12 @@ class emitter //////////////////////////////////////////////////////////////////////// // Space taken up to here: - // x86: 17 bits - // amd64: 17 bits - // arm: 16 bits - // arm64: 17 bits + // x86: 17 bits + // amd64: 17 bits + // arm: 16 bits + // arm64: 17 bits // loongarch64: 14 bits + // risc-v: 14 bits private: #if defined(TARGET_XARCH) @@ -766,11 +767,12 @@ class emitter //////////////////////////////////////////////////////////////////////// // Space taken up to here: - // x86: 38 bits - // amd64: 38 bits - // arm: 32 bits - // arm64: 31 bits + // x86: 38 bits + // amd64: 38 bits + // arm: 32 bits + // arm64: 31 bits // loongarch64: 28 bits + // risc-v: 28 bits unsigned _idSmallDsc : 1; // is this a "small" descriptor? unsigned _idLargeCns : 1; // does a large constant follow? @@ -817,11 +819,12 @@ class emitter //////////////////////////////////////////////////////////////////////// // Space taken up to here: - // x86: 47 bits - // amd64: 47 bits - // arm: 48 bits - // arm64: 50 bits + // x86: 47 bits + // amd64: 47 bits + // arm: 48 bits + // arm64: 50 bits // loongarch64: 46 bits + // risc-v: 46 bits // // How many bits have been used beyond the first 32? @@ -871,11 +874,12 @@ class emitter //////////////////////////////////////////////////////////////////////// // Space taken up to here (with/without prev offset, assuming host==target): - // x86: 53/49 bits - // amd64: 54/49 bits - // arm: 54/50 bits - // arm64: 57/52 bits + // x86: 53/49 bits + // amd64: 54/49 bits + // arm: 54/50 bits + // arm64: 57/52 bits // loongarch64: 53/48 bits + // risc-v: 53/48 bits CLANG_FORMAT_COMMENT_ANCHOR; #define ID_EXTRA_BITS (ID_EXTRA_RELOC_BITS + ID_EXTRA_BITFIELD_BITS + ID_EXTRA_PREV_OFFSET_BITS) @@ -884,18 +888,43 @@ class emitter #define ID_BIT_SMALL_CNS (32 - ID_EXTRA_BITS) C_ASSERT(ID_BIT_SMALL_CNS > 0); -#define ID_MIN_SMALL_CNS 0 -#define ID_MAX_SMALL_CNS (int)((1 << ID_BIT_SMALL_CNS) - 1U) //////////////////////////////////////////////////////////////////////// // Small constant size (with/without prev offset, assuming host==target): - // x86: 12/16 bits - // amd64: 11/16 bits - // arm: 10/14 bits - // arm64: 7/12 bits + // x86: 11/15 bits + // amd64: 10/15 bits + // arm: 10/14 bits + // arm64: 7/12 bits // loongarch64: 11/16 bits + // risc-v: 11/16 bits + CLANG_FORMAT_COMMENT_ANCHOR; +#if defined(TARGET_XARCH) +// On xarch we have a few different immediate sizes we can encounter: +// * 8-bit: Can be used directly as 8-bit or sign-extended to 16, 32, or 64-bits +// * 16-bit: Can be used directly as 16-bit +// * 32-bit: Can be used directly as 32-bit or sign-extended to 64-bits +// * 64-bit: Can be used directly as 64-bit +// +// The 64-bit version is only found for a specific `mov` instruction +// +// The 16-bit version is uncommon since the JIT uses 32-bits as its "natural size" +// and so it requires specific optimizations/scenarios to be encountered +// +// The 8-bit and 32-bit are both fairly common, particularly the 8-bit since its +// the only size used for SIMD instructions. +// +// Given that, we will differ from other platforms and store a signed value. This +// allows us to store at least [-512, +511] and covers all the common cases for +// 8-bit sign-extended values that are most common for the architecture +#define ID_MIN_SMALL_CNS (int)(0 - (1 << (ID_BIT_SMALL_CNS - 1))) +#define ID_MAX_SMALL_CNS (int)((1 << (ID_BIT_SMALL_CNS - 1)) - 1) + signed _idSmallCns : ID_BIT_SMALL_CNS; +#else +#define ID_MIN_SMALL_CNS 0 +#define ID_MAX_SMALL_CNS (int)((1 << ID_BIT_SMALL_CNS) - 1U) unsigned _idSmallCns : ID_BIT_SMALL_CNS; +#endif //////////////////////////////////////////////////////////////////////// // Space taken up to here: 64 bits, all architectures, by design. @@ -1646,6 +1675,18 @@ class emitter #endif // EMIT_BACKWARDS_NAVIGATION +#if defined(TARGET_XARCH) + ssize_t idSmallCns() const + { + return _idSmallCns; + } + void idSmallCns(ssize_t value) + { + assert(fitsInSmallCns(value)); + _idSmallCns = value; + assert(value == idSmallCns()); + } +#else unsigned idSmallCns() const { return _idSmallCns; @@ -1655,6 +1696,7 @@ class emitter assert(fitsInSmallCns(value)); _idSmallCns = value; } +#endif inline const idAddrUnion* idAddr() const { From c1982f92e5049317606683a4efad733d7d49f40b Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 11 Jun 2023 08:02:00 -0700 Subject: [PATCH 2/9] Ensure EMITTER_STATS are correctly tracked --- src/coreclr/jit/emit.cpp | 40 +++++++++++++++++++++++++--------------- src/coreclr/jit/emit.h | 40 +++++++++++++++++++++------------------- 2 files changed, 46 insertions(+), 34 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 11407c9cabb1da..ff678213149fed 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -478,22 +478,40 @@ void emitterStats(FILE* fout) if (emitter::emitSmallCnsCnt > 0) { fprintf(fout, "\n\n"); +#if defined(TARGET_XARCH) + fprintf(fout, "Common small constants >= %2d, <= %2d\n", ID_MIN_SMALL_CNS, ID_MAX_SMALL_CNS); +#else fprintf(fout, "Common small constants >= %2u, <= %2u\n", ID_MIN_SMALL_CNS, ID_MAX_SMALL_CNS); +#endif + // Only print constants representing more than 0.1% of the total constants unsigned m = emitter::emitSmallCnsCnt / 1000 + 1; - for (int i = ID_MIN_SMALL_CNS; (i <= ID_MAX_SMALL_CNS) && (i < SMALL_CNS_TSZ); i++) + for (int i = 0; (i <= ID_CNT_SMALL_CNS) && (i < SMALL_CNS_TSZ); i++) { - unsigned c = emitter::emitSmallCns[i - ID_MIN_SMALL_CNS]; + unsigned c = emitter::emitSmallCns[i]; + if (c >= m) { - if (i == SMALL_CNS_TSZ - 1) + // Adjust the index to match the allowed value range + int v = i; + + if (ID_ADJ_SMALL_CNS != 0) + { + v -= (SMALL_CNS_TSZ / 2); + } + + if ((ID_ADJ_SMALL_CNS != 0) && (i == 0)) + { + fprintf(fout, "cns[<=%4d] = %u\n", v, c); + } + else if (i == SMALL_CNS_TSZ - 1) { - fprintf(fout, "cns[>=%4d] = %u\n", i, c); + fprintf(fout, "cns[>=%4d] = %u\n", v, c); } else { - fprintf(fout, "cns[%4d] = %u\n", i, c); + fprintf(fout, "cns[ %4d] = %u\n", v, c); } } } @@ -2642,11 +2660,7 @@ emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, target_ssize_t cn id->idSmallCns(cns); #if EMITTER_STATS - emitSmallCnsCnt++; - if ((cns - ID_MIN_SMALL_CNS) >= (SMALL_CNS_TSZ - 1)) - emitSmallCns[SMALL_CNS_TSZ - 1]++; - else - emitSmallCns[cns - ID_MIN_SMALL_CNS]++; + ID_INC_SMALL_CNS(cns); emitSmallDspCnt++; #endif @@ -2677,11 +2691,7 @@ emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, target_ssize_t cn #if EMITTER_STATS emitLargeDspCnt++; - emitSmallCnsCnt++; - if ((cns - ID_MIN_SMALL_CNS) >= (SMALL_CNS_TSZ - 1)) - emitSmallCns[SMALL_CNS_TSZ - 1]++; - else - emitSmallCns[cns - ID_MIN_SMALL_CNS]++; + ID_INC_SMALL_CNS(cns); #endif return id; diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 78e30d82d0b940..7270e06f01f022 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -917,15 +917,29 @@ class emitter // Given that, we will differ from other platforms and store a signed value. This // allows us to store at least [-512, +511] and covers all the common cases for // 8-bit sign-extended values that are most common for the architecture -#define ID_MIN_SMALL_CNS (int)(0 - (1 << (ID_BIT_SMALL_CNS - 1))) -#define ID_MAX_SMALL_CNS (int)((1 << (ID_BIT_SMALL_CNS - 1)) - 1) +#define ID_ADJ_SMALL_CNS (int)(1 << (ID_BIT_SMALL_CNS - 1)) +#define ID_IDX_SMALL_CNS(x) \ + (x >= ((SMALL_CNS_TSZ / 2) - 1)) ? (SMALL_CNS_TSZ - 1) \ + : ((x >= (0 - SMALL_CNS_TSZ / 2)) ? (x + (SMALL_CNS_TSZ / 2)) : 0) + signed _idSmallCns : ID_BIT_SMALL_CNS; #else -#define ID_MIN_SMALL_CNS 0 -#define ID_MAX_SMALL_CNS (int)((1 << ID_BIT_SMALL_CNS) - 1U) +#define ID_ADJ_SMALL_CNS 0 +#define ID_IDX_SMALL_CNS(x) (x >= (SMALL_CNS_TSZ - 1)) ? (SMALL_CNS_TSZ - 1) : x + unsigned _idSmallCns : ID_BIT_SMALL_CNS; #endif +#define ID_CNT_SMALL_CNS (int)(1 << ID_BIT_SMALL_CNS) +#define ID_MIN_SMALL_CNS (int)(0 - ID_ADJ_SMALL_CNS) +#define ID_MAX_SMALL_CNS (int)(ID_CNT_SMALL_CNS - ID_ADJ_SMALL_CNS - 1) + +#define ID_INC_SMALL_CNS(x) \ + { \ + emitSmallCnsCnt++; \ + emitSmallCns[ID_IDX_SMALL_CNS(x)]++; \ + } + //////////////////////////////////////////////////////////////////////// // Space taken up to here: 64 bits, all architectures, by design. //////////////////////////////////////////////////////////////////////// @@ -3477,11 +3491,7 @@ inline emitter::instrDesc* emitter::emitNewInstrLclVarPair(emitAttr attr, cnsval instrDescLclVarPair* id = emitAllocInstrLclVarPair(attr); id->idSmallCns(cns); #if EMITTER_STATS - emitSmallCnsCnt++; - if ((cns - ID_MIN_SMALL_CNS) >= (SMALL_CNS_TSZ - 1)) - emitSmallCns[SMALL_CNS_TSZ - 1]++; - else - emitSmallCns[cns - ID_MIN_SMALL_CNS]++; + ID_INC_SMALL_CNS(cns); #endif return id; } @@ -3539,11 +3549,7 @@ inline emitter::instrDesc* emitter::emitNewInstrCns(emitAttr attr, cnsval_ssize_ id->idSmallCns(cns); #if EMITTER_STATS - emitSmallCnsCnt++; - if ((cns - ID_MIN_SMALL_CNS) >= (SMALL_CNS_TSZ - 1)) - emitSmallCns[SMALL_CNS_TSZ - 1]++; - else - emitSmallCns[cns - ID_MIN_SMALL_CNS]++; + ID_INC_SMALL_CNS(cns); #endif return id; @@ -3611,11 +3617,7 @@ inline emitter::instrDesc* emitter::emitNewInstrSC(emitAttr attr, cnsval_ssize_t id->idSmallCns(cns); #if EMITTER_STATS - emitSmallCnsCnt++; - if ((cns - ID_MIN_SMALL_CNS) >= (SMALL_CNS_TSZ - 1)) - emitSmallCns[SMALL_CNS_TSZ - 1]++; - else - emitSmallCns[cns - ID_MIN_SMALL_CNS]++; + ID_INC_SMALL_CNS(cns); #endif return id; From 2d8fe2b7e6ef7e989be0752ce9c52e7cf7298ed5 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 12 Jun 2023 03:50:36 -0700 Subject: [PATCH 3/9] Use signed _idSmallCns on other platforms as well --- src/coreclr/jit/emit.cpp | 18 +++++--------- src/coreclr/jit/emit.h | 52 ++++++++-------------------------------- 2 files changed, 16 insertions(+), 54 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index ff678213149fed..e7e667dc929b65 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -478,11 +478,7 @@ void emitterStats(FILE* fout) if (emitter::emitSmallCnsCnt > 0) { fprintf(fout, "\n\n"); -#if defined(TARGET_XARCH) fprintf(fout, "Common small constants >= %2d, <= %2d\n", ID_MIN_SMALL_CNS, ID_MAX_SMALL_CNS); -#else - fprintf(fout, "Common small constants >= %2u, <= %2u\n", ID_MIN_SMALL_CNS, ID_MAX_SMALL_CNS); -#endif // Only print constants representing more than 0.1% of the total constants unsigned m = emitter::emitSmallCnsCnt / 1000 + 1; @@ -493,19 +489,17 @@ void emitterStats(FILE* fout) if (c >= m) { - // Adjust the index to match the allowed value range - int v = i; + // We make and assumption that MIN is negative and MAX is positive + assert((ID_MIN_SMALL_CNS < 0) && (ID_MAX_SMALL_CNS > 0)); - if (ID_ADJ_SMALL_CNS != 0) - { - v -= (SMALL_CNS_TSZ / 2); - } + // Adjust the index to match the allowed value range + int v = i - (SMALL_CNS_TSZ / 2); - if ((ID_ADJ_SMALL_CNS != 0) && (i == 0)) + if (i == 0) { fprintf(fout, "cns[<=%4d] = %u\n", v, c); } - else if (i == SMALL_CNS_TSZ - 1) + else if (i == (SMALL_CNS_TSZ - 1)) { fprintf(fout, "cns[>=%4d] = %u\n", v, c); } diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 7270e06f01f022..178271535eb0ff 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -899,47 +899,27 @@ class emitter // risc-v: 11/16 bits CLANG_FORMAT_COMMENT_ANCHOR; -#if defined(TARGET_XARCH) -// On xarch we have a few different immediate sizes we can encounter: -// * 8-bit: Can be used directly as 8-bit or sign-extended to 16, 32, or 64-bits -// * 16-bit: Can be used directly as 16-bit -// * 32-bit: Can be used directly as 32-bit or sign-extended to 64-bits -// * 64-bit: Can be used directly as 64-bit -// -// The 64-bit version is only found for a specific `mov` instruction -// -// The 16-bit version is uncommon since the JIT uses 32-bits as its "natural size" -// and so it requires specific optimizations/scenarios to be encountered -// -// The 8-bit and 32-bit are both fairly common, particularly the 8-bit since its -// the only size used for SIMD instructions. -// -// Given that, we will differ from other platforms and store a signed value. This -// allows us to store at least [-512, +511] and covers all the common cases for -// 8-bit sign-extended values that are most common for the architecture -#define ID_ADJ_SMALL_CNS (int)(1 << (ID_BIT_SMALL_CNS - 1)) -#define ID_IDX_SMALL_CNS(x) \ - (x >= ((SMALL_CNS_TSZ / 2) - 1)) ? (SMALL_CNS_TSZ - 1) \ - : ((x >= (0 - SMALL_CNS_TSZ / 2)) ? (x + (SMALL_CNS_TSZ / 2)) : 0) - - signed _idSmallCns : ID_BIT_SMALL_CNS; -#else -#define ID_ADJ_SMALL_CNS 0 -#define ID_IDX_SMALL_CNS(x) (x >= (SMALL_CNS_TSZ - 1)) ? (SMALL_CNS_TSZ - 1) : x - - unsigned _idSmallCns : ID_BIT_SMALL_CNS; -#endif +// We encounter many constants, but there is a disproportionate amount that are in the range [-1, +4] +// and otherwise powers of 2. We therefore allow the tracked range here to incldue negative values. +#define ID_ADJ_SMALL_CNS (int)(1 << (ID_BIT_SMALL_CNS - 1)) #define ID_CNT_SMALL_CNS (int)(1 << ID_BIT_SMALL_CNS) + #define ID_MIN_SMALL_CNS (int)(0 - ID_ADJ_SMALL_CNS) #define ID_MAX_SMALL_CNS (int)(ID_CNT_SMALL_CNS - ID_ADJ_SMALL_CNS - 1) +#define ID_IDX_SMALL_CNS(x) \ + (x >= ((SMALL_CNS_TSZ / 2) - 1)) ? (SMALL_CNS_TSZ - 1) \ + : ((x >= (0 - SMALL_CNS_TSZ / 2)) ? (x + (SMALL_CNS_TSZ / 2)) : 0) + #define ID_INC_SMALL_CNS(x) \ { \ emitSmallCnsCnt++; \ emitSmallCns[ID_IDX_SMALL_CNS(x)]++; \ } + signed _idSmallCns : ID_BIT_SMALL_CNS; + //////////////////////////////////////////////////////////////////////// // Space taken up to here: 64 bits, all architectures, by design. //////////////////////////////////////////////////////////////////////// @@ -1689,7 +1669,6 @@ class emitter #endif // EMIT_BACKWARDS_NAVIGATION -#if defined(TARGET_XARCH) ssize_t idSmallCns() const { return _idSmallCns; @@ -1700,17 +1679,6 @@ class emitter _idSmallCns = value; assert(value == idSmallCns()); } -#else - unsigned idSmallCns() const - { - return _idSmallCns; - } - void idSmallCns(size_t value) - { - assert(fitsInSmallCns(value)); - _idSmallCns = value; - } -#endif inline const idAddrUnion* idAddr() const { From b133ecc506ea900a45da2ac674b71f68ab95dcf5 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 12 Jun 2023 04:30:32 -0700 Subject: [PATCH 4/9] Have EMITTER_STATS track additional information about constants --- src/coreclr/jit/emit.cpp | 33 ++++++++++------ src/coreclr/jit/emit.h | 85 +++++++++++++++++++++++++++++----------- 2 files changed, 83 insertions(+), 35 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index e7e667dc929b65..1cf167866ba23c 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -199,9 +199,11 @@ unsigned emitter::emitTotalIDescRelocCnt; unsigned emitter::emitSmallDspCnt; unsigned emitter::emitLargeDspCnt; +unsigned emitter::emitSmallCns[SMALL_CNS_TSZ]; unsigned emitter::emitSmallCnsCnt; unsigned emitter::emitLargeCnsCnt; -unsigned emitter::emitSmallCns[SMALL_CNS_TSZ]; +unsigned emitter::emitNegCnsCnt; +unsigned emitter::emitPow2CnsCnt; unsigned emitter::emitTotalDescAlignCnt; @@ -469,9 +471,16 @@ void emitterStats(FILE* fout) if ((emitter::emitSmallCnsCnt > 0) || (emitter::emitLargeCnsCnt > 0)) { - fprintf(fout, "SmallCnsCnt = %6u\n", emitter::emitSmallCnsCnt); - fprintf(fout, "LargeCnsCnt = %6u (%3u %% of total)\n", emitter::emitLargeCnsCnt, - 100 * emitter::emitLargeCnsCnt / (emitter::emitLargeCnsCnt + emitter::emitSmallCnsCnt)); + unsigned emitTotalCnsCnt = emitter::emitLargeCnsCnt + emitter::emitSmallCnsCnt; + + fprintf(fout, "SmallCnsCnt = %8u (%5.2f%%)\n", emitter::emitSmallCnsCnt, + (100.0 * emitter::emitSmallCnsCnt) / emitTotalCnsCnt); + fprintf(fout, "LargeCnsCnt = %8u (%5.2f%%)\n", emitter::emitLargeCnsCnt, + (100.0 * emitter::emitLargeCnsCnt) / emitTotalCnsCnt); + fprintf(fout, "NegCnsCnt = %8u (%5.2f%%)\n", emitter::emitNegCnsCnt, + (100.0 * emitter::emitNegCnsCnt) / emitTotalCnsCnt); + fprintf(fout, "Pow2CnsCnt = %8u (%5.2f%%)\n", emitter::emitPow2CnsCnt, + (100.0 * emitter::emitPow2CnsCnt) / emitTotalCnsCnt); } // Print out the most common small constants. @@ -481,7 +490,7 @@ void emitterStats(FILE* fout) fprintf(fout, "Common small constants >= %2d, <= %2d\n", ID_MIN_SMALL_CNS, ID_MAX_SMALL_CNS); // Only print constants representing more than 0.1% of the total constants - unsigned m = emitter::emitSmallCnsCnt / 1000 + 1; + unsigned m = (emitter::emitSmallCnsCnt / 1000) + 1; for (int i = 0; (i <= ID_CNT_SMALL_CNS) && (i < SMALL_CNS_TSZ); i++) { @@ -497,15 +506,15 @@ void emitterStats(FILE* fout) if (i == 0) { - fprintf(fout, "cns[<=%4d] = %u\n", v, c); + fprintf(fout, "cns[<=%4d] = %8u (%5.2f%%)\n", v, c, (100.0 * c) / emitter::emitSmallCnsCnt); } else if (i == (SMALL_CNS_TSZ - 1)) { - fprintf(fout, "cns[>=%4d] = %u\n", v, c); + fprintf(fout, "cns[>=%4d] = %8u (%5.2f%%)\n", v, c, (100.0 * c) / emitter::emitSmallCnsCnt); } else { - fprintf(fout, "cns[ %4d] = %u\n", v, c); + fprintf(fout, "cns[ %4d] = %8u (%5.2f%%)\n", v, c, (100.0 * c) / emitter::emitSmallCnsCnt); } } } @@ -2654,7 +2663,7 @@ emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, target_ssize_t cn id->idSmallCns(cns); #if EMITTER_STATS - ID_INC_SMALL_CNS(cns); + TrackSmallCns(cns); emitSmallDspCnt++; #endif @@ -2665,7 +2674,7 @@ emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, target_ssize_t cn instrDescCns* id = emitAllocInstrCns(size, cns); #if EMITTER_STATS - emitLargeCnsCnt++; + TrackLargeCns(cns); emitSmallDspCnt++; #endif @@ -2684,8 +2693,8 @@ emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, target_ssize_t cn id->idSmallCns(cns); #if EMITTER_STATS + TrackSmallCns(cns); emitLargeDspCnt++; - ID_INC_SMALL_CNS(cns); #endif return id; @@ -2701,8 +2710,8 @@ emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, target_ssize_t cn id->iddcDspVal = dsp; #if EMITTER_STATS + TrackLargeCns(cns); emitLargeDspCnt++; - emitLargeCnsCnt++; #endif return id; diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 178271535eb0ff..eb9d26a4f801ca 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -899,25 +899,14 @@ class emitter // risc-v: 11/16 bits CLANG_FORMAT_COMMENT_ANCHOR; -// We encounter many constants, but there is a disproportionate amount that are in the range [-1, +4] -// and otherwise powers of 2. We therefore allow the tracked range here to incldue negative values. - #define ID_ADJ_SMALL_CNS (int)(1 << (ID_BIT_SMALL_CNS - 1)) #define ID_CNT_SMALL_CNS (int)(1 << ID_BIT_SMALL_CNS) #define ID_MIN_SMALL_CNS (int)(0 - ID_ADJ_SMALL_CNS) #define ID_MAX_SMALL_CNS (int)(ID_CNT_SMALL_CNS - ID_ADJ_SMALL_CNS - 1) -#define ID_IDX_SMALL_CNS(x) \ - (x >= ((SMALL_CNS_TSZ / 2) - 1)) ? (SMALL_CNS_TSZ - 1) \ - : ((x >= (0 - SMALL_CNS_TSZ / 2)) ? (x + (SMALL_CNS_TSZ / 2)) : 0) - -#define ID_INC_SMALL_CNS(x) \ - { \ - emitSmallCnsCnt++; \ - emitSmallCns[ID_IDX_SMALL_CNS(x)]++; \ - } - + // We encounter many constants, but there is a disproportionate amount that are in the range [-1, +4] + // and otherwise powers of 2. We therefore allow the tracked range here to incldue negative values. signed _idSmallCns : ID_BIT_SMALL_CNS; //////////////////////////////////////////////////////////////////////// @@ -1491,7 +1480,7 @@ class emitter #endif // TARGET_RISCV64 - inline static bool fitsInSmallCns(ssize_t val) + inline static bool fitsInSmallCns(cnsval_ssize_t val) { return ((val >= ID_MIN_SMALL_CNS) && (val <= ID_MAX_SMALL_CNS)); } @@ -1669,11 +1658,11 @@ class emitter #endif // EMIT_BACKWARDS_NAVIGATION - ssize_t idSmallCns() const + signed idSmallCns() const { return _idSmallCns; } - void idSmallCns(ssize_t value) + void idSmallCns(cnsval_ssize_t value) { assert(fitsInSmallCns(value)); _idSmallCns = value; @@ -3223,14 +3212,60 @@ class emitter static unsigned emitSmallDspCnt; static unsigned emitLargeDspCnt; - static unsigned emitSmallCnsCnt; #define SMALL_CNS_TSZ 256 static unsigned emitSmallCns[SMALL_CNS_TSZ]; + static unsigned emitSmallCnsCnt; static unsigned emitLargeCnsCnt; + static unsigned emitNegCnsCnt; + static unsigned emitPow2CnsCnt; + static unsigned emitTotalDescAlignCnt; static unsigned emitIFcounts[IF_COUNT]; + void TrackCns(cnsval_ssize_t value) + { + if (value < 0) + { + emitNegCnsCnt++; + } + + if (isPow2(value)) + { + emitPow2CnsCnt++; + } + } + + void TrackSmallCns(cnsval_ssize_t value) + { + // We only track a subset of the allowed small constants and + // so we'll split the tracked range between positive/negative + // aggregating those outside the tracked range into the min/max + // instead. + + assert(fitsInSmallCns(value)); + uint32_t index = 0; + + if (value >= ((SMALL_CNS_TSZ / 2) - 1)) + { + index = static_cast(SMALL_CNS_TSZ - 1); + } + else if (value >= (0 - SMALL_CNS_TSZ / 2)) + { + index = static_cast(value + (SMALL_CNS_TSZ / 2)); + } + + emitSmallCnsCnt++; + emitSmallCns[index]++; + + TrackCns(value); + } + + void TrackLargeCns(cnsval_ssize_t value) + { + emitLargeCnsCnt++; + TrackCns(value); + } #endif // EMITTER_STATS /************************************************************************* @@ -3458,17 +3493,21 @@ inline emitter::instrDesc* emitter::emitNewInstrLclVarPair(emitAttr attr, cnsval { instrDescLclVarPair* id = emitAllocInstrLclVarPair(attr); id->idSmallCns(cns); + #if EMITTER_STATS - ID_INC_SMALL_CNS(cns); + TrackSmallCns(cns); #endif + return id; } else { instrDescLclVarPairCns* id = emitAllocInstrLclVarPairCns(attr, cns); + #if EMITTER_STATS - emitLargeCnsCnt++; + TrackLargeCns(cns); #endif + return id; } } @@ -3517,7 +3556,7 @@ inline emitter::instrDesc* emitter::emitNewInstrCns(emitAttr attr, cnsval_ssize_ id->idSmallCns(cns); #if EMITTER_STATS - ID_INC_SMALL_CNS(cns); + TrackSmallCns(cns); #endif return id; @@ -3527,7 +3566,7 @@ inline emitter::instrDesc* emitter::emitNewInstrCns(emitAttr attr, cnsval_ssize_ instrDescCns* id = emitAllocInstrCns(attr, cns); #if EMITTER_STATS - emitLargeCnsCnt++; + TrackLargeCns(cns); #endif return id; @@ -3585,7 +3624,7 @@ inline emitter::instrDesc* emitter::emitNewInstrSC(emitAttr attr, cnsval_ssize_t id->idSmallCns(cns); #if EMITTER_STATS - ID_INC_SMALL_CNS(cns); + TrackSmallCns(cns); #endif return id; @@ -3595,7 +3634,7 @@ inline emitter::instrDesc* emitter::emitNewInstrSC(emitAttr attr, cnsval_ssize_t instrDescCns* id = emitAllocInstrCns(attr, cns); #if EMITTER_STATS - emitLargeCnsCnt++; + TrackLargeCns(cns); #endif return id; From 0583c1f57b2925fb7b1ff1f84f1e18833218f12a Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 12 Jun 2023 05:39:15 -0700 Subject: [PATCH 5/9] Also track whether the constant fits into 8, 16, or 32-bits --- src/coreclr/jit/emit.cpp | 23 ++++++++++++++++------- src/coreclr/jit/emit.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 1cf167866ba23c..7e34a772716ea8 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -202,6 +202,9 @@ unsigned emitter::emitLargeDspCnt; unsigned emitter::emitSmallCns[SMALL_CNS_TSZ]; unsigned emitter::emitSmallCnsCnt; unsigned emitter::emitLargeCnsCnt; +unsigned emitter::emitInt8CnsCnt; +unsigned emitter::emitInt16CnsCnt; +unsigned emitter::emitInt32CnsCnt; unsigned emitter::emitNegCnsCnt; unsigned emitter::emitPow2CnsCnt; @@ -469,14 +472,20 @@ void emitterStats(FILE* fout) stkDepthTable.dump(fout); fprintf(fout, "\n"); - if ((emitter::emitSmallCnsCnt > 0) || (emitter::emitLargeCnsCnt > 0)) - { - unsigned emitTotalCnsCnt = emitter::emitLargeCnsCnt + emitter::emitSmallCnsCnt; + unsigned emitTotalCnsCnt = emitter::emitLargeCnsCnt + emitter::emitSmallCnsCnt; + if (emitTotalCnsCnt != 0) + { fprintf(fout, "SmallCnsCnt = %8u (%5.2f%%)\n", emitter::emitSmallCnsCnt, (100.0 * emitter::emitSmallCnsCnt) / emitTotalCnsCnt); fprintf(fout, "LargeCnsCnt = %8u (%5.2f%%)\n", emitter::emitLargeCnsCnt, (100.0 * emitter::emitLargeCnsCnt) / emitTotalCnsCnt); + fprintf(fout, "Int8CnsCnt = %8u (%5.2f%%)\n", emitter::emitInt8CnsCnt, + (100.0 * emitter::emitInt8CnsCnt) / emitTotalCnsCnt); + fprintf(fout, "Int16CnsCnt = %8u (%5.2f%%)\n", emitter::emitInt16CnsCnt, + (100.0 * emitter::emitInt16CnsCnt) / emitTotalCnsCnt); + fprintf(fout, "Int32CnsCnt = %8u (%5.2f%%)\n", emitter::emitInt32CnsCnt, + (100.0 * emitter::emitInt32CnsCnt) / emitTotalCnsCnt); fprintf(fout, "NegCnsCnt = %8u (%5.2f%%)\n", emitter::emitNegCnsCnt, (100.0 * emitter::emitNegCnsCnt) / emitTotalCnsCnt); fprintf(fout, "Pow2CnsCnt = %8u (%5.2f%%)\n", emitter::emitPow2CnsCnt, @@ -484,7 +493,7 @@ void emitterStats(FILE* fout) } // Print out the most common small constants. - if (emitter::emitSmallCnsCnt > 0) + if (emitter::emitSmallCnsCnt != 0) { fprintf(fout, "\n\n"); fprintf(fout, "Common small constants >= %2d, <= %2d\n", ID_MIN_SMALL_CNS, ID_MAX_SMALL_CNS); @@ -506,15 +515,15 @@ void emitterStats(FILE* fout) if (i == 0) { - fprintf(fout, "cns[<=%4d] = %8u (%5.2f%%)\n", v, c, (100.0 * c) / emitter::emitSmallCnsCnt); + fprintf(fout, "cns[<=%4d] = %8u (%5.2f%%)\n", v, c, (100.0 * c) / emitTotalCnsCnt); } else if (i == (SMALL_CNS_TSZ - 1)) { - fprintf(fout, "cns[>=%4d] = %8u (%5.2f%%)\n", v, c, (100.0 * c) / emitter::emitSmallCnsCnt); + fprintf(fout, "cns[>=%4d] = %8u (%5.2f%%)\n", v, c, (100.0 * c) / emitTotalCnsCnt); } else { - fprintf(fout, "cns[ %4d] = %8u (%5.2f%%)\n", v, c, (100.0 * c) / emitter::emitSmallCnsCnt); + fprintf(fout, "cns[ %4d] = %8u (%5.2f%%)\n", v, c, (100.0 * c) / emitTotalCnsCnt); } } } diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index eb9d26a4f801ca..70e947ae254003 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -3216,6 +3216,9 @@ class emitter static unsigned emitSmallCns[SMALL_CNS_TSZ]; static unsigned emitSmallCnsCnt; static unsigned emitLargeCnsCnt; + static unsigned emitInt8CnsCnt; + static unsigned emitInt16CnsCnt; + static unsigned emitInt32CnsCnt; static unsigned emitNegCnsCnt; static unsigned emitPow2CnsCnt; @@ -3228,12 +3231,39 @@ class emitter if (value < 0) { emitNegCnsCnt++; + + if (value >= INT8_MIN) + { + emitInt8CnsCnt++; + } + else if (value >= INT16_MIN) + { + emitInt16CnsCnt++; + } + else if (value >= INT32_MIN) + { + emitInt32CnsCnt++; + } + } + else if (value <= INT8_MAX) + { + emitInt8CnsCnt++; + } + else if (value <= INT16_MAX) + { + emitInt16CnsCnt++; + } + else if (value <= INT32_MAX) + { + emitInt32CnsCnt++; } if (isPow2(value)) { emitPow2CnsCnt++; } + + } void TrackSmallCns(cnsval_ssize_t value) From 4355d6ce1b240ecec021a9858a83078defddbfcd Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 12 Jun 2023 07:11:30 -0700 Subject: [PATCH 6/9] Fix the formatting/ordering of the EMITTER_STATS header --- src/coreclr/jit/emit.cpp | 153 +++++++++++++++++++++++---------------- src/coreclr/jit/emit.h | 34 ++------- 2 files changed, 100 insertions(+), 87 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 7e34a772716ea8..70cdfcff79973f 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -224,116 +224,147 @@ void emitterStaticStats(FILE* fout) fprintf(fout, "\n"); fprintf(fout, "insGroup:\n"); - fprintf(fout, "Offset / size of igNext = %2zu / %2zu\n", offsetof(insGroup, igNext), + fprintf(fout, "Offset / size of igNext = %3zu / %2zu\n", offsetof(insGroup, igNext), sizeof(igDummy->igNext)); #if EMIT_BACKWARDS_NAVIGATION - fprintf(fout, "Offset / size of igPrev = %2zu / %2zu\n", offsetof(insGroup, igPrev), + fprintf(fout, "Offset / size of igPrev = %3zu / %2zu\n", offsetof(insGroup, igPrev), sizeof(igDummy->igPrev)); #endif // EMIT_BACKWARDS_NAVIGATION #ifdef DEBUG - fprintf(fout, "Offset / size of igSelf = %2zu / %2zu\n", offsetof(insGroup, igSelf), + fprintf(fout, "Offset / size of igSelf = %3zu / %2zu\n", offsetof(insGroup, igSelf), sizeof(igDummy->igSelf)); -#endif - fprintf(fout, "Offset / size of igNum = %2zu / %2zu\n", offsetof(insGroup, igNum), +#endif // DEBUG +#if defined(DEBUG) || defined(LATE_DISASM) + fprintf(fout, "Offset / size of igWeight = %3zu / %2zu\n", offsetof(insGroup, igWeight), + sizeof(igDummy->igWeight)); + fprintf(fout, "Offset / size of igPerfScore = %3zu / %2zu\n", offsetof(insGroup, igPerfScore), + sizeof(igDummy->igPerfScore)); +#endif // DEBUG || LATE_DISASM +#ifdef DEBUG + fprintf(fout, "Offset / size of lastGeneratedBlock = %3zu / %2zu\n", offsetof(insGroup, lastGeneratedBlock), + sizeof(igDummy->lastGeneratedBlock)); + fprintf(fout, "Offset / size of igBlocks = %3zu / %2zu\n", offsetof(insGroup, igBlocks), + sizeof(igDummy->igBlocks)); + fprintf(fout, "Offset / size of igDataSize = %3zu / %2zu\n", offsetof(insGroup, igDataSize), + sizeof(igDummy->igDataSize)); +#endif // DEBUG + fprintf(fout, "Offset / size of igNum = %3zu / %2zu\n", offsetof(insGroup, igNum), sizeof(igDummy->igNum)); - fprintf(fout, "Offset / size of igOffs = %2zu / %2zu\n", offsetof(insGroup, igOffs), + fprintf(fout, "Offset / size of igOffs = %3zu / %2zu\n", offsetof(insGroup, igOffs), sizeof(igDummy->igOffs)); - fprintf(fout, "Offset / size of igFuncIdx = %2zu / %2zu\n", offsetof(insGroup, igFuncIdx), + fprintf(fout, "Offset / size of igFuncIdx = %3zu / %2zu\n", offsetof(insGroup, igFuncIdx), sizeof(igDummy->igFuncIdx)); - fprintf(fout, "Offset / size of igFlags = %2zu / %2zu\n", offsetof(insGroup, igFlags), + fprintf(fout, "Offset / size of igFlags = %3zu / %2zu\n", offsetof(insGroup, igFlags), sizeof(igDummy->igFlags)); - fprintf(fout, "Offset / size of igSize = %2zu / %2zu\n", offsetof(insGroup, igSize), + fprintf(fout, "Offset / size of igSize = %3zu / %2zu\n", offsetof(insGroup, igSize), sizeof(igDummy->igSize)); - fprintf(fout, "Offset / size of igData = %2zu / %2zu\n", offsetof(insGroup, igData), +#if FEATURE_LOOP_ALIGN + fprintf(fout, "Offset / size of igLoopBackEdge = %3zu / %2zu\n", offsetof(insGroup, igLoopBackEdge), + sizeof(igDummy->igLoopBackEdge)); +#endif // FEATURE_LOOP_ALIGN +#if !(REGMASK_BITS <= 32) + fprintf(fout, "Offset / size of igGCregs = %3zu / %2zu\n", offsetof(insGroup, igGCregs), + sizeof(igDummy->igGCregs)); +#endif // !(REGMASK_BITS <= 32) + fprintf(fout, "Offset / size of igData = %3zu / %2zu\n", offsetof(insGroup, igData), sizeof(igDummy->igData)); - fprintf(fout, "Offset / size of igPhData = %2zu / %2zu\n", offsetof(insGroup, igPhData), + fprintf(fout, "Offset / size of igPhData = %3zu / %2zu\n", offsetof(insGroup, igPhData), sizeof(igDummy->igPhData)); #if EMIT_BACKWARDS_NAVIGATION - fprintf(fout, "Offset / size of igLastIns = %2zu / %2zu\n", offsetof(insGroup, igLastIns), + fprintf(fout, "Offset / size of igLastIns = %3zu / %2zu\n", offsetof(insGroup, igLastIns), sizeof(igDummy->igLastIns)); #endif // EMIT_BACKWARDS_NAVIGATION #if EMIT_TRACK_STACK_DEPTH - fprintf(fout, "Offset / size of igStkLvl = %2zu / %2zu\n", offsetof(insGroup, igStkLvl), + fprintf(fout, "Offset / size of igStkLvl = %3zu / %2zu\n", offsetof(insGroup, igStkLvl), sizeof(igDummy->igStkLvl)); -#endif - fprintf(fout, "Offset / size of igGCregs = %2zu / %2zu\n", offsetof(insGroup, igGCregs), +#endif // EMIT_TRACK_STACK_DEPTH +#if REGMASK_BITS <= 32 + fprintf(fout, "Offset / size of igGCregs = %3zu / %2zu\n", offsetof(insGroup, igGCregs), sizeof(igDummy->igGCregs)); - fprintf(fout, "Offset / size of igInsCnt = %2zu / %2zu\n", offsetof(insGroup, igInsCnt), +#endif // REGMASK_BITS <= 32 + fprintf(fout, "Offset / size of igInsCnt = %3zu / %2zu\n", offsetof(insGroup, igInsCnt), sizeof(igDummy->igInsCnt)); fprintf(fout, "\n"); - fprintf(fout, "Size of insGroup = %zu\n", sizeof(insGroup)); + fprintf(fout, "Size of insGroup = %zu\n", sizeof(insGroup)); // insPlaceholderGroupData members + insPlaceholderGroupData* ipgdDummy = nullptr; + fprintf(fout, "\n"); fprintf(fout, "insPlaceholderGroupData:\n"); - fprintf(fout, "Offset of igPhNext = %2zu\n", offsetof(insPlaceholderGroupData, igPhNext)); - fprintf(fout, "Offset of igPhBB = %2zu\n", offsetof(insPlaceholderGroupData, igPhBB)); - fprintf(fout, "Offset of igPhInitGCrefVars = %2zu\n", offsetof(insPlaceholderGroupData, igPhInitGCrefVars)); - fprintf(fout, "Offset of igPhInitGCrefRegs = %2zu\n", offsetof(insPlaceholderGroupData, igPhInitGCrefRegs)); - fprintf(fout, "Offset of igPhInitByrefRegs = %2zu\n", offsetof(insPlaceholderGroupData, igPhInitByrefRegs)); - fprintf(fout, "Offset of igPhPrevGCrefVars = %2zu\n", offsetof(insPlaceholderGroupData, igPhPrevGCrefVars)); - fprintf(fout, "Offset of igPhPrevGCrefRegs = %2zu\n", offsetof(insPlaceholderGroupData, igPhPrevGCrefRegs)); - fprintf(fout, "Offset of igPhPrevByrefRegs = %2zu\n", offsetof(insPlaceholderGroupData, igPhPrevByrefRegs)); - fprintf(fout, "Offset of igPhType = %2zu\n", offsetof(insPlaceholderGroupData, igPhType)); - fprintf(fout, "Size of insPlaceholderGroupData = %zu\n", sizeof(insPlaceholderGroupData)); + fprintf(fout, "Offset / size of igPhNext = %3zu / %2zu\n", offsetof(insPlaceholderGroupData, igPhNext), + sizeof(ipgdDummy->igPhNext)); + fprintf(fout, "Offset / size of igPhBB = %3zu / %2zu\n", offsetof(insPlaceholderGroupData, igPhBB), + sizeof(ipgdDummy->igPhBB)); + fprintf(fout, "Offset / size of igPhInitGCrefVars = %3zu / %2zu\n", + offsetof(insPlaceholderGroupData, igPhInitGCrefVars), sizeof(ipgdDummy->igPhInitGCrefVars)); + fprintf(fout, "Offset / size of igPhInitGCrefRegs = %3zu / %2zu\n", + offsetof(insPlaceholderGroupData, igPhInitGCrefRegs), sizeof(ipgdDummy->igPhInitGCrefRegs)); + fprintf(fout, "Offset / size of igPhInitByrefRegs = %3zu / %2zu\n", + offsetof(insPlaceholderGroupData, igPhInitByrefRegs), sizeof(ipgdDummy->igPhInitByrefRegs)); + fprintf(fout, "Offset / size of igPhPrevGCrefVars = %3zu / %2zu\n", + offsetof(insPlaceholderGroupData, igPhPrevGCrefVars), sizeof(ipgdDummy->igPhPrevGCrefVars)); + fprintf(fout, "Offset / size of igPhPrevGCrefRegs = %3zu / %2zu\n", + offsetof(insPlaceholderGroupData, igPhPrevGCrefRegs), sizeof(ipgdDummy->igPhPrevGCrefRegs)); + fprintf(fout, "Offset / size of igPhPrevByrefRegs = %3zu / %2zu\n", + offsetof(insPlaceholderGroupData, igPhPrevByrefRegs), sizeof(ipgdDummy->igPhPrevByrefRegs)); + fprintf(fout, "Offset / size of igPhType = %3zu / %2zu\n", offsetof(insPlaceholderGroupData, igPhType), + sizeof(ipgdDummy->igPhType)); + fprintf(fout, "\n"); + fprintf(fout, "Size of insPlaceholderGroupData = %zu\n", sizeof(insPlaceholderGroupData)); fprintf(fout, "\n"); fprintf(fout, "SMALL_IDSC_SIZE = %2u\n", SMALL_IDSC_SIZE); - fprintf(fout, "Size of instrDesc = %2zu\n", sizeof(emitter::instrDesc)); - // fprintf(fout, "Offset of _idIns = %2zu\n", offsetof(emitter::instrDesc, _idIns )); - // fprintf(fout, "Offset of _idInsFmt = %2zu\n", offsetof(emitter::instrDesc, _idInsFmt )); - // fprintf(fout, "Offset of _idOpSize = %2zu\n", offsetof(emitter::instrDesc, _idOpSize )); - // fprintf(fout, "Offset of idSmallCns = %2zu\n", offsetof(emitter::instrDesc, idSmallCns )); - // fprintf(fout, "Offset of _idAddrUnion= %2zu\n", offsetof(emitter::instrDesc, _idAddrUnion)); - // fprintf(fout, "\n"); - // fprintf(fout, "Size of _idAddrUnion= %2zu\n", sizeof(((emitter::instrDesc*)0)->_idAddrUnion)); - - fprintf(fout, "Size of instrDescJmp = %2zu\n", sizeof(emitter::instrDescJmp)); -#if FEATURE_LOOP_ALIGN - fprintf(fout, "Size of instrDescAlign = %2zu\n", sizeof(emitter::instrDescAlign)); -#endif // FEATURE_LOOP_ALIGN -#if !defined(TARGET_ARM64) - fprintf(fout, "Size of instrDescLbl = %2zu\n", sizeof(emitter::instrDescLbl)); -#endif // !defined(TARGET_ARM64) - fprintf(fout, "Size of instrDescCns = %2zu\n", sizeof(emitter::instrDescCns)); - fprintf(fout, "Size of instrDescDsp = %2zu\n", sizeof(emitter::instrDescDsp)); - fprintf(fout, "Size of instrDescCnsDsp = %2zu\n", sizeof(emitter::instrDescCnsDsp)); + fprintf(fout, "Size of instrDesc = %2zu\n", sizeof(emitter::instrDesc)); + fprintf(fout, "Size of instrDescCns = %2zu\n", sizeof(emitter::instrDescCns)); + fprintf(fout, "Size of instrDescDsp = %2zu\n", sizeof(emitter::instrDescDsp)); + fprintf(fout, "Size of instrDescCnsDsp = %2zu\n", sizeof(emitter::instrDescCnsDsp)); #ifdef TARGET_XARCH - fprintf(fout, "Size of instrDescAmd = %2zu\n", sizeof(emitter::instrDescAmd)); - fprintf(fout, "Size of instrDescCnsAmd = %2zu\n", sizeof(emitter::instrDescCnsAmd)); + fprintf(fout, "Size of instrDescAmd = %2zu\n", sizeof(emitter::instrDescAmd)); + fprintf(fout, "Size of instrDescCnsAmd = %2zu\n", sizeof(emitter::instrDescCnsAmd)); #endif // TARGET_XARCH - fprintf(fout, "Size of instrDescCGCA = %2zu\n", sizeof(emitter::instrDescCGCA)); #ifdef TARGET_ARM - fprintf(fout, "Size of instrDescReloc = %2zu\n", sizeof(emitter::instrDescReloc)); + fprintf(fout, "Size of instrDescReloc = %2zu\n", sizeof(emitter::instrDescReloc)); #endif // TARGET_ARM +#if FEATURE_LOOP_ALIGN + fprintf(fout, "Size of instrDescAlign = %2zu\n", sizeof(emitter::instrDescAlign)); +#endif // FEATURE_LOOP_ALIGN + fprintf(fout, "Size of instrDescJmp = %2zu\n", sizeof(emitter::instrDescJmp)); +#if !defined(TARGET_ARM64) + fprintf(fout, "Size of instrDescLbl = %2zu\n", sizeof(emitter::instrDescLbl)); +#endif // !defined(TARGET_ARM64) + fprintf(fout, "Size of instrDescCGCA = %2zu\n", sizeof(emitter::instrDescCGCA)); fprintf(fout, "\n"); fprintf(fout, "igBuffSize = %2zu\n", igBuffSize); fprintf(fout, "SMALL_IDSC_SIZE per IG buffer = %2zu\n", igBuffSize / SMALL_IDSC_SIZE); - fprintf(fout, "instrDesc per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDesc)); - fprintf(fout, "instrDescJmp per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescJmp)); -#if !defined(TARGET_ARM64) - fprintf(fout, "instrDescLbl per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescLbl)); -#endif // !defined(TARGET_ARM64) - fprintf(fout, "instrDescCns per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCns)); - fprintf(fout, "instrDescDsp per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescDsp)); + fprintf(fout, "instrDesc per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDesc)); + fprintf(fout, "instrDescCns per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCns)); + fprintf(fout, "instrDescDsp per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescDsp)); fprintf(fout, "instrDescCnsDsp per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCnsDsp)); #ifdef TARGET_XARCH - fprintf(fout, "instrDescAmd per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescAmd)); + fprintf(fout, "instrDescAmd per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescAmd)); fprintf(fout, "instrDescCnsAmd per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCnsAmd)); #endif // TARGET_XARCH - fprintf(fout, "instrDescCGCA per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCGCA)); #ifdef TARGET_ARM - fprintf(fout, "instrDescReloc per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescReloc)); + fprintf(fout, "instrDescReloc per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescReloc)); #endif // TARGET_ARM +#if FEATURE_LOOP_ALIGN + fprintf(fout, "instrDescAlign per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescAlign)); +#endif // FEATURE_LOOP_ALIGN + fprintf(fout, "instrDescJmp per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescJmp)); +#if !defined(TARGET_ARM64) + fprintf(fout, "instrDescLbl per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescLbl)); +#endif // !defined(TARGET_ARM64) + fprintf(fout, "instrDescCGCA per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCGCA)); fprintf(fout, "\n"); fprintf(fout, "GCInfo::regPtrDsc:\n"); fprintf(fout, "Offset of rpdNext = %2zu\n", offsetof(GCInfo::regPtrDsc, rpdNext)); fprintf(fout, "Offset of rpdOffs = %2zu\n", offsetof(GCInfo::regPtrDsc, rpdOffs)); fprintf(fout, "Offset of = %2zu\n", offsetof(GCInfo::regPtrDsc, rpdPtrArg)); - fprintf(fout, "Size of GCInfo::regPtrDsc = %2zu\n", sizeof(GCInfo::regPtrDsc)); + fprintf(fout, "Size of GCInfo::regPtrDsc = %2zu\n", sizeof(GCInfo::regPtrDsc)); fprintf(fout, "\n"); } diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 70e947ae254003..352e437cc0f0ea 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -323,7 +323,10 @@ struct insGroup // Try to do better packing based on how large regMaskSmall is (8, 16, or 64 bits). CLANG_FORMAT_COMMENT_ANCHOR; -#if REGMASK_BITS <= 32 + +#if !(REGMASK_BITS <= 32) + regMaskSmall igGCregs; // set of registers with live GC refs +#endif // !(REGMASK_BITS <= 32) union { BYTE* igData; // addr of instruction descriptors @@ -334,37 +337,18 @@ struct insGroup // Last instruction in group, if any (nullptr if none); used for backwards navigation. // (Should be type emitter::instrDesc*). void* igLastIns; -#endif +#endif // EMIT_BACKWARDS_NAVIGATION #if EMIT_TRACK_STACK_DEPTH unsigned igStkLvl; // stack level on entry -#endif - regMaskSmall igGCregs; // set of registers with live GC refs - unsigned char igInsCnt; // # of instructions in this group - -#else // REGMASK_BITS +#endif // EMIT_TRACK_STACK_DEPTH +#if REGMASK_BITS <= 32 regMaskSmall igGCregs; // set of registers with live GC refs - - union { - BYTE* igData; // addr of instruction descriptors - insPlaceholderGroupData* igPhData; // when igFlags & IGF_PLACEHOLDER - }; - -#if EMIT_BACKWARDS_NAVIGATION - // Last instruction in group, if any (nullptr if none); used for backwards navigation. - // (Should be type emitter::instrDesc*). - void* igLastIns; -#endif - -#if EMIT_TRACK_STACK_DEPTH - unsigned igStkLvl; // stack level on entry -#endif +#endif // REGMASK_BITS <= 32 unsigned char igInsCnt; // # of instructions in this group -#endif // REGMASK_BITS - VARSET_VALRET_TP igGCvars() const { assert(igFlags & IGF_GC_VARS); @@ -3262,8 +3246,6 @@ class emitter { emitPow2CnsCnt++; } - - } void TrackSmallCns(cnsval_ssize_t value) From f2e70c1f80ef1e24054b866719bfc7149150d91d Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 12 Jun 2023 07:22:30 -0700 Subject: [PATCH 7/9] Ensure the EMITTER_STATS header covers all the instrDesc types --- src/coreclr/jit/emit.cpp | 67 +++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 70cdfcff79973f..b30cc8452575a5 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -315,49 +315,58 @@ void emitterStaticStats(FILE* fout) fprintf(fout, "Size of insPlaceholderGroupData = %zu\n", sizeof(insPlaceholderGroupData)); fprintf(fout, "\n"); - fprintf(fout, "SMALL_IDSC_SIZE = %2u\n", SMALL_IDSC_SIZE); - fprintf(fout, "Size of instrDesc = %2zu\n", sizeof(emitter::instrDesc)); - fprintf(fout, "Size of instrDescCns = %2zu\n", sizeof(emitter::instrDescCns)); - fprintf(fout, "Size of instrDescDsp = %2zu\n", sizeof(emitter::instrDescDsp)); - fprintf(fout, "Size of instrDescCnsDsp = %2zu\n", sizeof(emitter::instrDescCnsDsp)); -#ifdef TARGET_XARCH - fprintf(fout, "Size of instrDescAmd = %2zu\n", sizeof(emitter::instrDescAmd)); - fprintf(fout, "Size of instrDescCnsAmd = %2zu\n", sizeof(emitter::instrDescCnsAmd)); -#endif // TARGET_XARCH + fprintf(fout, "SMALL_IDSC_SIZE = %2u\n", SMALL_IDSC_SIZE); + fprintf(fout, "Size of instrDesc = %2zu\n", sizeof(emitter::instrDesc)); + fprintf(fout, "Size of instrDescCns = %2zu\n", sizeof(emitter::instrDescCns)); + fprintf(fout, "Size of instrDescDsp = %2zu\n", sizeof(emitter::instrDescDsp)); +#ifdef TARGET_ARM64 + fprintf(fout, "Size of instrDescLclVarPair = %2zu\n", sizeof(emitter::instrDescLclVarPair)); + fprintf(fout, "Size of instrDescLclVarPairCns = %2zu\n", sizeof(emitter::instrDescLclVarPairCns)); +#endif // TARGET_ARM64 #ifdef TARGET_ARM - fprintf(fout, "Size of instrDescReloc = %2zu\n", sizeof(emitter::instrDescReloc)); + fprintf(fout, "Size of instrDescReloc = %2zu\n", sizeof(emitter::instrDescReloc)); #endif // TARGET_ARM +#ifdef TARGET_XARCH + fprintf(fout, "Size of instrDescAmd = %2zu\n", sizeof(emitter::instrDescAmd)); + fprintf(fout, "Size of instrDescCnsAmd = %2zu\n", sizeof(emitter::instrDescCnsAmd)); +#endif // TARGET_XARCH + fprintf(fout, "Size of instrDescCnsDsp = %2zu\n", sizeof(emitter::instrDescCnsDsp)); #if FEATURE_LOOP_ALIGN - fprintf(fout, "Size of instrDescAlign = %2zu\n", sizeof(emitter::instrDescAlign)); + fprintf(fout, "Size of instrDescAlign = %2zu\n", sizeof(emitter::instrDescAlign)); #endif // FEATURE_LOOP_ALIGN - fprintf(fout, "Size of instrDescJmp = %2zu\n", sizeof(emitter::instrDescJmp)); + fprintf(fout, "Size of instrDescJmp = %2zu\n", sizeof(emitter::instrDescJmp)); #if !defined(TARGET_ARM64) - fprintf(fout, "Size of instrDescLbl = %2zu\n", sizeof(emitter::instrDescLbl)); + fprintf(fout, "Size of instrDescLbl = %2zu\n", sizeof(emitter::instrDescLbl)); #endif // !defined(TARGET_ARM64) - fprintf(fout, "Size of instrDescCGCA = %2zu\n", sizeof(emitter::instrDescCGCA)); + fprintf(fout, "Size of instrDescCGCA = %2zu\n", sizeof(emitter::instrDescCGCA)); fprintf(fout, "\n"); - fprintf(fout, "igBuffSize = %2zu\n", igBuffSize); - fprintf(fout, "SMALL_IDSC_SIZE per IG buffer = %2zu\n", igBuffSize / SMALL_IDSC_SIZE); - fprintf(fout, "instrDesc per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDesc)); - fprintf(fout, "instrDescCns per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCns)); - fprintf(fout, "instrDescDsp per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescDsp)); - fprintf(fout, "instrDescCnsDsp per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCnsDsp)); -#ifdef TARGET_XARCH - fprintf(fout, "instrDescAmd per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescAmd)); - fprintf(fout, "instrDescCnsAmd per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCnsAmd)); -#endif // TARGET_XARCH + fprintf(fout, "igBuffSize = %2zu\n", igBuffSize); + fprintf(fout, "SMALL_IDSC_SIZE per IG buffer = %2zu\n", igBuffSize / SMALL_IDSC_SIZE); + fprintf(fout, "instrDesc per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDesc)); + fprintf(fout, "instrDescCns per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCns)); + fprintf(fout, "instrDescDsp per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescDsp)); +#ifdef TARGET_ARM64 + fprintf(fout, "instrDescLclVarPair per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescLclVarPair)); + fprintf(fout, "instrDescLclVarPairCns per IG buffer = %2zu\n", + igBuffSize / sizeof(emitter::instrDescLclVarPairCns)); +#endif // TARGET_ARM64 #ifdef TARGET_ARM - fprintf(fout, "instrDescReloc per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescReloc)); + fprintf(fout, "instrDescReloc per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescReloc)); #endif // TARGET_ARM +#ifdef TARGET_XARCH + fprintf(fout, "instrDescAmd per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescAmd)); + fprintf(fout, "instrDescCnsAmd per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCnsAmd)); +#endif // TARGET_XARCH + fprintf(fout, "instrDescCnsDsp per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCnsDsp)); #if FEATURE_LOOP_ALIGN - fprintf(fout, "instrDescAlign per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescAlign)); + fprintf(fout, "instrDescAlign per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescAlign)); #endif // FEATURE_LOOP_ALIGN - fprintf(fout, "instrDescJmp per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescJmp)); + fprintf(fout, "instrDescJmp per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescJmp)); #if !defined(TARGET_ARM64) - fprintf(fout, "instrDescLbl per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescLbl)); + fprintf(fout, "instrDescLbl per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescLbl)); #endif // !defined(TARGET_ARM64) - fprintf(fout, "instrDescCGCA per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCGCA)); + fprintf(fout, "instrDescCGCA per IG buffer = %2zu\n", igBuffSize / sizeof(emitter::instrDescCGCA)); fprintf(fout, "\n"); fprintf(fout, "GCInfo::regPtrDsc:\n"); From 645fb4900ca0378d8215089efb6a07497472567d Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 12 Jun 2023 07:34:50 -0700 Subject: [PATCH 8/9] Ensure that instrDesc counts are all being tracked by EMITTER_STATS --- src/coreclr/jit/emit.cpp | 77 +++++++++++++++++++++++----------------- src/coreclr/jit/emit.h | 33 +++++++++++------ 2 files changed, 67 insertions(+), 43 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index b30cc8452575a5..d4381ad62e6fb1 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -180,21 +180,28 @@ unsigned emitter::emitTotalIGExtend; unsigned emitter::emitTotalIDescSmallCnt; unsigned emitter::emitTotalIDescCnt; -unsigned emitter::emitTotalIDescJmpCnt; -#if !defined(TARGET_ARM64) -unsigned emitter::emitTotalIDescLblCnt; -#endif // !defined(TARGET_ARM64) unsigned emitter::emitTotalIDescCnsCnt; unsigned emitter::emitTotalIDescDspCnt; -unsigned emitter::emitTotalIDescCnsDspCnt; +#ifdef TARGET_ARM64 +unsigned emitter::emitTotalIDescLclVarPairCnt; +unsigned emitter::emitTotalIDescLclVarPairCnsCnt; +#endif // TARGET_ARM64 +#ifdef TARGET_ARM +unsigned emitter::emitTotalIDescRelocCnt; +#endif // TARGET_ARM #ifdef TARGET_XARCH unsigned emitter::emitTotalIDescAmdCnt; unsigned emitter::emitTotalIDescCnsAmdCnt; #endif // TARGET_XARCH +unsigned emitter::emitTotalIDescCnsDspCnt; +#if FEATURE_LOOP_ALIGN +unsigned emitter::emitTotalIDescAlignCnt; +#endif // FEATURE_LOOP_ALIGN +unsigned emitter::emitTotalIDescJmpCnt; +#if !defined(TARGET_ARM64) +unsigned emitter::emitTotalIDescLblCnt; +#endif // !defined(TARGET_ARM64) unsigned emitter::emitTotalIDescCGCACnt; -#ifdef TARGET_ARM -unsigned emitter::emitTotalIDescRelocCnt; -#endif // TARGET_ARM unsigned emitter::emitSmallDspCnt; unsigned emitter::emitLargeDspCnt; @@ -208,8 +215,6 @@ unsigned emitter::emitInt32CnsCnt; unsigned emitter::emitNegCnsCnt; unsigned emitter::emitPow2CnsCnt; -unsigned emitter::emitTotalDescAlignCnt; - void emitterStaticStats(FILE* fout) { // The IG buffer size depends on whether we are storing a debug info pointer or not. For our purposes @@ -465,37 +470,45 @@ void emitterStats(FILE* fout) fprintf(fout, "A total of %8zu desc. bytes\n", emitter::emitTotalIGsize); fprintf(fout, "\n"); - fprintf(fout, "Total instructions: %8u\n", emitter::emitTotalInsCnt); - fprintf(fout, "Total small instrDesc: %8u (%5.2f%%)\n", emitter::emitTotalIDescSmallCnt, + fprintf(fout, "Total instructions: %8u\n", emitter::emitTotalInsCnt); + fprintf(fout, "Total small instrDesc: %8u (%5.2f%%)\n", emitter::emitTotalIDescSmallCnt, 100.0 * emitter::emitTotalIDescSmallCnt / emitter::emitTotalInsCnt); - fprintf(fout, "Total instrDesc: %8u (%5.2f%%)\n", emitter::emitTotalIDescCnt, + fprintf(fout, "Total instrDesc: %8u (%5.2f%%)\n", emitter::emitTotalIDescCnt, 100.0 * emitter::emitTotalIDescCnt / emitter::emitTotalInsCnt); - fprintf(fout, "Total instrDescJmp: %8u (%5.2f%%)\n", emitter::emitTotalIDescJmpCnt, - 100.0 * emitter::emitTotalIDescJmpCnt / emitter::emitTotalInsCnt); -#if !defined(TARGET_ARM64) - fprintf(fout, "Total instrDescLbl: %8u (%5.2f%%)\n", emitter::emitTotalIDescLblCnt, - 100.0 * emitter::emitTotalIDescLblCnt / emitter::emitTotalInsCnt); -#endif // !defined(TARGET_ARM64) - fprintf(fout, "Total instrDescCns: %8u (%5.2f%%)\n", emitter::emitTotalIDescCnsCnt, + fprintf(fout, "Total instrDescCns: %8u (%5.2f%%)\n", emitter::emitTotalIDescCnsCnt, 100.0 * emitter::emitTotalIDescCnsCnt / emitter::emitTotalInsCnt); - fprintf(fout, "Total instrDescDsp: %8u (%5.2f%%)\n", emitter::emitTotalIDescDspCnt, + fprintf(fout, "Total instrDescDsp: %8u (%5.2f%%)\n", emitter::emitTotalIDescDspCnt, 100.0 * emitter::emitTotalIDescDspCnt / emitter::emitTotalInsCnt); - fprintf(fout, "Total instrDescCnsDsp: %8u (%5.2f%%)\n", emitter::emitTotalIDescCnsDspCnt, - 100.0 * emitter::emitTotalIDescCnsDspCnt / emitter::emitTotalInsCnt); +#ifdef TARGET_ARM64 + fprintf(fout, "Total instrDescLclVarPair: %8u (%5.2f%%)\n", emitter::emitTotalIDescLclVarPairCnt, + 100.0 * emitter::emitTotalIDescLclVarPairCnt / emitter::emitTotalInsCnt); + fprintf(fout, "Total instrDescLclVarPairCns: %8u (%5.2f%%)\n", emitter::emitTotalIDescLclVarPairCnsCnt, + 100.0 * emitter::emitTotalIDescLclVarPairCnsCnt / emitter::emitTotalInsCnt); +#endif // TARGET_ARM64 +#ifdef TARGET_ARM + fprintf(fout, "Total instrDescReloc: %8u (%5.2f%%)\n", emitter::emitTotalIDescRelocCnt, + 100.0 * emitter::emitTotalIDescRelocCnt / emitter::emitTotalInsCnt); +#endif // TARGET_ARM #ifdef TARGET_XARCH - fprintf(fout, "Total instrDescAmd: %8u (%5.2f%%)\n", emitter::emitTotalIDescAmdCnt, + fprintf(fout, "Total instrDescAmd: %8u (%5.2f%%)\n", emitter::emitTotalIDescAmdCnt, 100.0 * emitter::emitTotalIDescAmdCnt / emitter::emitTotalInsCnt); - fprintf(fout, "Total instrDescCnsAmd: %8u (%5.2f%%)\n", emitter::emitTotalIDescCnsAmdCnt, + fprintf(fout, "Total instrDescCnsAmd: %8u (%5.2f%%)\n", emitter::emitTotalIDescCnsAmdCnt, 100.0 * emitter::emitTotalIDescCnsAmdCnt / emitter::emitTotalInsCnt); #endif // TARGET_XARCH - fprintf(fout, "Total instrDescCGCA: %8u (%5.2f%%)\n", emitter::emitTotalIDescCGCACnt, + fprintf(fout, "Total instrDescCnsDsp: %8u (%5.2f%%)\n", emitter::emitTotalIDescCnsDspCnt, + 100.0 * emitter::emitTotalIDescCnsDspCnt / emitter::emitTotalInsCnt); +#if FEATURE_LOOP_ALIGN + fprintf(fout, "Total instrDescAlign: %8u (%5.2f%%)\n", emitter::emitTotalIDescAlignCnt, + 100.0 * emitter::emitTotalIDescAlignCnt / emitter::emitTotalInsCnt); +#endif // FEATURE_LOOP_ALIGN + fprintf(fout, "Total instrDescJmp: %8u (%5.2f%%)\n", emitter::emitTotalIDescJmpCnt, + 100.0 * emitter::emitTotalIDescJmpCnt / emitter::emitTotalInsCnt); +#if !defined(TARGET_ARM64) + fprintf(fout, "Total instrDescLbl: %8u (%5.2f%%)\n", emitter::emitTotalIDescLblCnt, + 100.0 * emitter::emitTotalIDescLblCnt / emitter::emitTotalInsCnt); +#endif // !defined(TARGET_ARM64) + fprintf(fout, "Total instrDescCGCA: %8u (%5.2f%%)\n", emitter::emitTotalIDescCGCACnt, 100.0 * emitter::emitTotalIDescCGCACnt / emitter::emitTotalInsCnt); -#ifdef TARGET_ARM - fprintf(fout, "Total instrDescReloc: %8u (%5.2f%%)\n", emitter::emitTotalIDescRelocCnt, - 100.0 * emitter::emitTotalIDescRelocCnt / emitter::emitTotalInsCnt); -#endif // TARGET_ARM - fprintf(fout, "Total instrDescAlign: %8u (%5.2f%%)\n", emitter::emitTotalDescAlignCnt, - 100.0 * emitter::emitTotalDescAlignCnt / emitter::emitTotalInsCnt); fprintf(fout, "\n"); } diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 352e437cc0f0ea..41639cc769f645 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -2754,6 +2754,9 @@ class emitter #if defined(TARGET_ARM64) instrDescLclVarPair* emitAllocInstrLclVarPair(emitAttr attr) { +#if EMITTER_STATS + emitTotalIDescLclVarPairCnt++; +#endif // EMITTER_STATS instrDescLclVarPair* result = (instrDescLclVarPair*)emitAllocAnyInstr(sizeof(instrDescLclVarPair), attr); result->idSetIsLclVarPair(); return result; @@ -2761,6 +2764,9 @@ class emitter instrDescLclVarPairCns* emitAllocInstrLclVarPairCns(emitAttr attr, cnsval_size_t cns) { +#if EMITTER_STATS + emitTotalIDescLclVarPairCnsCnt++; +#endif // EMITTER_STATS instrDescLclVarPairCns* result = (instrDescLclVarPairCns*)emitAllocAnyInstr(sizeof(instrDescLclVarPairCns), attr); result->idSetIsLargeCns(); @@ -2834,7 +2840,7 @@ class emitter instrDescAlign* emitAllocInstrAlign() { #if EMITTER_STATS - emitTotalDescAlignCnt++; + emitTotalIDescAlignCnt++; #endif // EMITTER_STATS return (instrDescAlign*)emitAllocAnyInstr(sizeof(instrDescAlign), EA_1BYTE); } @@ -3175,21 +3181,28 @@ class emitter static unsigned emitTotalIDescSmallCnt; static unsigned emitTotalIDescCnt; - static unsigned emitTotalIDescJmpCnt; -#if !defined(TARGET_ARM64) - static unsigned emitTotalIDescLblCnt; -#endif // !defined(TARGET_ARM64) static unsigned emitTotalIDescCnsCnt; static unsigned emitTotalIDescDspCnt; - static unsigned emitTotalIDescCnsDspCnt; +#ifdef TARGET_ARM64 + static unsigned emitTotalIDescLclVarPairCnt; + static unsigned emitTotalIDescLclVarPairCnsCnt; +#endif // TARGET_ARM64 +#ifdef TARGET_ARM + static unsigned emitTotalIDescRelocCnt; +#endif // TARGET_ARM #ifdef TARGET_XARCH static unsigned emitTotalIDescAmdCnt; static unsigned emitTotalIDescCnsAmdCnt; #endif // TARGET_XARCH + static unsigned emitTotalIDescCnsDspCnt; +#if FEATURE_LOOP_ALIGN + static unsigned emitTotalIDescAlignCnt; +#endif // FEATURE_LOOP_ALIGN + static unsigned emitTotalIDescJmpCnt; +#if !defined(TARGET_ARM64) + static unsigned emitTotalIDescLblCnt; +#endif // !defined(TARGET_ARM64) static unsigned emitTotalIDescCGCACnt; -#ifdef TARGET_ARM - static unsigned emitTotalIDescRelocCnt; -#endif // TARGET_ARM static size_t emitTotMemAlloc; @@ -3206,8 +3219,6 @@ class emitter static unsigned emitNegCnsCnt; static unsigned emitPow2CnsCnt; - static unsigned emitTotalDescAlignCnt; - static unsigned emitIFcounts[IF_COUNT]; void TrackCns(cnsval_ssize_t value) From d1db261ade1a907bca27a1cfeb0d0c49f0c9b78f Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 19 Jun 2023 14:55:10 -0700 Subject: [PATCH 9/9] Apply suggestions from code review Co-authored-by: Bruce Forstall --- src/coreclr/jit/emit.cpp | 2 +- src/coreclr/jit/emit.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index d4381ad62e6fb1..e82b5f01cbebc0 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -560,7 +560,7 @@ void emitterStats(FILE* fout) if (c >= m) { - // We make and assumption that MIN is negative and MAX is positive + // We make an assumption that MIN is negative and MAX is positive assert((ID_MIN_SMALL_CNS < 0) && (ID_MAX_SMALL_CNS > 0)); // Adjust the index to match the allowed value range diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 41639cc769f645..0602a67784370a 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -890,7 +890,7 @@ class emitter #define ID_MAX_SMALL_CNS (int)(ID_CNT_SMALL_CNS - ID_ADJ_SMALL_CNS - 1) // We encounter many constants, but there is a disproportionate amount that are in the range [-1, +4] - // and otherwise powers of 2. We therefore allow the tracked range here to incldue negative values. + // and otherwise powers of 2. We therefore allow the tracked range here to include negative values. signed _idSmallCns : ID_BIT_SMALL_CNS; ////////////////////////////////////////////////////////////////////////