diff options
author | Bruce Forstall <brucefo@microsoft.com> | 2019-03-21 13:50:53 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-21 13:50:53 -0700 |
commit | ceca0a77e8b48e30f9c6b67d2992c3276aba2177 (patch) | |
tree | 0c84536f7ef6a2f3beb18a211f71b7238a73964a | |
parent | 9497b0c77819d7b64a0f3c8bf22921182c99c09d (diff) | |
parent | db98a132c216cf561b74a3cb86980e3f22d80852 (diff) | |
download | coreclr-ceca0a77e8b48e30f9c6b67d2992c3276aba2177.tar.gz coreclr-ceca0a77e8b48e30f9c6b67d2992c3276aba2177.tar.bz2 coreclr-ceca0a77e8b48e30f9c6b67d2992c3276aba2177.zip |
Merge pull request #23369 from BruceForstall/UpdateStaticStats
Update emitter statistics
-rw-r--r-- | src/jit/block.cpp | 140 | ||||
-rw-r--r-- | src/jit/block.h | 2 | ||||
-rw-r--r-- | src/jit/compiler.cpp | 106 | ||||
-rw-r--r-- | src/jit/emit.cpp | 225 | ||||
-rw-r--r-- | src/jit/emit.h | 142 | ||||
-rw-r--r-- | src/jit/emitarm.cpp | 4 | ||||
-rw-r--r-- | src/jit/emitarm64.cpp | 2 | ||||
-rw-r--r-- | src/jit/emitxarch.cpp | 28 |
8 files changed, 440 insertions, 209 deletions
diff --git a/src/jit/block.cpp b/src/jit/block.cpp index 9598366828..8d1a83f5b4 100644 --- a/src/jit/block.cpp +++ b/src/jit/block.cpp @@ -1357,3 +1357,143 @@ BasicBlock* Compiler::bbNewBasicBlock(BBjumpKinds jumpKind) return block; } + +//------------------------------------------------------------------------------ +// DisplayStaticSizes: display various static sizes of the BasicBlock data structure. +// +// Arguments: +// fout - where to write the output +// +// Return Value: +// None +// +// Note: This function only does something if MEASURE_BLOCK_SIZE is defined, which it might +// be in private Release builds. +// +/* static */ +void BasicBlock::DisplayStaticSizes(FILE* fout) +{ +#if MEASURE_BLOCK_SIZE + + BasicBlock* bbDummy = nullptr; + + fprintf(fout, "\n"); + fprintf(fout, "Offset / size of bbNext = %3u / %3u\n", offsetof(BasicBlock, bbNext), + sizeof(bbDummy->bbNext)); + fprintf(fout, "Offset / size of bbPrev = %3u / %3u\n", offsetof(BasicBlock, bbPrev), + sizeof(bbDummy->bbPrev)); + fprintf(fout, "Offset / size of bbFlags = %3u / %3u\n", offsetof(BasicBlock, bbFlags), + sizeof(bbDummy->bbFlags)); + fprintf(fout, "Offset / size of bbNum = %3u / %3u\n", offsetof(BasicBlock, bbNum), + sizeof(bbDummy->bbNum)); + fprintf(fout, "Offset / size of bbPostOrderNum = %3u / %3u\n", offsetof(BasicBlock, bbPostOrderNum), + sizeof(bbDummy->bbPostOrderNum)); + fprintf(fout, "Offset / size of bbRefs = %3u / %3u\n", offsetof(BasicBlock, bbRefs), + sizeof(bbDummy->bbRefs)); + fprintf(fout, "Offset / size of bbWeight = %3u / %3u\n", offsetof(BasicBlock, bbWeight), + sizeof(bbDummy->bbWeight)); + fprintf(fout, "Offset / size of bbJumpKind = %3u / %3u\n", offsetof(BasicBlock, bbJumpKind), + sizeof(bbDummy->bbJumpKind)); + fprintf(fout, "Offset / size of bbJumpOffs = %3u / %3u\n", offsetof(BasicBlock, bbJumpOffs), + sizeof(bbDummy->bbJumpOffs)); + fprintf(fout, "Offset / size of bbJumpDest = %3u / %3u\n", offsetof(BasicBlock, bbJumpDest), + sizeof(bbDummy->bbJumpDest)); + fprintf(fout, "Offset / size of bbJumpSwt = %3u / %3u\n", offsetof(BasicBlock, bbJumpSwt), + sizeof(bbDummy->bbJumpSwt)); + fprintf(fout, "Offset / size of bbEntryState = %3u / %3u\n", offsetof(BasicBlock, bbEntryState), + sizeof(bbDummy->bbEntryState)); + fprintf(fout, "Offset / size of bbStkTempsIn = %3u / %3u\n", offsetof(BasicBlock, bbStkTempsIn), + sizeof(bbDummy->bbStkTempsIn)); + fprintf(fout, "Offset / size of bbStkTempsOut = %3u / %3u\n", offsetof(BasicBlock, bbStkTempsOut), + sizeof(bbDummy->bbStkTempsOut)); + fprintf(fout, "Offset / size of bbTryIndex = %3u / %3u\n", offsetof(BasicBlock, bbTryIndex), + sizeof(bbDummy->bbTryIndex)); + fprintf(fout, "Offset / size of bbHndIndex = %3u / %3u\n", offsetof(BasicBlock, bbHndIndex), + sizeof(bbDummy->bbHndIndex)); + fprintf(fout, "Offset / size of bbCatchTyp = %3u / %3u\n", offsetof(BasicBlock, bbCatchTyp), + sizeof(bbDummy->bbCatchTyp)); + fprintf(fout, "Offset / size of bbStkDepth = %3u / %3u\n", offsetof(BasicBlock, bbStkDepth), + sizeof(bbDummy->bbStkDepth)); + fprintf(fout, "Offset / size of bbFPinVars = %3u / %3u\n", offsetof(BasicBlock, bbFPinVars), + sizeof(bbDummy->bbFPinVars)); + fprintf(fout, "Offset / size of bbCheapPreds = %3u / %3u\n", offsetof(BasicBlock, bbCheapPreds), + sizeof(bbDummy->bbCheapPreds)); + fprintf(fout, "Offset / size of bbPreds = %3u / %3u\n", offsetof(BasicBlock, bbPreds), + sizeof(bbDummy->bbPreds)); + fprintf(fout, "Offset / size of bbReach = %3u / %3u\n", offsetof(BasicBlock, bbReach), + sizeof(bbDummy->bbReach)); + fprintf(fout, "Offset / size of bbIDom = %3u / %3u\n", offsetof(BasicBlock, bbIDom), + sizeof(bbDummy->bbIDom)); + fprintf(fout, "Offset / size of bbDfsNum = %3u / %3u\n", offsetof(BasicBlock, bbDfsNum), + sizeof(bbDummy->bbDfsNum)); + fprintf(fout, "Offset / size of bbCodeOffs = %3u / %3u\n", offsetof(BasicBlock, bbCodeOffs), + sizeof(bbDummy->bbCodeOffs)); + fprintf(fout, "Offset / size of bbCodeOffsEnd = %3u / %3u\n", offsetof(BasicBlock, bbCodeOffsEnd), + sizeof(bbDummy->bbCodeOffsEnd)); + fprintf(fout, "Offset / size of bbVarUse = %3u / %3u\n", offsetof(BasicBlock, bbVarUse), + sizeof(bbDummy->bbVarUse)); + fprintf(fout, "Offset / size of bbVarDef = %3u / %3u\n", offsetof(BasicBlock, bbVarDef), + sizeof(bbDummy->bbVarDef)); + fprintf(fout, "Offset / size of bbLiveIn = %3u / %3u\n", offsetof(BasicBlock, bbLiveIn), + sizeof(bbDummy->bbLiveIn)); + fprintf(fout, "Offset / size of bbLiveOut = %3u / %3u\n", offsetof(BasicBlock, bbLiveOut), + sizeof(bbDummy->bbLiveOut)); + // Can't do bitfield bbMemoryUse, bbMemoryDef, bbMemoryLiveIn, bbMemoryLiveOut, bbMemoryHavoc + fprintf(fout, "Offset / size of bbMemorySsaPhiFunc = %3u / %3u\n", offsetof(BasicBlock, bbMemorySsaPhiFunc), + sizeof(bbDummy->bbMemorySsaPhiFunc)); + fprintf(fout, "Offset / size of bbMemorySsaNumIn = %3u / %3u\n", offsetof(BasicBlock, bbMemorySsaNumIn), + sizeof(bbDummy->bbMemorySsaNumIn)); + fprintf(fout, "Offset / size of bbMemorySsaNumOut = %3u / %3u\n", offsetof(BasicBlock, bbMemorySsaNumOut), + sizeof(bbDummy->bbMemorySsaNumOut)); + fprintf(fout, "Offset / size of bbScope = %3u / %3u\n", offsetof(BasicBlock, bbScope), + sizeof(bbDummy->bbScope)); + fprintf(fout, "Offset / size of bbCseGen = %3u / %3u\n", offsetof(BasicBlock, bbCseGen), + sizeof(bbDummy->bbCseGen)); +#if ASSERTION_PROP + fprintf(fout, "Offset / size of bbAssertionGen = %3u / %3u\n", offsetof(BasicBlock, bbAssertionGen), + sizeof(bbDummy->bbAssertionGen)); +#endif // ASSERTION_PROP + fprintf(fout, "Offset / size of bbCseIn = %3u / %3u\n", offsetof(BasicBlock, bbCseIn), + sizeof(bbDummy->bbCseIn)); +#if ASSERTION_PROP + fprintf(fout, "Offset / size of bbAssertionIn = %3u / %3u\n", offsetof(BasicBlock, bbAssertionIn), + sizeof(bbDummy->bbAssertionIn)); +#endif // ASSERTION_PROP + fprintf(fout, "Offset / size of bbCseOut = %3u / %3u\n", offsetof(BasicBlock, bbCseOut), + sizeof(bbDummy->bbCseOut)); +#if ASSERTION_PROP + fprintf(fout, "Offset / size of bbAssertionOut = %3u / %3u\n", offsetof(BasicBlock, bbAssertionOut), + sizeof(bbDummy->bbAssertionOut)); +#endif // ASSERTION_PROP + fprintf(fout, "Offset / size of bbEmitCookie = %3u / %3u\n", offsetof(BasicBlock, bbEmitCookie), + sizeof(bbDummy->bbEmitCookie)); + +#if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_) + fprintf(fout, "Offset / size of bbUnwindNopEmitCookie = %3u / %3u\n", offsetof(BasicBlock, bbUnwindNopEmitCookie), + sizeof(bbDummy->bbUnwindNopEmitCookie)); +#endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_) + +#ifdef VERIFIER + fprintf(fout, "Offset / size of bbStackIn = %3u / %3u\n", offsetof(BasicBlock, bbStackIn), + sizeof(bbDummy->bbStackIn)); + fprintf(fout, "Offset / size of bbStackOut = %3u / %3u\n", offsetof(BasicBlock, bbStackOut), + sizeof(bbDummy->bbStackOut)); + fprintf(fout, "Offset / size of bbTypesIn = %3u / %3u\n", offsetof(BasicBlock, bbTypesIn), + sizeof(bbDummy->bbTypesIn)); + fprintf(fout, "Offset / size of bbTypesOut = %3u / %3u\n", offsetof(BasicBlock, bbTypesOut), + sizeof(bbDummy->bbTypesOut)); +#endif // VERIFIER + +#ifdef DEBUG + fprintf(fout, "Offset / size of bbLoopNum = %3u / %3u\n", offsetof(BasicBlock, bbLoopNum), + sizeof(bbDummy->bbLoopNum)); +#endif // DEBUG + + fprintf(fout, "Offset / size of bbNatLoopNum = %3u / %3u\n", offsetof(BasicBlock, bbNatLoopNum), + sizeof(bbDummy->bbNatLoopNum)); + + fprintf(fout, "\n"); + fprintf(fout, "Size of BasicBlock = %3u\n", sizeof(BasicBlock)); + +#endif // MEASURE_BLOCK_SIZE +} diff --git a/src/jit/block.h b/src/jit/block.h index d447429542..56b1c7313d 100644 --- a/src/jit/block.h +++ b/src/jit/block.h @@ -1183,6 +1183,8 @@ struct BasicBlock : private LIR::Range return false; } #endif // DEBUG + + static void DisplayStaticSizes(FILE* fout); }; template <> diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp index 3887f0ea98..7bb93a299d 100644 --- a/src/jit/compiler.cpp +++ b/src/jit/compiler.cpp @@ -1783,115 +1783,11 @@ void Compiler::compShutdown() /* static */ void Compiler::compDisplayStaticSizes(FILE* fout) { - #if MEASURE_NODE_SIZE GenTree::DumpNodeSizes(fout); #endif -#if MEASURE_BLOCK_SIZE - - BasicBlock* bbDummy = nullptr; - - fprintf(fout, "\n"); - fprintf(fout, "Offset / size of bbNext = %3u / %3u\n", offsetof(BasicBlock, bbNext), - sizeof(bbDummy->bbNext)); - fprintf(fout, "Offset / size of bbNum = %3u / %3u\n", offsetof(BasicBlock, bbNum), - sizeof(bbDummy->bbNum)); - fprintf(fout, "Offset / size of bbPostOrderNum = %3u / %3u\n", offsetof(BasicBlock, bbPostOrderNum), - sizeof(bbDummy->bbPostOrderNum)); - fprintf(fout, "Offset / size of bbRefs = %3u / %3u\n", offsetof(BasicBlock, bbRefs), - sizeof(bbDummy->bbRefs)); - fprintf(fout, "Offset / size of bbFlags = %3u / %3u\n", offsetof(BasicBlock, bbFlags), - sizeof(bbDummy->bbFlags)); - fprintf(fout, "Offset / size of bbWeight = %3u / %3u\n", offsetof(BasicBlock, bbWeight), - sizeof(bbDummy->bbWeight)); - fprintf(fout, "Offset / size of bbJumpKind = %3u / %3u\n", offsetof(BasicBlock, bbJumpKind), - sizeof(bbDummy->bbJumpKind)); - fprintf(fout, "Offset / size of bbJumpOffs = %3u / %3u\n", offsetof(BasicBlock, bbJumpOffs), - sizeof(bbDummy->bbJumpOffs)); - fprintf(fout, "Offset / size of bbJumpDest = %3u / %3u\n", offsetof(BasicBlock, bbJumpDest), - sizeof(bbDummy->bbJumpDest)); - fprintf(fout, "Offset / size of bbJumpSwt = %3u / %3u\n", offsetof(BasicBlock, bbJumpSwt), - sizeof(bbDummy->bbJumpSwt)); - fprintf(fout, "Offset / size of bbEntryState = %3u / %3u\n", offsetof(BasicBlock, bbEntryState), - sizeof(bbDummy->bbEntryState)); - fprintf(fout, "Offset / size of bbStkTempsIn = %3u / %3u\n", offsetof(BasicBlock, bbStkTempsIn), - sizeof(bbDummy->bbStkTempsIn)); - fprintf(fout, "Offset / size of bbStkTempsOut = %3u / %3u\n", offsetof(BasicBlock, bbStkTempsOut), - sizeof(bbDummy->bbStkTempsOut)); - fprintf(fout, "Offset / size of bbTryIndex = %3u / %3u\n", offsetof(BasicBlock, bbTryIndex), - sizeof(bbDummy->bbTryIndex)); - fprintf(fout, "Offset / size of bbHndIndex = %3u / %3u\n", offsetof(BasicBlock, bbHndIndex), - sizeof(bbDummy->bbHndIndex)); - fprintf(fout, "Offset / size of bbCatchTyp = %3u / %3u\n", offsetof(BasicBlock, bbCatchTyp), - sizeof(bbDummy->bbCatchTyp)); - fprintf(fout, "Offset / size of bbStkDepth = %3u / %3u\n", offsetof(BasicBlock, bbStkDepth), - sizeof(bbDummy->bbStkDepth)); - fprintf(fout, "Offset / size of bbFPinVars = %3u / %3u\n", offsetof(BasicBlock, bbFPinVars), - sizeof(bbDummy->bbFPinVars)); - fprintf(fout, "Offset / size of bbPreds = %3u / %3u\n", offsetof(BasicBlock, bbPreds), - sizeof(bbDummy->bbPreds)); - fprintf(fout, "Offset / size of bbReach = %3u / %3u\n", offsetof(BasicBlock, bbReach), - sizeof(bbDummy->bbReach)); - fprintf(fout, "Offset / size of bbIDom = %3u / %3u\n", offsetof(BasicBlock, bbIDom), - sizeof(bbDummy->bbIDom)); - fprintf(fout, "Offset / size of bbDfsNum = %3u / %3u\n", offsetof(BasicBlock, bbDfsNum), - sizeof(bbDummy->bbDfsNum)); - fprintf(fout, "Offset / size of bbCodeOffs = %3u / %3u\n", offsetof(BasicBlock, bbCodeOffs), - sizeof(bbDummy->bbCodeOffs)); - fprintf(fout, "Offset / size of bbCodeOffsEnd = %3u / %3u\n", offsetof(BasicBlock, bbCodeOffsEnd), - sizeof(bbDummy->bbCodeOffsEnd)); - fprintf(fout, "Offset / size of bbVarUse = %3u / %3u\n", offsetof(BasicBlock, bbVarUse), - sizeof(bbDummy->bbVarUse)); - fprintf(fout, "Offset / size of bbVarDef = %3u / %3u\n", offsetof(BasicBlock, bbVarDef), - sizeof(bbDummy->bbVarDef)); - fprintf(fout, "Offset / size of bbLiveIn = %3u / %3u\n", offsetof(BasicBlock, bbLiveIn), - sizeof(bbDummy->bbLiveIn)); - fprintf(fout, "Offset / size of bbLiveOut = %3u / %3u\n", offsetof(BasicBlock, bbLiveOut), - sizeof(bbDummy->bbLiveOut)); - fprintf(fout, "Offset / size of bbMemorySsaPhiFunc = %3u / %3u\n", offsetof(BasicBlock, bbMemorySsaPhiFunc), - sizeof(bbDummy->bbMemorySsaPhiFunc)); - fprintf(fout, "Offset / size of bbMemorySsaNumIn = %3u / %3u\n", offsetof(BasicBlock, bbMemorySsaNumIn), - sizeof(bbDummy->bbMemorySsaNumIn)); - fprintf(fout, "Offset / size of bbMemorySsaNumOut = %3u / %3u\n", offsetof(BasicBlock, bbMemorySsaNumOut), - sizeof(bbDummy->bbMemorySsaNumOut)); - fprintf(fout, "Offset / size of bbScope = %3u / %3u\n", offsetof(BasicBlock, bbScope), - sizeof(bbDummy->bbScope)); - fprintf(fout, "Offset / size of bbCseGen = %3u / %3u\n", offsetof(BasicBlock, bbCseGen), - sizeof(bbDummy->bbCseGen)); - fprintf(fout, "Offset / size of bbCseIn = %3u / %3u\n", offsetof(BasicBlock, bbCseIn), - sizeof(bbDummy->bbCseIn)); - fprintf(fout, "Offset / size of bbCseOut = %3u / %3u\n", offsetof(BasicBlock, bbCseOut), - sizeof(bbDummy->bbCseOut)); - - fprintf(fout, "Offset / size of bbEmitCookie = %3u / %3u\n", offsetof(BasicBlock, bbEmitCookie), - sizeof(bbDummy->bbEmitCookie)); - -#if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_) - fprintf(fout, "Offset / size of bbUnwindNopEmitCookie = %3u / %3u\n", offsetof(BasicBlock, bbUnwindNopEmitCookie), - sizeof(bbDummy->bbUnwindNopEmitCookie)); -#endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_) - -#ifdef VERIFIER - fprintf(fout, "Offset / size of bbStackIn = %3u / %3u\n", offsetof(BasicBlock, bbStackIn), - sizeof(bbDummy->bbStackIn)); - fprintf(fout, "Offset / size of bbStackOut = %3u / %3u\n", offsetof(BasicBlock, bbStackOut), - sizeof(bbDummy->bbStackOut)); - fprintf(fout, "Offset / size of bbTypesIn = %3u / %3u\n", offsetof(BasicBlock, bbTypesIn), - sizeof(bbDummy->bbTypesIn)); - fprintf(fout, "Offset / size of bbTypesOut = %3u / %3u\n", offsetof(BasicBlock, bbTypesOut), - sizeof(bbDummy->bbTypesOut)); -#endif // VERIFIER - -#ifdef DEBUG - fprintf(fout, "Offset / size of bbLoopNum = %3u / %3u\n", offsetof(BasicBlock, bbLoopNum), - sizeof(bbDummy->bbLoopNum)); -#endif // DEBUG - - fprintf(fout, "\n"); - fprintf(fout, "Size of BasicBlock = %3u\n", sizeof(BasicBlock)); - -#endif // MEASURE_BLOCK_SIZE + BasicBlock::DisplayStaticSizes(fout); #if EMITTER_STATS emitterStaticStats(fout); diff --git a/src/jit/emit.cpp b/src/jit/emit.cpp index 982417d9d6..daaf237849 100644 --- a/src/jit/emit.cpp +++ b/src/jit/emit.cpp @@ -267,6 +267,10 @@ size_t emitter::emitSizeMethod; size_t emitter::emitTotMemAlloc; unsigned emitter::emitTotalInsCnt; +unsigned emitter::emitCurPrologInsCnt; +size_t emitter::emitCurPrologIGSize; +unsigned emitter::emitMaxPrologInsCnt; +size_t emitter::emitMaxPrologIGSize; unsigned emitter::emitTotalIGcnt; unsigned emitter::emitTotalPhIGcnt; unsigned emitter::emitTotalIGjmps; @@ -274,6 +278,25 @@ unsigned emitter::emitTotalIGptrs; unsigned emitter::emitTotalIGicnt; size_t emitter::emitTotalIGsize; unsigned emitter::emitTotalIGmcnt; +unsigned emitter::emitTotalIGEmitAdd; + +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_XARCH_ +unsigned emitter::emitTotalIDescAmdCnt; +unsigned emitter::emitTotalIDescCnsAmdCnt; +#endif // _TARGET_XARCH_ +unsigned emitter::emitTotalIDescCGCACnt; +#ifdef _TARGET_ARM_ +unsigned emitter::emitTotalIDescRelocCnt; +#endif // _TARGET_ARM_ unsigned emitter::emitSmallDspCnt; unsigned emitter::emitLargeDspCnt; @@ -286,24 +309,40 @@ void emitterStaticStats(FILE* fout) { // insGroup members + insGroup* igDummy = nullptr; + fprintf(fout, "\n"); fprintf(fout, "insGroup:\n"); - fprintf(fout, "Offset of igNext = %2u\n", offsetof(insGroup, igNext)); + fprintf(fout, "Offset / size of igNext = %2u / %2u\n", offsetof(insGroup, igNext), + sizeof(igDummy->igNext)); #ifdef DEBUG - fprintf(fout, "Offset of igSelf = %2u\n", offsetof(insGroup, igSelf)); + fprintf(fout, "Offset / size of igSelf = %2u / %2u\n", offsetof(insGroup, igSelf), + sizeof(igDummy->igSelf)); #endif - fprintf(fout, "Offset of igNum = %2u\n", offsetof(insGroup, igNum)); - fprintf(fout, "Offset of igOffs = %2u\n", offsetof(insGroup, igOffs)); - fprintf(fout, "Offset of igFuncIdx = %2u\n", offsetof(insGroup, igFuncIdx)); - fprintf(fout, "Offset of igFlags = %2u\n", offsetof(insGroup, igFlags)); - fprintf(fout, "Offset of igSize = %2u\n", offsetof(insGroup, igSize)); - fprintf(fout, "Offset of igData = %2u\n", offsetof(insGroup, igData)); + fprintf(fout, "Offset / size of igNum = %2u / %2u\n", offsetof(insGroup, igNum), + sizeof(igDummy->igNum)); + fprintf(fout, "Offset / size of igOffs = %2u / %2u\n", offsetof(insGroup, igOffs), + sizeof(igDummy->igOffs)); + fprintf(fout, "Offset / size of igFuncIdx = %2u / %2u\n", offsetof(insGroup, igFuncIdx), + sizeof(igDummy->igFuncIdx)); + fprintf(fout, "Offset / size of igFlags = %2u / %2u\n", offsetof(insGroup, igFlags), + sizeof(igDummy->igFlags)); + fprintf(fout, "Offset / size of igSize = %2u / %2u\n", offsetof(insGroup, igSize), + sizeof(igDummy->igSize)); + fprintf(fout, "Offset / size of igData = %2u / %2u\n", offsetof(insGroup, igData), + sizeof(igDummy->igData)); + fprintf(fout, "Offset / size of igPhData = %2u / %2u\n", offsetof(insGroup, igPhData), + sizeof(igDummy->igPhData)); #if EMIT_TRACK_STACK_DEPTH - fprintf(fout, "Offset of igStkLvl = %2u\n", offsetof(insGroup, igStkLvl)); + fprintf(fout, "Offset / size of igStkLvl = %2u / %2u\n", offsetof(insGroup, igStkLvl), + sizeof(igDummy->igStkLvl)); #endif - fprintf(fout, "Offset of igGCregs = %2u\n", offsetof(insGroup, igGCregs)); - fprintf(fout, "Offset of igInsCnt = %2u\n", offsetof(insGroup, igInsCnt)); - fprintf(fout, "Size of insGroup = %u\n", sizeof(insGroup)); + fprintf(fout, "Offset / size of igGCregs = %2u / %2u\n", offsetof(insGroup, igGCregs), + sizeof(igDummy->igGCregs)); + fprintf(fout, "Offset / size of igInsCnt = %2u / %2u\n", offsetof(insGroup, igInsCnt), + sizeof(igDummy->igInsCnt)); + fprintf(fout, "\n"); + fprintf(fout, "Size of insGroup = %u\n", sizeof(insGroup)); // insPlaceholderGroupData members @@ -321,7 +360,8 @@ void emitterStaticStats(FILE* fout) fprintf(fout, "Size of insPlaceholderGroupData = %u\n", sizeof(insPlaceholderGroupData)); fprintf(fout, "\n"); - fprintf(fout, "Size of instrDesc = %2u\n", sizeof(emitter::instrDesc)); + fprintf(fout, "SMALL_IDSC_SIZE = %2u\n", SMALL_IDSC_SIZE); + fprintf(fout, "Size of instrDesc = %2u\n", sizeof(emitter::instrDesc)); // fprintf(fout, "Offset of _idIns = %2u\n", offsetof(emitter::instrDesc, _idIns )); // fprintf(fout, "Offset of _idInsFmt = %2u\n", offsetof(emitter::instrDesc, _idInsFmt )); // fprintf(fout, "Offset of _idOpSize = %2u\n", offsetof(emitter::instrDesc, _idOpSize )); @@ -330,6 +370,42 @@ void emitterStaticStats(FILE* fout) // fprintf(fout, "\n"); // fprintf(fout, "Size of _idAddrUnion= %2u\n", sizeof(((emitter::instrDesc*)0)->_idAddrUnion)); + fprintf(fout, "Size of instrDescJmp = %2u\n", sizeof(emitter::instrDescJmp)); +#if !defined(_TARGET_ARM64_) + fprintf(fout, "Size of instrDescLbl = %2u\n", sizeof(emitter::instrDescLbl)); +#endif // !defined(_TARGET_ARM64_) + fprintf(fout, "Size of instrDescCns = %2u\n", sizeof(emitter::instrDescCns)); + fprintf(fout, "Size of instrDescDsp = %2u\n", sizeof(emitter::instrDescDsp)); + fprintf(fout, "Size of instrDescCnsDsp = %2u\n", sizeof(emitter::instrDescCnsDsp)); +#ifdef _TARGET_XARCH_ + fprintf(fout, "Size of instrDescAmd = %2u\n", sizeof(emitter::instrDescAmd)); + fprintf(fout, "Size of instrDescCnsAmd = %2u\n", sizeof(emitter::instrDescCnsAmd)); +#endif // _TARGET_XARCH_ + fprintf(fout, "Size of instrDescCGCA = %2u\n", sizeof(emitter::instrDescCGCA)); +#ifdef _TARGET_ARM_ + fprintf(fout, "Size of instrDescReloc = %2u\n", sizeof(emitter::instrDescReloc)); +#endif // _TARGET_ARM_ + + fprintf(fout, "\n"); + fprintf(fout, "SC_IG_BUFFER_SIZE = %2u\n", SC_IG_BUFFER_SIZE); + fprintf(fout, "SMALL_IDSC_SIZE per IG buffer = %2u\n", SC_IG_BUFFER_SIZE / SMALL_IDSC_SIZE); + fprintf(fout, "instrDesc per IG buffer = %2u\n", SC_IG_BUFFER_SIZE / sizeof(emitter::instrDesc)); + fprintf(fout, "instrDescJmp per IG buffer = %2u\n", SC_IG_BUFFER_SIZE / sizeof(emitter::instrDescJmp)); +#if !defined(_TARGET_ARM64_) + fprintf(fout, "instrDescLbl per IG buffer = %2u\n", SC_IG_BUFFER_SIZE / sizeof(emitter::instrDescLbl)); +#endif // !defined(_TARGET_ARM64_) + fprintf(fout, "instrDescCns per IG buffer = %2u\n", SC_IG_BUFFER_SIZE / sizeof(emitter::instrDescCns)); + fprintf(fout, "instrDescDsp per IG buffer = %2u\n", SC_IG_BUFFER_SIZE / sizeof(emitter::instrDescDsp)); + fprintf(fout, "instrDescCnsDsp per IG buffer = %2u\n", SC_IG_BUFFER_SIZE / sizeof(emitter::instrDescCnsDsp)); +#ifdef _TARGET_XARCH_ + fprintf(fout, "instrDescAmd per IG buffer = %2u\n", SC_IG_BUFFER_SIZE / sizeof(emitter::instrDescAmd)); + fprintf(fout, "instrDescCnsAmd per IG buffer = %2u\n", SC_IG_BUFFER_SIZE / sizeof(emitter::instrDescCnsAmd)); +#endif // _TARGET_XARCH_ + fprintf(fout, "instrDescCGCA per IG buffer = %2u\n", SC_IG_BUFFER_SIZE / sizeof(emitter::instrDescCGCA)); +#ifdef _TARGET_ARM_ + fprintf(fout, "instrDescReloc per IG buffer = %2u\n", SC_IG_BUFFER_SIZE / sizeof(emitter::instrDescReloc)); +#endif // _TARGET_ARM_ + fprintf(fout, "\n"); fprintf(fout, "GCInfo::regPtrDsc:\n"); fprintf(fout, "Offset of rpdNext = %2u\n", offsetof(GCInfo::regPtrDsc, rpdNext)); @@ -356,7 +432,7 @@ void emitterStats(FILE* fout) fprintf(fout, "\n"); } - assert(emitter::emitTotalInsCnt); + assert(emitter::emitTotalInsCnt > 0); fprintf(fout, "Average of %4.2f bytes of code generated per instruction\n", (double)totActualSize / emitter::emitTotalInsCnt); @@ -378,26 +454,33 @@ void emitterStats(FILE* fout) if ((c > 0) && (1000 * c >= ic)) { dc += c; - fprintf(fout, " %-13s %8u (%5.2f%%)\n", emitter::emitIfName(f), c, 100.0 * c / ic); + fprintf(fout, " %-14s %8u (%5.2f%%)\n", emitter::emitIfName(f), c, 100.0 * c / ic); } } - fprintf(fout, " --------------------------------\n"); - fprintf(fout, " %-13s %8u (%5.2f%%)\n", "Total shown", dc, 100.0 * dc / ic); + fprintf(fout, " ---------------------------------\n"); + fprintf(fout, " %-14s %8u (%5.2f%%)\n", "Total shown", dc, 100.0 * dc / ic); - if (emitter::emitTotalIGmcnt) + if (emitter::emitTotalIGmcnt > 0) { + fprintf(fout, "\n"); fprintf(fout, "Total of %8u methods\n", emitter::emitTotalIGmcnt); fprintf(fout, "Total of %8u insGroup\n", emitter::emitTotalIGcnt); fprintf(fout, "Total of %8u insPlaceholderGroupData\n", emitter::emitTotalPhIGcnt); + fprintf(fout, "Total of %8u emitAdd insGroup\n", emitter::emitTotalIGEmitAdd); fprintf(fout, "Total of %8u instructions\n", emitter::emitTotalIGicnt); fprintf(fout, "Total of %8u jumps\n", emitter::emitTotalIGjmps); fprintf(fout, "Total of %8u GC livesets\n", emitter::emitTotalIGptrs); fprintf(fout, "\n"); + fprintf(fout, "Max prolog instrDesc count: %8u\n", emitter::emitMaxPrologInsCnt); + fprintf(fout, "Max prolog insGroup size : %8u\n", emitter::emitMaxPrologIGSize); + fprintf(fout, "\n"); fprintf(fout, "Average of %8.1lf insGroup per method\n", (double)emitter::emitTotalIGcnt / emitter::emitTotalIGmcnt); fprintf(fout, "Average of %8.1lf insPhGroup per method\n", (double)emitter::emitTotalPhIGcnt / emitter::emitTotalIGmcnt); + fprintf(fout, "Average of %8.1lf emitAdd IG per method\n", + (double)emitter::emitTotalIGEmitAdd / emitter::emitTotalIGmcnt); fprintf(fout, "Average of %8.1lf instructions per method\n", (double)emitter::emitTotalIGicnt / emitter::emitTotalIGmcnt); fprintf(fout, "Average of %8.1lf desc. bytes per method\n", @@ -419,6 +502,37 @@ void emitterStats(FILE* fout) fprintf(fout, "\n"); fprintf(fout, "A total of %8u 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, + 100.0 * emitter::emitTotalIDescSmallCnt / emitter::emitTotalInsCnt); + 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, + 100.0 * emitter::emitTotalIDescCnsCnt / emitter::emitTotalInsCnt); + 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_XARCH_ + 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, + 100.0 * emitter::emitTotalIDescCnsAmdCnt / emitter::emitTotalInsCnt); +#endif // _TARGET_XARCH_ + 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, "\n"); } fprintf(fout, "Descriptor size distribution:\n"); @@ -433,33 +547,37 @@ void emitterStats(FILE* fout) stkDepthTable.dump(fout); fprintf(fout, "\n"); - int i; - unsigned c; - unsigned m; - - if (emitter::emitSmallCnsCnt || emitter::emitLargeCnsCnt) + 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)); } -#if 0 - // TODO-Cleanup: WHy is this in #if 0 - Is EMITTER_STATS ever used? Fix or delete this. - if (emitter::emitSmallCnsCnt) + // Print out the most common small constants. + if (emitter::emitSmallCnsCnt > 0) { - fprintf(fout, "\n"); + fprintf(fout, "\n\n"); + fprintf(fout, "Common small constants >= %2u, <= %2u\n", ID_MIN_SMALL_CNS, ID_MAX_SMALL_CNS); - m = emitter::emitSmallCnsCnt/1000 + 1; + unsigned m = emitter::emitSmallCnsCnt / 1000 + 1; - for (i = ID_MIN_SMALL_CNS; i < ID_MAX_SMALL_CNS; i++) + for (int i = ID_MIN_SMALL_CNS; (i <= ID_MAX_SMALL_CNS) && (i < SMALL_CNS_TSZ); i++) { - c = emitter::emitSmallCns[i-ID_MIN_SMALL_CNS]; - if (c >= m) - fprintf(fout, "cns[%4d] = %u\n", i, c); + unsigned c = emitter::emitSmallCns[i - ID_MIN_SMALL_CNS]; + if (c >= m) + { + if (i == SMALL_CNS_TSZ - 1) + { + fprintf(fout, "cns[>=%4d] = %u\n", i, c); + } + else + { + fprintf(fout, "cns[%4d] = %u\n", i, c); + } + } } } -#endif // 0 fprintf(fout, "%8u bytes allocated in the emitter\n", emitter::emitTotMemAlloc); } @@ -789,6 +907,22 @@ insGroup* emitter::emitSavIG(bool emitAdd) emitTotalIGicnt += emitCurIGinsCnt; emitTotalIGsize += sz; emitSizeMethod += sz; + + if (emitIGisInProlog(ig)) + { + emitCurPrologInsCnt += emitCurIGinsCnt; + emitCurPrologIGSize += sz; + + // Keep track of the maximums. + if (emitCurPrologInsCnt > emitMaxPrologInsCnt) + { + emitMaxPrologInsCnt = emitCurPrologInsCnt; + } + if (emitCurPrologIGSize > emitMaxPrologIGSize) + { + emitMaxPrologIGSize = emitCurPrologIGSize; + } + } #endif // printf("Group [%08X]%3u has %2u instructions (%4u bytes at %08X)\n", ig, ig->igNum, emitCurIGinsCnt, sz, id); @@ -1019,7 +1153,9 @@ void emitter::emitBegFN(bool hasFramePtr #if EMITTER_STATS emitTotalIGmcnt++; - emitSizeMethod = 0; + emitSizeMethod = 0; + emitCurPrologInsCnt = 0; + emitCurPrologIGSize = 0; #endif emitInsCount = 0; @@ -1170,7 +1306,7 @@ size_t emitter::emitGenEpilogLst(size_t (*fp)(void*, unsigned), void* cp) * The following series of methods allocates instruction descriptors. */ -void* emitter::emitAllocInstr(size_t sz, emitAttr opsz) +void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) { instrDesc* id; @@ -2154,7 +2290,10 @@ emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, target_ssize_t cn #if EMITTER_STATS emitSmallCnsCnt++; - emitSmallCns[cns - ID_MIN_SMALL_CNS]++; + if ((cns - ID_MIN_SMALL_CNS) >= (SMALL_CNS_TSZ - 1)) + emitSmallCns[SMALL_CNS_TSZ - 1]++; + else + emitSmallCns[cns - ID_MIN_SMALL_CNS]++; emitSmallDspCnt++; #endif @@ -2162,10 +2301,7 @@ emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, target_ssize_t cn } else { - instrDescCns* id = emitAllocInstrCns(size); - - id->idSetIsLargeCns(); - id->idcCnsVal = cns; + instrDescCns* id = emitAllocInstrCns(size, cns); #if EMITTER_STATS emitLargeCnsCnt++; @@ -2189,7 +2325,10 @@ emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, target_ssize_t cn #if EMITTER_STATS emitLargeDspCnt++; emitSmallCnsCnt++; - emitSmallCns[cns - ID_MIN_SMALL_CNS]++; + if ((cns - ID_MIN_SMALL_CNS) >= (SMALL_CNS_TSZ - 1)) + emitSmallCns[SMALL_CNS_TSZ - 1]++; + else + emitSmallCns[cns - ID_MIN_SMALL_CNS]++; #endif return id; @@ -6861,6 +7000,10 @@ void emitter::emitNxtIG(bool emitAdd) if (emitAdd) { emitCurIG->igFlags |= IGF_EMIT_ADD; + +#if EMITTER_STATS + emitTotalIGEmitAdd++; +#endif // EMITTER_STATS } // We've created a new IG; no need to force another one. diff --git a/src/jit/emit.h b/src/jit/emit.h index c5b50a5d1b..1308531a90 100644 --- a/src/jit/emit.h +++ b/src/jit/emit.h @@ -589,7 +589,8 @@ protected: static_assert_no_msg(INS_count <= 256); instruction _idIns : 8; #endif // !(defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)) - // The format for the instruction + +// The format for the instruction #if defined(_TARGET_XARCH_) static_assert_no_msg(IF_COUNT <= 128); insFormat _idInsFmt : 7; @@ -1613,9 +1614,9 @@ private: // and must store them all to the frame on entry. If the frame is very large, we generate // ugly code like "movw r10, 0x488; add r10, sp; vstr s0, [r10]" for each store, which // eats up our insGroup buffer. -#define SC_IG_BUFFER_SIZE (100 * sizeof(instrDesc) + 14 * SMALL_IDSC_SIZE) +#define SC_IG_BUFFER_SIZE (100 * sizeof(emitter::instrDesc) + 14 * SMALL_IDSC_SIZE) #else // !_TARGET_ARMARCH_ -#define SC_IG_BUFFER_SIZE (50 * sizeof(instrDesc) + 14 * SMALL_IDSC_SIZE) +#define SC_IG_BUFFER_SIZE (50 * sizeof(emitter::instrDesc) + 14 * SMALL_IDSC_SIZE) #endif // !_TARGET_ARMARCH_ size_t emitIGbuffSize; @@ -1771,32 +1772,52 @@ private: int emitNextRandomNop(); - void* emitAllocInstr(size_t sz, emitAttr attr); + // + // Functions for allocating instrDescs. + // + // The emitAllocXXX functions are the base level that allocate memory, and do little else. + // The emitters themselves use emitNewXXX, which might be thin wrappers over the emitAllocXXX functions. + // + + void* emitAllocAnyInstr(size_t sz, emitAttr attr); instrDesc* emitAllocInstr(emitAttr attr) { - return (instrDesc*)emitAllocInstr(sizeof(instrDesc), attr); +#if EMITTER_STATS + emitTotalIDescCnt++; +#endif // EMITTER_STATS + return (instrDesc*)emitAllocAnyInstr(sizeof(instrDesc), attr); } instrDescJmp* emitAllocInstrJmp() { - return (instrDescJmp*)emitAllocInstr(sizeof(instrDescJmp), EA_1BYTE); +#if EMITTER_STATS + emitTotalIDescJmpCnt++; +#endif // EMITTER_STATS + return (instrDescJmp*)emitAllocAnyInstr(sizeof(instrDescJmp), EA_1BYTE); } #if !defined(_TARGET_ARM64_) instrDescLbl* emitAllocInstrLbl() { - return (instrDescLbl*)emitAllocInstr(sizeof(instrDescLbl), EA_4BYTE); +#if EMITTER_STATS + emitTotalIDescLblCnt++; +#endif // EMITTER_STATS + return (instrDescLbl*)emitAllocAnyInstr(sizeof(instrDescLbl), EA_4BYTE); } #endif // !_TARGET_ARM64_ instrDescCns* emitAllocInstrCns(emitAttr attr) { - return (instrDescCns*)emitAllocInstr(sizeof(instrDescCns), attr); +#if EMITTER_STATS + emitTotalIDescCnsCnt++; +#endif // EMITTER_STATS + return (instrDescCns*)emitAllocAnyInstr(sizeof(instrDescCns), attr); } - instrDescCns* emitAllocInstrCns(emitAttr attr, int cns) + + instrDescCns* emitAllocInstrCns(emitAttr attr, target_size_t cns) { - instrDescCns* result = (instrDescCns*)emitAllocInstr(sizeof(instrDescCns), attr); + instrDescCns* result = emitAllocInstrCns(attr); result->idSetIsLargeCns(); result->idcCnsVal = cns; return result; @@ -1804,31 +1825,46 @@ private: instrDescDsp* emitAllocInstrDsp(emitAttr attr) { - return (instrDescDsp*)emitAllocInstr(sizeof(instrDescDsp), attr); +#if EMITTER_STATS + emitTotalIDescDspCnt++; +#endif // EMITTER_STATS + return (instrDescDsp*)emitAllocAnyInstr(sizeof(instrDescDsp), attr); } instrDescCnsDsp* emitAllocInstrCnsDsp(emitAttr attr) { - return (instrDescCnsDsp*)emitAllocInstr(sizeof(instrDescCnsDsp), attr); +#if EMITTER_STATS + emitTotalIDescCnsDspCnt++; +#endif // EMITTER_STATS + return (instrDescCnsDsp*)emitAllocAnyInstr(sizeof(instrDescCnsDsp), attr); } #ifdef _TARGET_XARCH_ instrDescAmd* emitAllocInstrAmd(emitAttr attr) { - return (instrDescAmd*)emitAllocInstr(sizeof(instrDescAmd), attr); +#if EMITTER_STATS + emitTotalIDescAmdCnt++; +#endif // EMITTER_STATS + return (instrDescAmd*)emitAllocAnyInstr(sizeof(instrDescAmd), attr); } instrDescCnsAmd* emitAllocInstrCnsAmd(emitAttr attr) { - return (instrDescCnsAmd*)emitAllocInstr(sizeof(instrDescCnsAmd), attr); +#if EMITTER_STATS + emitTotalIDescCnsAmdCnt++; +#endif // EMITTER_STATS + return (instrDescCnsAmd*)emitAllocAnyInstr(sizeof(instrDescCnsAmd), attr); } #endif // _TARGET_XARCH_ instrDescCGCA* emitAllocInstrCGCA(emitAttr attr) { - return (instrDescCGCA*)emitAllocInstr(sizeof(instrDescCGCA), attr); +#if EMITTER_STATS + emitTotalIDescCGCACnt++; +#endif // EMITTER_STATS + return (instrDescCGCA*)emitAllocAnyInstr(sizeof(instrDescCGCA), attr); } instrDesc* emitNewInstrSmall(emitAttr attr); @@ -2103,14 +2139,38 @@ public: static unsigned emitTotalInsCnt; + static unsigned emitCurPrologInsCnt; // current number of prolog instrDescs + static size_t emitCurPrologIGSize; // current size of prolog instrDescs + static unsigned emitMaxPrologInsCnt; // maximum number of prolog instrDescs + static size_t emitMaxPrologIGSize; // maximum size of prolog instrDescs + static unsigned emitTotalIGcnt; // total number of insGroup allocated static unsigned emitTotalPhIGcnt; // total number of insPlaceholderGroupData allocated static unsigned emitTotalIGicnt; static size_t emitTotalIGsize; - static unsigned emitTotalIGmcnt; // total method count + static unsigned emitTotalIGmcnt; // total method count + static unsigned emitTotalIGEmitAdd; // total number of 'emitAdd' (overflow) groups static unsigned emitTotalIGjmps; static unsigned emitTotalIGptrs; + 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_XARCH_ + static unsigned emitTotalIDescAmdCnt; + static unsigned emitTotalIDescCnsAmdCnt; +#endif // _TARGET_XARCH_ + static unsigned emitTotalIDescCGCACnt; +#ifdef _TARGET_ARM_ + static unsigned emitTotalIDescRelocCnt; +#endif // _TARGET_ARM_ + static size_t emitTotMemAlloc; static unsigned emitSmallDspCnt; @@ -2294,10 +2354,13 @@ inline emitter::instrDesc* emitter::emitNewInstrSmall(emitAttr attr) { instrDesc* id; - // This is larger than the Tiny Descr - id = (instrDesc*)emitAllocInstr(SMALL_IDSC_SIZE, attr); + id = (instrDesc*)emitAllocAnyInstr(SMALL_IDSC_SIZE, attr); id->idSetIsSmallDsc(); +#if EMITTER_STATS + emitTotalIDescSmallCnt++; +#endif // EMITTER_STATS + return id; } @@ -2359,12 +2422,11 @@ inline emitter::instrDesc* emitter::emitNewInstrCns(emitAttr attr, target_ssize_ if (instrDesc::fitsInSmallCns(cns)) { instrDesc* id = emitAllocInstr(attr); - id->idSmallCns(cns); #if EMITTER_STATS emitSmallCnsCnt++; - if (cns - ID_MIN_SMALL_CNS >= SMALL_CNS_TSZ) + if ((cns - ID_MIN_SMALL_CNS) >= (SMALL_CNS_TSZ - 1)) emitSmallCns[SMALL_CNS_TSZ - 1]++; else emitSmallCns[cns - ID_MIN_SMALL_CNS]++; @@ -2374,10 +2436,7 @@ inline emitter::instrDesc* emitter::emitNewInstrCns(emitAttr attr, target_ssize_ } else { - instrDescCns* id = emitAllocInstrCns(attr); - - id->idSetIsLargeCns(); - id->idcCnsVal = cns; + instrDescCns* id = emitAllocInstrCns(attr, cns); #if EMITTER_STATS emitLargeCnsCnt++; @@ -2414,29 +2473,36 @@ inline size_t emitter::emitGetInstrDescSize(const instrDesc* id) * constant operand. This is the same as emitNewInstrCns() except that here * any constant that is small enough for instrDesc::fitsInSmallCns() only gets * allocated SMALL_IDSC_SIZE bytes (and is thus a small descriptor, whereas - * emitNewInstrCns() always allocates at least sizeof(instrDesc). + * emitNewInstrCns() always allocates at least sizeof(instrDesc)). */ inline emitter::instrDesc* emitter::emitNewInstrSC(emitAttr attr, target_ssize_t cns) { - instrDesc* id; - if (instrDesc::fitsInSmallCns(cns)) { - id = (instrDesc*)emitAllocInstr(SMALL_IDSC_SIZE, attr); - + instrDesc* id = emitNewInstrSmall(attr); id->idSmallCns(cns); - id->idSetIsSmallDsc(); + +#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]++; +#endif + + return id; } else { - id = (instrDesc*)emitAllocInstr(sizeof(instrDescCns), attr); + instrDescCns* id = emitAllocInstrCns(attr, cns); - id->idSetIsLargeCns(); - ((instrDescCns*)id)->idcCnsVal = cns; - } +#if EMITTER_STATS + emitLargeCnsCnt++; +#endif - return id; + return id; + } } /***************************************************************************** @@ -2466,11 +2532,15 @@ inline emitter::instrDesc* emitter::emitNewInstrReloc(emitAttr attr, BYTE* addr) { assert(EA_IS_RELOC(attr)); - instrDescReloc* id = (instrDescReloc*)emitAllocInstr(sizeof(instrDescReloc), attr); + instrDescReloc* id = (instrDescReloc*)emitAllocAnyInstr(sizeof(instrDescReloc), attr); assert(id->idIsReloc()); id->idrRelocVal = addr; +#if EMITTER_STATS + emitTotalIDescRelocCnt++; +#endif // EMITTER_STATS + return id; } diff --git a/src/jit/emitarm.cpp b/src/jit/emitarm.cpp index 8098c60a41..3d7089bb8a 100644 --- a/src/jit/emitarm.cpp +++ b/src/jit/emitarm.cpp @@ -3344,9 +3344,7 @@ void emitter::emitIns_R_R_R_I(instruction ins, assert(sf != INS_FLAGS_DONT_CARE); // 3-reg ops can't use the small instrdesc - instrDescCns* id = emitAllocInstrCns(attr); - id->idSetIsLargeCns(); - id->idcCnsVal = imm; + instrDesc* id = emitNewInstrCns(attr, imm); id->idIns(ins); id->idInsFmt(fmt); diff --git a/src/jit/emitarm64.cpp b/src/jit/emitarm64.cpp index 9f4208a4a5..d066edfd27 100644 --- a/src/jit/emitarm64.cpp +++ b/src/jit/emitarm64.cpp @@ -7020,7 +7020,7 @@ void emitter::emitIns_R_AI(instruction ins, emitAttr attr, regNumber ireg, ssize // add reg, reg, imm ins = INS_add; fmt = IF_DI_2A; - instrDesc* id = emitAllocInstr(attr); + instrDesc* id = emitNewInstr(attr); assert(id->idIsReloc()); id->idIns(ins); diff --git a/src/jit/emitxarch.cpp b/src/jit/emitxarch.cpp index bbaeb81d0f..8bba1f688a 100644 --- a/src/jit/emitxarch.cpp +++ b/src/jit/emitxarch.cpp @@ -2407,33 +2407,15 @@ emitter::instrDesc* emitter::emitNewInstrAmdCns(emitAttr size, ssize_t dsp, int { if (dsp >= AM_DISP_MIN && dsp <= AM_DISP_MAX) { - if (cns >= ID_MIN_SMALL_CNS && cns <= ID_MAX_SMALL_CNS) - { - instrDesc* id = emitAllocInstr(size); - - id->idSmallCns(cns); - - id->idAddr()->iiaAddrMode.amDisp = dsp; - assert(id->idAddr()->iiaAddrMode.amDisp == dsp); // make sure the value fit - - return id; - } - else - { - instrDescCns* id = emitAllocInstrCns(size); - - id->idSetIsLargeCns(); - id->idcCnsVal = cns; - - id->idAddr()->iiaAddrMode.amDisp = dsp; - assert(id->idAddr()->iiaAddrMode.amDisp == dsp); // make sure the value fit + instrDesc* id = emitNewInstrCns(size, cns); + id->idAddr()->iiaAddrMode.amDisp = dsp; + assert(id->idAddr()->iiaAddrMode.amDisp == dsp); // make sure the value fit - return id; - } + return id; } else { - if (cns >= ID_MIN_SMALL_CNS && cns <= ID_MAX_SMALL_CNS) + if (instrDesc::fitsInSmallCns(cns)) { instrDescAmd* id = emitAllocInstrAmd(size); |