-
-
Notifications
You must be signed in to change notification settings - Fork 609
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
Conversation
|
Thanks for your pull request, @WalterBright! Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + dmd#11374" |
There was a problem hiding this 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
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. |
Maybe we do, maybe we don't. I like having a specific test for it.
There are many optimizer tests like that in the test suite. |
|
The failing Win64 autotest seems to be related to dlang/druntime#2436 |
|
Which @rainers has just fixed! |
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. |
There was a problem hiding this 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.
|
However it doesn't cater for early returns instead of asserts. 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. |
The optimizer is built on the presumption that the hot branch of |
…he function