Skip to content

JIT: Expand loop detection in if-conversion#82170

Merged
jakobbotsch merged 2 commits intodotnet:mainfrom
jakobbotsch:expand-if-conversion-loop-detection
Feb 16, 2023
Merged

JIT: Expand loop detection in if-conversion#82170
jakobbotsch merged 2 commits intodotnet:mainfrom
jakobbotsch:expand-if-conversion-loop-detection

Conversation

@jakobbotsch
Copy link
Member

@jakobbotsch jakobbotsch commented Feb 15, 2023

The BB weight approach does not detect unnatural loops.

Fix #82106

For more context, see #82106 (comment)

The BB weight approach does not detect unnatural loops.

Fix dotnet#82106
@ghost
Copy link

ghost commented Feb 15, 2023

Tagging subscribers to this area: @dotnet/area-system-text-regularexpressions
See info in area-owners.md if you want to be subscribed.

Issue Details

The BB weight approach does not detect unnatural loops.

Fix #82106

Let's see how costly this is...

Author: jakobbotsch
Assignees: jakobbotsch
Labels:

area-System.Text.RegularExpressions

Milestone: -

@jakobbotsch
Copy link
Member Author

Diffs

Surprisingly, not too impactful. cc @dotnet/jit-contrib PTAL @a74nh @AndyAyersMS
Ideally we should be smarter and allow some if-conversion within loops, but I'm not sure what the right conditions would be and it's unlikely we even have the information available. Presumably the analysis would need to take into account that if-conversion can introduce new data/control-flow dependencies across loop iterations.

@jakobbotsch jakobbotsch marked this pull request as ready for review February 15, 2023 18:31
Comment on lines +765 to +772
// Don't optimise the block if it is inside a loop
// When inside a loop, branches are quicker than selects.
// Detect via the block weight as that will be high when inside a loop.
if (m_startBlock->getBBWeight(m_comp) > BB_UNITY_WEIGHT)
{
JITDUMP("Skipping if-conversion inside loop (via weight)\n");
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to leave this "cheap" weight check first in the function, and only insert the "expensive" check here, after the long sequence of potentially expensive (appearing) checks above?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually tried this locally, but I did not see any impact from moving the cheap check.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative option would be to put all of the checks into a function bool canIfConvert().

Then optIfConvert would be:

if (!m_comp->compStressCompile(Compiler::STRESS_IF_CONVERSION_INNER_LOOPS, 25))
    {
        if (m_startBlock->getBBWeight(m_comp) > BB_UNITY_WEIGHT)
        {
            if (verbose && canIfConvert()) JITDUMP("Skipping if-conversion inside loop (via weight)\n");
            return false;
        }
        if (m_comp->optReachable(m_finalBlock, m_startBlock, nullptr))
        {
            if (verbose && canIfConvert()) JITDUMP("Skipping if-conversion inside loop (via FG walk)\n");
            return false;
        }
}

if (!canIfConvert()) return false;

.... do the if conversion

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like that would do the optReachable check before identifying the candidate which is what I wanted to avoid, as the flow-graph walk is expensive. Also, it is using m_finalBlock which is found as part of identifying the candidate. I moved the other check to simplify the code (as it does not have noticeable impact).

Of course if the flow graph walk was prohibitively expensive we could just compute reachability sets in this phase, but since the TP impact of this approach didn't turn out too bad I think we can leave it like this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, didn't spot the use of final block, ok, agreed, leave as is.

@jakobbotsch jakobbotsch added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI and removed area-System.Text.RegularExpressions labels Feb 16, 2023
@ghost
Copy link

ghost commented Feb 16, 2023

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch, @kunalspathak
See info in area-owners.md if you want to be subscribed.

Issue Details

The BB weight approach does not detect unnatural loops.

Fix #82106

For more context, see #82106 (comment)

Author: jakobbotsch
Assignees: jakobbotsch
Labels:

area-CodeGen-coreclr

Milestone: -

@a74nh
Copy link
Contributor

a74nh commented Feb 16, 2023

I'd be curious to see any diffs or performance changes for Arm64. Otherwise looks good to me.

@jakobbotsch
Copy link
Member Author

I'd be curious to see any diffs or performance changes for Arm64. Otherwise looks good to me.

Let's see during perf triage. FWIW, the benchmark I looked at originally regressed with if-conversion on arm64 as well: https://pvscmdupload.blob.core.windows.net/reports/allTestHistory%2frefs%2fheads%2fmain_arm64_ubuntu%2020.04%2fSystem.Text.RegularExpressions.Tests.Perf_Regex_Industry_RustLang_Sherlock.Count(Pattern%3a%20%22aei%22%2c%20Options%3a%20Compiled).html

Here's a benchmark that improved a bit on arm64 when else-conditions were added to if-conversion, but that this PR is affecting: https://pvscmdupload.blob.core.windows.net/reports/allTestHistory%2frefs%2fheads%2fmain_arm64_ubuntu%2020.04%2fBilinearTest.Interpol_Scalar.html
So likely this will regress it back to pre Nov 30th levels, but the if-conversion is happening inside a loop in this benchmark today.

I'm not sure there is so much we can do about this without investing in much more expensive/complicated analysis (that would probably be easier if the pass was still at a point where we had SSA). I assume the existing logic actually did mean to check for any kind of loop construct?

@jakobbotsch jakobbotsch merged commit 21553df into dotnet:main Feb 16, 2023
@jakobbotsch jakobbotsch deleted the expand-if-conversion-loop-detection branch February 16, 2023 12:01
@ghost ghost locked as resolved and limited conversation to collaborators Mar 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regressions in System.Text.RegularExpressions.Tests.Perf_Regex_Industry_RustLang_Sherlock

4 participants