Skip to content

Internal API suggestion: bool JitHelpers.IsKnownConstant(uint) to let us optimize certain code paths #11484

@GrabYourPitchforks

Description

@GrabYourPitchforks

There are quite a few places in the Framework where we have specialized knowledge of data structures and algorithms - beyond what the JIT has - where we'd be able to make optimizations beyond what the JIT can provide if the JIT is able to hint to us information about locals.

For example, consider string.StartsWith(char) : bool, which is currently implemented as below.

public bool StartsWith(char value) => Length != 0 && _firstChar == value;

If the JIT were able to hint to us information about the local, we could write this as follows, which would allow us to elide the first branch entirely in almost all cases, taking advantage of the fact that empty strings have the null-terminator in the _firstChar position.

public bool StartsWith(char value) {
  if (JitHelpers.IsKnownConstant(value) && value != 0) {
    return _firstChar == value;
  } else {
    return Length != 0 && _firstChar == value;
  }
}

It would also allow us to further optimize the Span.Slice(int start, int length) logic we checked in earlier, which allows us to do something akin to the below.

if (JitHelpers.IsKnownConstant(start)) {
  if (start == 0) {
    // case Slice(0, <something>)
    ThrowIf((uint)length > (uint)_realLength);
    return <slice>;
  } else if (JitHelpers.IsKnownConstant(length) && start >= 0 && length >= 0) {
    // case Slice(10, 20)
    ThrowIf((uint)(start + length) > (uint)(_realLength));
    return <slice>;
  }
}

ThrowIf(normal_validation_checks);
return <slice>;

This could also have potential applications for methods which are implemented via a giant switch statement which normally doesn't get inlined (see String.Equals(..., StringComparison) overload). We could choose to implement the method as an inlineable method that does a very fast dispatch if the comparison parameter is known constant, falling back to a slower non-inlined method if the comparison parameter needs to be evaluated at runtime.

The behavior of IsKnownConstant would be such that the JIT would replace it with true if the value is known at JIT time to be constant (perhaps because it is itself a literal or has been calculated from some other const-folding). It would be replaced with false in all other cases, including if the JIT simply doesn't have enough information to make a determination, or if optimizations have been disabled. I'm also assuming branch pruning would kick in to completely elide code that is on the incorrect side of the IsKnownConstant check.

category:proposal
theme:optimization
skill-level:expert
cost:extra-large

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIdesign-discussionOngoing discussion about design without consensusoptimization

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions