diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index d983a849c9dfa087b516cb3bdb0a4b0d5677e260..b6ed8c9ea998cfab43fd5767ee1045e69463abbe 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -2403,11 +2403,19 @@ void CodeGen::genEmitMachineCode() if (compiler->opts.disAsm || verbose) { printf("\n; Total bytes of code %d, prolog size %d, PerfScore %.2f, instruction count %d, allocated bytes for " - "code %d (MethodHash=%08x) for " - "method %s\n", + "code %d", codeSize, prologSize, compiler->info.compPerfScore, instrCount, - GetEmitter()->emitTotalHotCodeSize + GetEmitter()->emitTotalColdCodeSize, - compiler->info.compMethodHash(), compiler->info.compFullName); + GetEmitter()->emitTotalHotCodeSize + GetEmitter()->emitTotalColdCodeSize); + +#if TRACK_LSRA_STATS + if (JitConfig.DisplayLsraStats() == 3) + { + compiler->m_pLinearScan->dumpLsraStatsSummary(jitstdout); + } +#endif // TRACK_LSRA_STATS + + printf(" (MethodHash=%08x) for method %s\n", compiler->info.compMethodHash(), compiler->info.compFullName); + printf("; ============================================================\n\n"); printf(""); // in our logic this causes a flush } diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 2acf26f096d1045045580cd881cd232ef4e88b0c..8b64594e6727e6183996a547d14c092f8e60e2b0 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -1131,7 +1131,8 @@ public: virtual void recordVarLocationsAtStartOfBB(BasicBlock* bb) = 0; virtual bool willEnregisterLocalVars() const = 0; #if TRACK_LSRA_STATS - virtual void dumpLsraStatsCsv(FILE* file) = 0; + virtual void dumpLsraStatsCsv(FILE* file) = 0; + virtual void dumpLsraStatsSummary(FILE* file) = 0; #endif // TRACK_LSRA_STATS }; diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index 5d1cd06faaad9df0e6d768c9fe7b239dff207b20..71733a3addd8e71e41cbb1c3cbd11396695a8100 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -26,10 +26,12 @@ CONFIG_INTEGER(DiffableDasm, W("JitDiffableDasm"), 0) // Make the disas CONFIG_INTEGER(JitDasmWithAddress, W("JitDasmWithAddress"), 0) // Print the process address next to each instruction of // the disassembly CONFIG_INTEGER(DisplayLoopHoistStats, W("JitLoopHoistStats"), 0) // Display JIT loop hoisting statistics -CONFIG_INTEGER(DisplayLsraStats, W("JitLsraStats"), 0) // Display JIT Linear Scan Register Allocator statistics - // if set to 1. If set to "2", display the stats in csv format. - // Recommended to use with JitStdOutFile flag. -CONFIG_STRING(JitLsraOrdering, W("JitLsraOrdering")) // LSRA heuristics ordering +CONFIG_INTEGER(DisplayLsraStats, W("JitLsraStats"), 0) // Display JIT Linear Scan Register Allocator statistics + // If set to "1", display the stats in textual format. + // If set to "2", display the stats in csv format. + // If set to "3", display the stats in summarize format. + // Recommended to use with JitStdOutFile flag. +CONFIG_STRING(JitLsraOrdering, W("JitLsraOrdering")) // LSRA heuristics ordering CONFIG_INTEGER(DumpJittedMethods, W("DumpJittedMethods"), 0) // Prints all jitted methods to the console CONFIG_INTEGER(EnablePCRelAddr, W("JitEnablePCRelAddr"), 1) // Whether absolute addr be encoded as PC-rel offset by // RyuJIT where possible diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index bedf7cd0283691681789e7f1b41d4df2d4375a84..af168348e194d306aadf32b2a0c9f1a798755b46 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -8621,7 +8621,8 @@ void LinearScan::dumpLsraStats(FILE* file) fprintf(file, "----------\n"); #ifdef DEBUG - fprintf(file, "Register selection order: %S\n", JitConfig.JitLsraOrdering()); + fprintf(file, "Register selection order: %S\n", + JitConfig.JitLsraOrdering() == nullptr ? W("ABCDEFGHIJKLMNOPQ") : JitConfig.JitLsraOrdering()); #endif fprintf(file, "Total Tracked Vars: %d\n", compiler->lvaTrackedCount); fprintf(file, "Total Reg Cand Vars: %d\n", regCandidateVarCount); @@ -8640,6 +8641,7 @@ void LinearScan::dumpLsraStats(FILE* file) bool addedBlockHeader = false; bool anyNonZeroStat = false; + // Iterate for block 0 for (int statIndex = 0; statIndex < LsraStat::COUNT; statIndex++) { unsigned lsraStat = blockInfo[0].stats[statIndex]; @@ -8667,6 +8669,7 @@ void LinearScan::dumpLsraStats(FILE* file) fprintf(file, "\n"); } + // Iterate for remaining blocks for (BasicBlock* const block : compiler->Blocks()) { if (block->bbNum > bbNumMaxBeforeResolution) @@ -8712,7 +8715,6 @@ void LinearScan::dumpLsraStats(FILE* file) { fprintf(file, "..........\n"); } - // TODO-review: I don't see a point of displaying Stats (SpillCount, etc.) if they are zero. Thoughts? if ((regSelectI < firstRegSelStat) || (sumStats[regSelectI] != 0)) { // Print register selection stats @@ -8780,6 +8782,48 @@ void LinearScan::dumpLsraStatsCsv(FILE* file) } fprintf(file, ",%.2f\n", compiler->info.compPerfScore); } + +// ----------------------------------------------------------- +// dumpLsraStatsSummary - dumps Lsra stats summary to given file +// +// Arguments: +// file - file to which stats are to be written. +// +void LinearScan::dumpLsraStatsSummary(FILE* file) +{ + unsigned sumStats[LsraStat::STAT_FREE] = {0}; + BasicBlock::weight_t wtdStats[LsraStat::STAT_FREE] = {0.0}; + + // Iterate for block 0 + for (int statIndex = 0; statIndex < LsraStat::STAT_FREE; statIndex++) + { + unsigned lsraStat = blockInfo[0].stats[statIndex]; + sumStats[statIndex] += lsraStat; + wtdStats[statIndex] += (lsraStat * blockInfo[0].weight); + } + + // Iterate for remaining blocks + for (BasicBlock* const block : compiler->Blocks()) + { + if (block->bbNum > bbNumMaxBeforeResolution) + { + continue; + } + + for (int statIndex = 0; statIndex < LsraStat::STAT_FREE; statIndex++) + { + unsigned lsraStat = blockInfo[block->bbNum].stats[statIndex]; + sumStats[statIndex] += lsraStat; + wtdStats[statIndex] += (lsraStat * block->bbWeight); + } + } + + for (int regSelectI = 0; regSelectI < LsraStat::STAT_FREE; regSelectI++) + { + fprintf(file, ", %s %u %sWt %f", getStatName(regSelectI), sumStats[regSelectI], getStatName(regSelectI), + wtdStats[regSelectI]); + } +} #endif // TRACK_LSRA_STATS #ifdef DEBUG diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index d944c4530739d532886ff2d8786cedef988d613b..eda5d014c658a77f857064bb181fe5502e74eaf6 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1455,6 +1455,7 @@ private: public: virtual void dumpLsraStatsCsv(FILE* file); + virtual void dumpLsraStatsSummary(FILE* file); static const char* getStatName(unsigned stat); #define INTRACK_STATS(x) x