Repository navigation
RyuJIT: Loop hoist invariant struct field accesses #7265
Description
Activity
The reason RyuJIT doesn't hoist the field accesses is that these reads from By-ref through indir are given unique value numbers. Note that these methods (Equals and GetHashCode) are pure methods in the sense that they only read from heap and no writes to it.
Please note that ByteString struct used by knucleotide benchmark is similar in concept to
Span<T>. Getting this right for ByteString would also likely to benefitSpan<T>scenarios whereSpan<T>accessed is an argument.The changes I have in flight to address #6913 currently produce these diffs on these methods. Looks like the only loads we're leaving in the loops are the variant ones and the array lengths in the bounds-checks. I'll look into why we're not getting those array lengths...
- changed the title
[-]RyuJIt: Loop hoist invariant struct field accesses[/-][+]RyuJIT: Loop hoist invariant struct field accesses[/+]on Mar 29, 2017 - addedJitUntriagedCLR JIT issues needing additional triageCLR JIT issues needing additional triage
on Oct 28, 2020 - removedJitUntriagedCLR JIT issues needing additional triageCLR JIT issues needing additional triage
on Jan 15, 2021
Knucleotide benchmark heavily uses Dictionary lookups. It uses the following struct as key into hash table
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