Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2021-02-17 19:43:47 +0300
committerGitHub <noreply@github.com>2021-02-17 19:43:47 +0300
commit701e029c330a6844f1e91c6760b93872ee106108 (patch)
tree06338e6d973e6fbdf7137c5b56bb7083fa2070d9 /src/coreclr/ToolBox
parent9195df699fe25d2e752c2bc350c16dc199f02f7a (diff)
Add MCS verb to dump jit flags histogram (#48281)
Useful for determining what sorts of jit compilations are found in an SPMI collection.
Diffstat (limited to 'src/coreclr/ToolBox')
-rw-r--r--src/coreclr/ToolBox/superpmi/mcs/CMakeLists.txt1
-rw-r--r--src/coreclr/ToolBox/superpmi/mcs/commandline.cpp20
-rw-r--r--src/coreclr/ToolBox/superpmi/mcs/commandline.h2
-rw-r--r--src/coreclr/ToolBox/superpmi/mcs/mcs.cpp5
-rw-r--r--src/coreclr/ToolBox/superpmi/mcs/verbjitflags.cpp83
-rw-r--r--src/coreclr/ToolBox/superpmi/mcs/verbjitflags.h18
-rw-r--r--src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.cpp88
-rw-r--r--src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.h3
8 files changed, 220 insertions, 0 deletions
diff --git a/src/coreclr/ToolBox/superpmi/mcs/CMakeLists.txt b/src/coreclr/ToolBox/superpmi/mcs/CMakeLists.txt
index 8524fe8faec..e928c48d0ca 100644
--- a/src/coreclr/ToolBox/superpmi/mcs/CMakeLists.txt
+++ b/src/coreclr/ToolBox/superpmi/mcs/CMakeLists.txt
@@ -21,6 +21,7 @@ set(MCS_SOURCES
verbdumpmap.cpp
verbdumptoc.cpp
verbfracture.cpp
+ verbjitflags.cpp
verbildump.cpp
verbinteg.cpp
verbmerge.cpp
diff --git a/src/coreclr/ToolBox/superpmi/mcs/commandline.cpp b/src/coreclr/ToolBox/superpmi/mcs/commandline.cpp
index d7c519e9021..e3b01e3b204 100644
--- a/src/coreclr/ToolBox/superpmi/mcs/commandline.cpp
+++ b/src/coreclr/ToolBox/superpmi/mcs/commandline.cpp
@@ -130,6 +130,10 @@ void CommandLine::DumpHelp(const char* program)
printf(" to the mch file.\n");
printf(" e.g. '-toc a.mch' creates a.mch.mct\n");
printf("\n");
+ printf(" -jitflags inputfile\n");
+ printf(" Summarize interesting jitflags for the method contexts\n");
+ printf(" e.g. '-jitflags a.mch'\n");
+ printf("\n");
printf("Range descriptions are either a single number, or a text file with .mcl extension\n");
printf("containing a sorted list of line delimited numbers.\n");
printf(" e.g. -strip 2 a.mc b.mc\n");
@@ -235,6 +239,12 @@ bool CommandLine::Parse(int argc, char* argv[], /* OUT */ Options* o)
foundVerb = true;
o->actionDumpToc = true;
}
+ else if ((_strnicmp(&argv[i][1], "jitflags", argLen) == 0))
+ {
+ tempLen = strlen(argv[i]);
+ foundVerb = true;
+ o->actionJitFlags = true;
+ }
else if ((_strnicmp(&argv[i][1], "ildump", argLen) == 0))
{
tempLen = strlen(argv[i]);
@@ -551,6 +561,16 @@ bool CommandLine::Parse(int argc, char* argv[], /* OUT */ Options* o)
}
return true;
}
+ if (o->actionJitFlags)
+ {
+ if (!foundFile1)
+ {
+ LogError("CommandLine::Parse() '-jitFlags' needs one input.");
+ DumpHelp(argv[0]);
+ return false;
+ }
+ return true;
+ }
if (o->actionILDump)
{
if (!foundFile1)
diff --git a/src/coreclr/ToolBox/superpmi/mcs/commandline.h b/src/coreclr/ToolBox/superpmi/mcs/commandline.h
index 74ca6374914..8bcf0da11d1 100644
--- a/src/coreclr/ToolBox/superpmi/mcs/commandline.h
+++ b/src/coreclr/ToolBox/superpmi/mcs/commandline.h
@@ -23,6 +23,7 @@ public:
, actionDumpMap(false)
, actionDumpToc(false)
, actionFracture(false)
+ , actionJitFlags(false)
, actionILDump(false)
, actionInteg(false)
, actionMerge(false)
@@ -51,6 +52,7 @@ public:
bool actionDumpMap;
bool actionDumpToc;
bool actionFracture;
+ bool actionJitFlags;
bool actionILDump;
bool actionInteg;
bool actionMerge;
diff --git a/src/coreclr/ToolBox/superpmi/mcs/mcs.cpp b/src/coreclr/ToolBox/superpmi/mcs/mcs.cpp
index f8a007075bc..34313a577bb 100644
--- a/src/coreclr/ToolBox/superpmi/mcs/mcs.cpp
+++ b/src/coreclr/ToolBox/superpmi/mcs/mcs.cpp
@@ -12,6 +12,7 @@
#include "verbfracture.h"
#include "verbdumpmap.h"
#include "verbdumptoc.h"
+#include "verbjitflags.h"
#include "verbildump.h"
#include "verbtoc.h"
#include "verbremovedup.h"
@@ -102,6 +103,10 @@ int __cdecl main(int argc, char* argv[])
{
exitCode = verbPrintJITEEVersion::DoWork();
}
+ if (o.actionJitFlags)
+ {
+ exitCode = verbJitFlags::DoWork(o.nameOfFile1);
+ }
Logger::Shutdown();
return exitCode;
diff --git a/src/coreclr/ToolBox/superpmi/mcs/verbjitflags.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbjitflags.cpp
new file mode 100644
index 00000000000..26379ce6771
--- /dev/null
+++ b/src/coreclr/ToolBox/superpmi/mcs/verbjitflags.cpp
@@ -0,0 +1,83 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+#include "standardpch.h"
+#include "verbjitflags.h"
+#include "methodcontext.h"
+#include "methodcontextiterator.h"
+#include "errorhandling.h"
+#include "spmidumphelper.h"
+
+int verbJitFlags::DoWork(const char* nameOfInput)
+{
+ MethodContextIterator mci;
+ if (!mci.Initialize(nameOfInput))
+ return -1;
+
+ LightWeightMap<unsigned long long, unsigned> flagMap;
+ unsigned mcCount = 0;
+
+ while (mci.MoveNext())
+ {
+ MethodContext* mc = mci.Current();
+ CORJIT_FLAGS corJitFlags;
+ mc->repGetJitFlags(&corJitFlags, sizeof(corJitFlags));
+ unsigned long long rawFlags = corJitFlags.GetFlagsRaw();
+
+ int index = flagMap.GetIndex(rawFlags);
+ if (index == -1)
+ {
+ flagMap.Add(rawFlags, 1);
+ }
+ else
+ {
+ int oldVal = flagMap.GetItem(index);
+ flagMap.Update(index, oldVal + 1);
+ }
+
+ mcCount++;
+ }
+
+ if (!mci.Destroy())
+ return -1;
+
+ printf("\nGrouped Flag Appearances (%u contexts)\n\n", mcCount);
+ printf("%-16s %8s %8s parsed\n", "bits", "count", "percent");
+
+ unsigned appearancesPerBit[64] = {};
+
+ const unsigned int count = flagMap.GetCount();
+ unsigned long long* pFlags = flagMap.GetRawKeys();
+
+ for (unsigned int i = 0; i < count; i++)
+ {
+ const unsigned long long flags = *pFlags++;
+ const int index = flagMap.GetIndex(flags);
+ const unsigned appearances = flagMap.GetItem(index);
+
+ printf("%016llx %8u %7.2f%% %s\n", flags, appearances, 100.0 * ((double) appearances / mcCount), SpmiDumpHelper::DumpJitFlags(flags).c_str());
+
+ for (unsigned int bit = 0; bit < 64; bit++)
+ {
+ if (flags & (1ull << bit))
+ {
+ appearancesPerBit[bit] += appearances;
+ }
+ }
+ }
+
+ printf("\nIndividual Flag Appearances\n\n");
+ for (unsigned int bit = 0; bit < 64; bit++)
+ {
+ unsigned perBit = appearancesPerBit[bit];
+ if (perBit > 0)
+ {
+ printf("%8u %7.2f%% %s\n", perBit, 100.0 * (double) perBit / mcCount, SpmiDumpHelper::DumpJitFlags(1ull<<bit).c_str());
+ }
+ }
+
+ return 0;
+}
+
diff --git a/src/coreclr/ToolBox/superpmi/mcs/verbjitflags.h b/src/coreclr/ToolBox/superpmi/mcs/verbjitflags.h
new file mode 100644
index 00000000000..495b0b84700
--- /dev/null
+++ b/src/coreclr/ToolBox/superpmi/mcs/verbjitflags.h
@@ -0,0 +1,18 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+//----------------------------------------------------------
+// verbJitFlags.h - verb that prints summary of jit flags values
+//----------------------------------------------------------
+#ifndef _verbJitFlags
+#define _verbJitFlags
+
+class verbJitFlags
+{
+public:
+ static int DoWork(const char* nameOfInput);
+};
+
+#endif
diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.cpp
index ea545729b91..b2d8ac7fd36 100644
--- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.cpp
+++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.cpp
@@ -206,3 +206,91 @@ std::string SpmiDumpHelper::DumpCorInfoFlag(CorInfoFlag flags)
return s;
}
+
+std::string SpmiDumpHelper::DumpJitFlags(CORJIT_FLAGS corJitFlags)
+{
+ return DumpJitFlags(corJitFlags.GetFlagsRaw());
+}
+
+std::string SpmiDumpHelper::DumpJitFlags(unsigned long long flags)
+{
+ std::string s("");
+
+#define AddFlag(__name)\
+ if (flags & (1ull << CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_ ## __name)) { \
+ s += std::string(" ") + std::string(#__name); \
+ flags &= ~(1ull << CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_ ## __name); }
+
+ // Note some flags are target dependent, but we want to
+ // be target-agnostic. So we use numbers for the few
+ // flags that are not universally defined.
+
+#define AddFlagNumeric(__name, __val)\
+ if (flags & (1ull << __val)) { \
+ s += std::string(" ") + std::string(#__name); \
+ flags &= ~(1ull <<__val); }
+
+ AddFlag(SPEED_OPT);
+ AddFlag(SIZE_OPT);
+ AddFlag(DEBUG_CODE);
+ AddFlag(DEBUG_EnC);
+ AddFlag(DEBUG_INFO);
+ AddFlag(MIN_OPT);
+
+ AddFlag(MCJIT_BACKGROUND);
+
+ // x86 only
+ //
+ AddFlagNumeric(PINVOKE_RESTORE_ESP, 8);
+ AddFlagNumeric(TARGET_P4, 9);
+ AddFlagNumeric(USE_FCOMI, 10);
+ AddFlagNumeric(USE_CMOV, 11);
+
+ AddFlag(OSR);
+ AddFlag(ALT_JIT);
+
+ AddFlagNumeric(FEATURE_SIMD, 17);
+
+ AddFlag(MAKEFINALCODE);
+ AddFlag(READYTORUN);
+ AddFlag(PROF_ENTERLEAVE);
+
+ AddFlag(PROF_NO_PINVOKE_INLINE);
+ AddFlag(SKIP_VERIFICATION);
+ AddFlag(PREJIT);
+ AddFlag(RELOC);
+ AddFlag(IMPORT_ONLY);
+ AddFlag(IL_STUB);
+ AddFlag(PROCSPLIT);
+ AddFlag(BBINSTR);
+ AddFlag(BBOPT);
+ AddFlag(FRAMED);
+
+ AddFlag(PUBLISH_SECRET_PARAM);
+
+ AddFlag(SAMPLING_JIT_BACKGROUND);
+ AddFlag(USE_PINVOKE_HELPERS);
+ AddFlag(REVERSE_PINVOKE);
+ AddFlag(TRACK_TRANSITIONS);
+ AddFlag(TIER0);
+ AddFlag(TIER1);
+
+ // arm32 only
+ //
+ AddFlagNumeric(RELATIVE_CODE_RELOCS, 41);
+
+ AddFlag(NO_INLINING);
+
+#undef AddFlag
+#undef AddFlagNumeric
+
+ if (flags != 0)
+ {
+ char buffer[MAX_BUFFER_SIZE];
+ sprintf_s(buffer, MAX_BUFFER_SIZE, " Unknown jit flags-%016llX", flags);
+ s += std::string(buffer);
+ }
+
+ return s;
+}
+
diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.h
index 977efc70c69..213d0baa381 100644
--- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.h
+++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.h
@@ -49,6 +49,9 @@ public:
static std::string DumpCorInfoFlag(CorInfoFlag flags);
+ static std::string DumpJitFlags(CORJIT_FLAGS corJitFlags);
+ static std::string DumpJitFlags(unsigned long long rawFlags);
+
private:
static void FormatAgnostic_CORINFO_SIG_INST_Element(