Add option for showing GT_xxx operator counts. (dotnet/coreclr#7262)
authorPeter Kukol <pkukol@users.noreply.github.com>
Mon, 19 Sep 2016 22:44:22 +0000 (16:44 -0600)
committerGitHub <noreply@github.com>
Mon, 19 Sep 2016 22:44:22 +0000 (16:44 -0600)
Commit migrated from https://github.com/dotnet/coreclr/commit/30e6ae225a113d2e286dbd868bba38c786bf141b

src/coreclr/src/jit/compiler.cpp
src/coreclr/src/jit/compiler.hpp
src/coreclr/src/jit/gentree.cpp
src/coreclr/src/jit/gentree.h
src/coreclr/src/jit/jit.h

index f3699bd..4030913 100644 (file)
@@ -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)
index cc428e9..39fb48e 100644 (file)
@@ -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++;
index 9dbcdcc..58b4616 100644 (file)
@@ -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()
index e0e6a1a..f40cf09 100644 (file)
@@ -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
 
index 8b79f88..57c8b6d 100644 (file)
@@ -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.