summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2019-03-21 13:50:53 -0700
committerGitHub <noreply@github.com>2019-03-21 13:50:53 -0700
commitceca0a77e8b48e30f9c6b67d2992c3276aba2177 (patch)
tree0c84536f7ef6a2f3beb18a211f71b7238a73964a
parent9497b0c77819d7b64a0f3c8bf22921182c99c09d (diff)
parentdb98a132c216cf561b74a3cb86980e3f22d80852 (diff)
downloadcoreclr-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.cpp140
-rw-r--r--src/jit/block.h2
-rw-r--r--src/jit/compiler.cpp106
-rw-r--r--src/jit/emit.cpp225
-rw-r--r--src/jit/emit.h142
-rw-r--r--src/jit/emitarm.cpp4
-rw-r--r--src/jit/emitarm64.cpp2
-rw-r--r--src/jit/emitxarch.cpp28
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);