diff options
author | Andy Ayers <andya@microsoft.com> | 2016-10-12 18:00:13 -0700 |
---|---|---|
committer | Andy Ayers <andya@microsoft.com> | 2016-10-19 12:17:35 -0700 |
commit | 1e0359ce3e5d25ba4dbbe72336653ea1c94113ac (patch) | |
tree | 31da0d21c2a1464936f4a14ee7f6fe374b99f37e /src/jit/inlinepolicy.cpp | |
parent | c764a9585625d88922ca92ea0798cd1bbce316c0 (diff) | |
download | coreclr-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.cpp | 21 |
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); |