// Choose instrumentation technology.
//
+ // We enable edge profiling by default, except when:
+ // * disabled by option
+ // * we are prejitting via classic ngen
+ // * we are jitting osr methods
+ //
// Currently, OSR is incompatible with edge profiling. So if OSR is enabled,
// always do block profiling.
//
// Note this incompatibility only exists for methods that actually have
// patchpoints, but we won't know that until we import.
//
- const bool methodMayHavePatchpoints =
- (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_TIER0) && (JitConfig.TC_OnStackReplacement() > 0));
+ CLANG_FORMAT_COMMENT_ANCHOR;
- if ((JitConfig.JitEdgeProfiling() > 0) && !methodMayHavePatchpoints)
+#ifdef FEATURE_READYTORUN_COMPILER
+ const bool r2r = opts.IsReadyToRun();
+#else
+ const bool r2r = false;
+#endif
+ const bool prejit = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT);
+ const bool classicNgen = prejit && !r2r;
+ const bool osr = (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_TIER0) && (JitConfig.TC_OnStackReplacement() > 0));
+ const bool useEdgeProfiles = (JitConfig.JitEdgeProfiling() > 0) && !classicNgen && !osr;
+
+ if (useEdgeProfiles)
{
fgCountInstrumentor = new (this, CMK_Pgo) EfficientEdgeCountInstrumentor(this);
}
else
{
- if (JitConfig.JitEdgeProfiling() > 0)
- {
- JITDUMP("OSR and edge profiling not yet compatible; using block profiling\n");
- }
+ JITDUMP("Using block profiling, because %s\n",
+ (JitConfig.JitEdgeProfiling() > 0) ? "edge profiles disabled" : classicNgen ? "classic Ngen" : "OSR");
fgCountInstrumentor = new (this, CMK_Pgo) BlockCountInstrumentor(this);
}
- if (JitConfig.JitClassProfiling() > 0)
+ // Enable class profiling by default, when jitting.
+ // Todo: we may also want this on by default for prejitting.
+ //
+ const bool useClassProfiles = (JitConfig.JitClassProfiling() > 0) && !prejit;
+ if (useClassProfiles)
{
fgClassInstrumentor = new (this, CMK_Pgo) ClassProbeInstrumentor(this);
}
else
{
+ JITDUMP("Not doing class profiling, because %s\n",
+ (JitConfig.JitClassProfiling() > 0) ? "class profiles disabled" : "prejit");
+
fgClassInstrumentor = new (this, CMK_Pgo) NonInstrumentor(this);
}
//
assert(fgClassInstrumentor->SchemaCount() == info.compClassProbeCount);
- // Optionally, if there were no class probes and only one count probe,
+ // Optionally, when jitting, if there were no class probes and only one count probe,
// suppress instrumentation.
//
- if ((JitConfig.JitMinimalProfiling() > 0) && (fgCountInstrumentor->SchemaCount() == 1) &&
- (fgClassInstrumentor->SchemaCount() == 0))
+ // We leave instrumentation in place when prejitting as the sample hits in the method
+ // may be used to determine if the method should be prejitted or not.
+ //
+ // For jitting, no information is conveyed by the count in a single=block method.
+ //
+ bool minimalProbeMode = false;
+
+ if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
+ {
+ minimalProbeMode = (JitConfig.JitMinimalPrejitProfiling() > 0);
+ }
+ else
+ {
+ minimalProbeMode = (JitConfig.JitMinimalJitProfiling() > 0);
+ }
+
+ if (minimalProbeMode && (fgCountInstrumentor->SchemaCount() == 1) && (fgClassInstrumentor->SchemaCount() == 0))
{
- JITDUMP("Not instrumenting method: only one counter, and no class probes\n");
+ JITDUMP(
+ "Not instrumenting method: minimal probing enabled, and method has only one counter and no class probes\n");
return PhaseStatus::MODIFIED_NOTHING;
}
CONFIG_INTEGER(JitEnableRemoveEmptyTry, W("JitEnableRemoveEmptyTry"), 1)
#endif // DEBUG
-// Overall master enable for Guarded Devirtualization. Currently not enabled by default.
-CONFIG_INTEGER(JitEnableGuardedDevirtualization, W("JitEnableGuardedDevirtualization"), 0)
+// Overall master enable for Guarded Devirtualization.
+CONFIG_INTEGER(JitEnableGuardedDevirtualization, W("JitEnableGuardedDevirtualization"), 1)
#if defined(DEBUG)
// Various policies for GuardedDevirtualization
CONFIG_INTEGER(TC_OnStackReplacement_InitialCounter, W("TC_OnStackReplacement_InitialCounter"), 1000)
// Profile instrumentation options
-CONFIG_INTEGER(JitMinimalProfiling, W("JitMinimalProfiling"), 0)
-CONFIG_INTEGER(JitClassProfiling, W("JitClassProfiling"), 0)
-CONFIG_INTEGER(JitEdgeProfiling, W("JitEdgeProfiling"), 0)
+CONFIG_INTEGER(JitMinimalJitProfiling, W("JitMinimalJitProfiling"), 1)
+CONFIG_INTEGER(JitMinimalPrejitProfiling, W("JitMinimalPrejitProfiling"), 0)
+CONFIG_INTEGER(JitClassProfiling, W("JitClassProfiling"), 1)
+CONFIG_INTEGER(JitEdgeProfiling, W("JitEdgeProfiling"), 1)
// Control when Virtual Calls are expanded
CONFIG_INTEGER(JitExpandCallsEarly, W("JitExpandCallsEarly"), 1) // Expand Call targets early (in the global morph
<TestEnvironment Include="gcstress0xc_jitminopts_heapverify1" GCStress="0xC" JITMinOpts="1" HeapVerify="1" />
<TestEnvironment Include="jitosr" TC_OnStackReplacement="1" TC_QuickJitForLoops="1" TieredCompilation="1" />
<TestEnvironment Include="jitosr_stress" TC_OnStackReplacement="1" TC_QuickJitForLoops="1" TC_OnStackReplacement_InitialCounter="1" OSR_HitLimit="1" TieredCompilation="1" />
- <TestEnvironment Include="jitpgo" TieredPGO="1" TieredCompilation="1" />
- <TestEnvironment Include="jitpgo_inline" TieredPGO="1" TieredCompilation="1" JitInlinePolicyProfile="1"/>
- <TestEnvironment Include="jitpgo_classes" TieredPGO="1" TieredCompilation="1" JitEnableGuardedDevirtualization="1" JitClassProfiling="1"/>
- <TestEnvironment Include="jitpgo_edgeinstrumentation" TieredPGO="1" TieredCompilation="1" JitEdgeProfiling="1"/>
- <TestEnvironment Include="jitguardeddevirtualization" JitEnableGuardedDevirtualization="1" TieredCompilation="0" />
+ <TestEnvironment Include="jitpgo" TieredPGO="1" TieredCompilation="1" TC_QuickJitForLoops="1" />
+ <TestEnvironment Include="jitpgo_inline" TieredPGO="1" TieredCompilation="1" JitInlinePolicyProfile="1" TC_QuickJitForLoops="1" />
<TestEnvironment Include="jitehwritethru" EnableEhWriteThru="1" TieredCompilation="0" />
<TestEnvironment Include="jitobjectstackallocation" JitObjectStackAllocation="1" TieredCompilation="0" />
<TestEnvironment Include="ilasmroundtrip" RunningIlasmRoundTrip="1" />