Skip to content

RyuJIT: Loop hoist invariant struct field accesses #7265

@sivarv

Description

@sivarv

Knucleotide benchmark heavily uses Dictionary lookups. It uses the following struct as key into hash table

struct ByteString
{
   public byte[] Array
   public int Start;
   public int Length;

    public override int GetHashCode()
    {
        int hc = 0;
        for (int i = 0; i < Length; i++)
            hc = hc * 31 + Array[Start + i];
        return hc;
    }

    public bool Equals(ByteString other)
    {
        if (Length != other.Length) return false;
        for (int i = 0; i < Length; i++)
            if (Array[Start+i] != other.Array[other.Start+i]) return false;
        return true;
    }
}

Call Chain:
Dictionary.TryGetValue() --> FindEntry() --> calls GetHashCode() and Equals() methods on ByteString.

In case of Equals() or GetHashCode() methods, ByteString accessed is either "thisptr" or argument passed to the method. Struct args on Windows are considered implicitly by-ref and hence struct fields get accessed through an indirection on a byref. Legacy JIT64 was able to loop hoist this.Array, this.Array.Length, this.Start, other.Array, other.Array.Length and other.Start by recognizing them as loop invariant. This shows up as execution perf difference between RyuJIT vs Legacy Jit64.

category:cq
theme:loop-opt
skill-level:expert
cost:medium

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIenhancementProduct code improvement that does NOT require public API changes/additionsoptimizationtenet-performancePerformance related issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions