-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Background and motivation
Having methods that always perform expensive operations like for example growing methods in growable collections is common in high performance code like the BCL. It'd be useful to be able to mark those with a flag being the reverse of AggressiveInlining which would tell the JIT to always treat blocks that end up with a call to it as cold, heavily pessimize inlining it unless a method always ends up calling it and prefer hoisting branches with it to the end of the generated codegen, similar to what Throw Helpers currently do.
I've thought about this while working on #82146 and noticing the JIT placing the call to Grow which is expected to be rare and expensive above a singular mov which is expected to happen in 90% of cases.
I'm not really sure what the exact name of the flag should be, my ideas include: Cold, Unlikely, Rare, Expensive.
cc @tannergooding @EgorBo @AndyAyersMS
API Proposal
namespace System.Runtime.CompilerServices;
public enum MethodImplOptions
{
Cold = 1024
}API Usage
There are quite a few places in the BCL that have "always cold" methods that should be marked with it, for example List.Grow that always ends up allocating a new array and copying data to it:
runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs
Lines 447 to 455 in e13f0dc
| /// <summary> | |
| /// Increase the capacity of this list to at least the specified <paramref name="capacity"/>. | |
| /// </summary> | |
| /// <param name="capacity">The minimum capacity to ensure.</param> | |
| internal void Grow(int capacity) | |
| { | |
| Debug.Assert(_items.Length < capacity); | |
| int newCapacity = _items.Length == 0 ? DefaultCapacity : 2 * _items.Length; |
Alternative Designs
Alternative designs include relying on PGO to detect such methods, which is less reliable, slows down startup and isn't as AOT friendly, or using more flexible method intrinsics from #4966 that are however harder to implement and require the library user, not author to mark the code with those.
Risks
Partial overlap with Assume intrinsics and PGO, more work for the JIT to do.