Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix Issue 20990 - Optimizer should move cold branches to the end of t… #11374

Merged
merged 1 commit into from
Jul 6, 2020

Conversation

WalterBright
Copy link
Member

…he function

@dlang-bot
Copy link
Contributor

Thanks for your pull request, @WalterBright!

Bugzilla references

Auto-close Bugzilla Severity Description
20990 enhancement Optimizer should move cold branches to the end of the function

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#11374"

Copy link
Contributor

@thewilsonator thewilsonator left a comment

Choose a reason for hiding this comment

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

The test doesn't actually test anything

src/dmd/backend/blockopt.d Outdated Show resolved Hide resolved
@WalterBright
Copy link
Member Author

The test doesn't actually test anything

What it does is tickle the optimization, so if it crashes the compiler it'll show up.

@Geod24
Copy link
Member

Geod24 commented Jul 5, 2020

What it does is tickle the optimization, so if it crashes the compiler it'll show up.

But then, I'm sure we already have plenty of code in the testsuite that already does this.
Any test that would pass before the patch doesn't make sense to me.

@WalterBright
Copy link
Member Author

I'm sure we already have plenty of code in the testsuite that already does this.

Maybe we do, maybe we don't. I like having a specific test for it.

Any test that would pass before the patch doesn't make sense to me.

There are many optimizer tests like that in the test suite.

@WalterBright
Copy link
Member Author

The failing Win64 autotest seems to be related to dlang/druntime#2436

@WalterBright
Copy link
Member Author

Which @rainers has just fixed!

@ibuclaw
Copy link
Member

ibuclaw commented Jul 6, 2020

There are many optimizer tests like that in the test suite.

There has been some discussions of adding in a directive to scan the resultant assembler to ensure it produces what we expect it to, but there's not really any strong desire to add it.

Copy link
Member

@ibuclaw ibuclaw left a comment

Choose a reason for hiding this comment

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

To my dismay, there's not even the word "cold" anywhere in the patch, so can't pretend I know what is going on here.

Checked with the following:

class Foo
{
    int *ptr;
    int inc;
}

class Bar
{
    Foo foo;
    int inc;
}

class Baz
{
    Bar bar;
    int inc;
}

// foo() and bar() should produce the same code when
// optimized.

void foo(Baz baz)
{
    if (baz is null)
        assert(false);
    baz.inc++;
    if (baz.bar is null)
        assert(false);
    baz.bar.inc++;
    if (baz.bar.foo is null)
        assert(false);
    baz.bar.foo.inc++;
    if (baz.bar.foo.ptr is null)
        assert(false);
    *baz.bar.foo.ptr = 42;
}

void bar(Baz baz)
{
    assert(baz);
    baz.inc++;
    assert(baz.bar);
    baz.bar.inc++;
    assert(baz.bar.foo);
    baz.bar.foo.inc++;
    assert(baz.bar.foo.ptr);
    *baz.bar.foo.ptr = 42;
}

And the output is what I expect it to be, so seems reasonable to me.

@ibuclaw
Copy link
Member

ibuclaw commented Jul 6, 2020

However it doesn't cater for early returns instead of asserts.

int foo(Baz baz)
{
    if (baz is null)
        return 0x10;
    baz.inc++;
    if (baz.bar is null)
        return 0x20;
    baz.bar.inc++;
    if (baz.bar.foo is null)
        return 0x40;
    baz.bar.foo.inc++;
    if (baz.bar.foo.ptr is null)
        return 0x80;
    *baz.bar.foo.ptr = 42;
    return 0x100;
}

Though the above may be more reliant on branch prediction, or understanding the interdependencies between branches in order to determine what is likely or unlikely to happen.

@WalterBright
Copy link
Member Author

However it doesn't cater for early returns instead of asserts.

The optimizer is built on the presumption that the hot branch of if-then-else is the then branch.

@WalterBright WalterBright merged commit e904a75 into dlang:master Jul 6, 2020
@WalterBright WalterBright deleted the fix20990 branch July 6, 2020 21:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants