From 8e33b235e19b72a76df4f4b7aed9a7bda594573a Mon Sep 17 00:00:00 2001 From: Peter Kukol Date: Mon, 19 Sep 2016 16:44:22 -0600 Subject: [PATCH] Add option for showing GT_xxx operator counts. (dotnet/coreclr#7262) Commit migrated from https://github.com/dotnet/coreclr/commit/30e6ae225a113d2e286dbd868bba38c786bf141b --- src/coreclr/src/jit/compiler.cpp | 57 ++++++++++++++++++++++++++++++++++++++++ src/coreclr/src/jit/compiler.hpp | 4 +++ src/coreclr/src/jit/gentree.cpp | 10 ++++--- src/coreclr/src/jit/gentree.h | 8 +++--- src/coreclr/src/jit/jit.h | 1 + 5 files changed, 74 insertions(+), 6 deletions(-) diff --git a/src/coreclr/src/jit/compiler.cpp b/src/coreclr/src/jit/compiler.cpp index f3699bd..4030913 100644 --- a/src/coreclr/src/jit/compiler.cpp +++ b/src/coreclr/src/jit/compiler.cpp @@ -1220,6 +1220,63 @@ void Compiler::compShutdown() } #endif // COUNT_RANGECHECKS +#if COUNT_AST_OPERS + + // Add up all the counts so that we can show percentages of total + unsigned gtc = 0; + for (unsigned op = 0; op < GT_COUNT; op++) + gtc += GenTree::s_gtNodeCounts[op]; + + if (gtc > 0) + { + unsigned rem_total = gtc; + unsigned rem_large = 0; + unsigned rem_small = 0; + + unsigned tot_large = 0; + unsigned tot_small = 0; + + fprintf(fout, "\nGenTree operator counts (approximate):\n\n"); + + for (unsigned op = 0; op < GT_COUNT; op++) + { + unsigned siz = GenTree::s_gtTrueSizes[op]; + unsigned cnt = GenTree::s_gtNodeCounts[op]; + double pct = 100.0 * cnt / gtc; + + if (siz > TREE_NODE_SZ_SMALL) + tot_large += cnt; + else + tot_small += cnt; + + // Let's not show anything below a threshold + if (pct >= 0.5) + { + fprintf(fout, " GT_%-17s %7u (%4.1lf%%) %3u bytes each\n", + GenTree::OpName((genTreeOps)op), cnt, pct, siz); + rem_total -= cnt; + } + else + { + if (siz > TREE_NODE_SZ_SMALL) + rem_large += cnt; + else + rem_small += cnt; + } + } + if (rem_total > 0) + { + fprintf(fout, " All other GT_xxx ... %7u (%4.1lf%%) ... %4.1lf%% small + %4.1lf%% large\n", + rem_total, 100.0 * rem_total / gtc, 100.0 * rem_small / gtc, 100.0 * rem_large / gtc); + } + fprintf(fout, " -----------------------------------------------------\n"); + fprintf(fout, " Total ....... %11u --ALL-- ... %4.1lf%% small + %4.1lf%% large\n", + gtc, 100.0 * tot_small / gtc, 100.0 * tot_large / gtc); + fprintf(fout, "\n"); + } + +#endif//COUNT_AST_OPERS + #if DISPLAY_SIZES if (grossVMsize && grossNCsize) diff --git a/src/coreclr/src/jit/compiler.hpp b/src/coreclr/src/jit/compiler.hpp index cc428e9..39fb48e 100644 --- a/src/coreclr/src/jit/compiler.hpp +++ b/src/coreclr/src/jit/compiler.hpp @@ -870,6 +870,10 @@ inline GenTree::GenTree(genTreeOps oper, var_types type DEBUGARG(bool largeNode) #endif #endif +#if COUNT_AST_OPERS + InterlockedIncrement(&s_gtNodeCounts[oper]); +#endif + #ifdef DEBUG gtSeqNum = 0; gtTreeID = JitTls::GetCompiler()->compGenTreeID++; diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index 9dbcdcc2e..58b4616 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -222,7 +222,7 @@ const char* GenTree::NodeName(genTreeOps op) #endif -#if defined(DEBUG) || NODEBASH_STATS +#if defined(DEBUG) || NODEBASH_STATS || COUNT_AST_OPERS static const char* opNames[] = { #define GTNODE(en, sn, st, cm, ok) #en, @@ -251,7 +251,7 @@ const char* GenTree::OpName(genTreeOps op) /* static */ unsigned char GenTree::s_gtNodeSizes[GT_COUNT + 1]; -#if NODEBASH_STATS +#if NODEBASH_STATS || COUNT_AST_OPERS unsigned char GenTree::s_gtTrueSizes[GT_COUNT+1] { @@ -259,7 +259,11 @@ unsigned char GenTree::s_gtTrueSizes[GT_COUNT+1] #include "gtlist.h" }; -#endif//NODEBASH_STATS +#endif // NODEBASH_STATS || COUNT_AST_OPERS + +#if COUNT_AST_OPERS +LONG GenTree::s_gtNodeCounts[GT_COUNT+1] = {0}; +#endif // COUNT_AST_OPERS /* static */ void GenTree::InitNodeSize() diff --git a/src/coreclr/src/jit/gentree.h b/src/coreclr/src/jit/gentree.h index e0e6a1a..f40cf09 100644 --- a/src/coreclr/src/jit/gentree.h +++ b/src/coreclr/src/jit/gentree.h @@ -1540,11 +1540,13 @@ public: public: #if SMALL_TREE_NODES static unsigned char s_gtNodeSizes[]; -#if NODEBASH_STATS +#if NODEBASH_STATS || COUNT_AST_OPERS static unsigned char s_gtTrueSizes[]; - static const char* s_gtNodeRawNames[]; #endif +#if COUNT_AST_OPERS + static LONG s_gtNodeCounts[]; #endif +#endif // SMALL_TREE_NODES static void InitNodeSize(); @@ -1568,7 +1570,7 @@ public: static const char* NodeName(genTreeOps op); #endif -#if defined(DEBUG) || NODEBASH_STATS +#if defined(DEBUG) || NODEBASH_STATS || COUNT_AST_OPERS static const char* OpName(genTreeOps op); #endif diff --git a/src/coreclr/src/jit/jit.h b/src/coreclr/src/jit/jit.h index 8b79f88..57c8b6d 100644 --- a/src/coreclr/src/jit/jit.h +++ b/src/coreclr/src/jit/jit.h @@ -466,6 +466,7 @@ typedef ptrdiff_t ssize_t; #define MEASURE_PTRTAB_SIZE 0 // Collect stats about GC pointer table allocations. #define EMITTER_STATS 0 // Collect stats on the emitter. #define NODEBASH_STATS 0 // Collect stats on changed gtOper values in GenTree's. +#define COUNT_AST_OPERS 0 // Display use counts for GenTree operators. #define VERBOSE_SIZES 0 // Always display GC info sizes. If set, DISPLAY_SIZES must also be set. #define VERBOSE_VERIFY 0 // Dump additional information when verifying code. Useful to debug verification bugs. -- 2.7.4