Fix a bug in JIT value numbering.
This is a fix for a silent bad codegen bug in value numbering.
The value numbering algorithm tries to check whether heap PHI arguments
evaluate to the same value for the given query. In doing so, it may encounter
PHIs that recursively depend on each other (this corresponds to cycles in
control flow graph). A special value RecursiveVN is returned in such cases.
The algorithm uses the following rule:
if some PHI arguments evaluate to RecursiveVN but all others evaluate to the
same value that's not RecursiveVN, then that value can be used as the result.
Furthermore, in order to avoid exponential searches in case of many PHI's the
results of all PHI evaluations are memoized.
The bug was that if RecursiveVN was used to get the result, it can't always
be memoized. In particular, if the loop causing recursive PHIs is a multi-entry
loop, intermediate PHI results shouldn't be memoized. The fix is conservative in
that it always disables memoization if RecursiveVN was involved. Note that we
also have another mechanism (budget) to mitigate expensive PHI evaluations.
There were no diffs in SuperPMI and no measurable throughput impact.
I added a test with a simplified repro.
The original bug had code with yield return.
I also fixed some formatting and added several function headers.