summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2019-03-18 14:53:52 -0700
committerBruce Forstall <brucefo@microsoft.com>2019-03-20 13:20:55 -0700
commitdb98a132c216cf561b74a3cb86980e3f22d80852 (patch)
tree8a9530019a5751c9e9f001016718fe929ec16517
parent0eae19e1754517085d38df2a48861c2370c26eea (diff)
downloadcoreclr-db98a132c216cf561b74a3cb86980e3f22d80852.tar.gz
coreclr-db98a132c216cf561b74a3cb86980e3f22d80852.tar.bz2
coreclr-db98a132c216cf561b74a3cb86980e3f22d80852.zip
Update emitter statistics
1. Move BasicBlock static statistics output to block.cpp, and update it to match the current BasicBlock declaration. 2. Add counts for each instrDesc type that is used. 3. Dump instrDesc type sizes. 4. Dump IG "static" buffer sizes. 5. Dump how many of each instrDesc can fit in the "static" IG. 6. Dump the maximum prolog instrDesc count and prolog IG size. 7. Fix and enable the "common small constants" output.
-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);