Skip to content

[API Proposal]: MethodImplOptions.Cold for marking cold methods for the JIT #84333

@MichalPetryka

Description

@MichalPetryka

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:

/// <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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-suggestionEarly API idea and discussion, it is NOT ready for implementationarea-System.Runtime.CompilerServicesneeds-further-triageIssue has been initially triaged, but needs deeper consideration or reconsideration

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions