summaryrefslogtreecommitdiff
path: root/src/jit/inlinepolicy.cpp
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2016-10-12 18:00:13 -0700
committerAndy Ayers <andya@microsoft.com>2016-10-19 12:17:35 -0700
commit1e0359ce3e5d25ba4dbbe72336653ea1c94113ac (patch)
tree31da0d21c2a1464936f4a14ee7f6fe374b99f37e /src/jit/inlinepolicy.cpp
parentc764a9585625d88922ca92ea0798cd1bbce316c0 (diff)
downloadcoreclr-1e0359ce3e5d25ba4dbbe72336653ea1c94113ac.tar.gz
coreclr-1e0359ce3e5d25ba4dbbe72336653ea1c94113ac.tar.bz2
coreclr-1e0359ce3e5d25ba4dbbe72336653ea1c94113ac.zip
Inliner: avoid inlining callees with GC structs on cold paths
If an inline introduces a local or temp GC struct, the initialization of that struct is done in the root method prolog. This can hurt performance if the inline call site is cold. Detect this during importation and update the inline policy to back out of the inline if the inline is an always or discretionary candidate. Jit diffs shows size wins in the core library with no regressions. ``` Total bytes of diff: -8789 (-0.29 % of base) diff is an improvement. Total byte diff includes 0 bytes from reconciling methods Base had 0 unique methods, 0 unique bytes Diff had 0 unique methods, 0 unique bytes Top file improvements by size (bytes): -8789 : System.Private.CoreLib.dasm (-0.29 % of base) 1 total files with size differences. Top method improvements by size (bytes): -320 : System.Private.CoreLib.dasm - FrameSecurityDescriptor:CheckDemand2(ref,ref,long,bool):bool:this -224 : System.Private.CoreLib.dasm - RuntimeConstructorInfo:CheckCanCreateInstance(ref,bool) -214 : System.Private.CoreLib.dasm - RuntimeType:GetMethodBase(ref,long):ref -150 : System.Private.CoreLib.dasm - CultureInfo:GetCultureInfoByIetfLanguageTag(ref):ref -146 : System.Private.CoreLib.dasm - GC:RegisterForFullGCNotification(int,int) 103 total methods with size differences. ``` Desktop testing shows similar wins in a number of places and only a few sparse small regressions. Added a perf test. Thanks to @hypersw for noticing this. Closes #7569.
Diffstat (limited to 'src/jit/inlinepolicy.cpp')
-rw-r--r--src/jit/inlinepolicy.cpp21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/jit/inlinepolicy.cpp b/src/jit/inlinepolicy.cpp
index f80f3a5ec0..20d18c4e4d 100644
--- a/src/jit/inlinepolicy.cpp
+++ b/src/jit/inlinepolicy.cpp
@@ -842,7 +842,7 @@ int LegacyPolicy::CodeSizeEstimate()
// NoteBool: handle a boolean observation with non-fatal impact
//
// Arguments:
-// obs - the current obsevation
+// obs - the current observation
// value - the value of the observation
void EnhancedLegacyPolicy::NoteBool(InlineObservation obs, bool value)
@@ -854,6 +854,25 @@ void EnhancedLegacyPolicy::NoteBool(InlineObservation obs, bool value)
m_IsNoReturnKnown = true;
break;
+ case InlineObservation::CALLSITE_RARE_GC_STRUCT:
+ // If this is a discretionary or always inline candidate
+ // with a gc struct, we may change our mind about inlining
+ // if the call site is rare, to avoid costs associated with
+ // zeroing the GC struct up in the root prolog.
+ if (m_Observation == InlineObservation::CALLEE_BELOW_ALWAYS_INLINE_SIZE)
+ {
+ assert(m_CallsiteFrequency == InlineCallsiteFrequency::UNUSED);
+ SetFailure(obs);
+ return;
+ }
+ else if (m_Observation == InlineObservation::CALLEE_IS_DISCRETIONARY_INLINE)
+ {
+ assert(m_CallsiteFrequency == InlineCallsiteFrequency::RARE);
+ SetFailure(obs);
+ return;
+ }
+ break;
+
default:
// Pass all other information to the legacy policy
LegacyPolicy::NoteBool(obs, value);