Bug 11497 – lambda in "static if"/"assert" prevent inlining of function

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-11-11T13:07:00Z
Last change time
2014-06-12T01:48:37Z
Keywords
performance, pull
Assigned to
nobody
Creator
monarchdodra
See also
https://d.puremagic.com/issues/show_bug.cgi?id=10848, https://d.puremagic.com/issues/show_bug.cgi?id=11483

Comments

Comment #0 by monarchdodra — 2013-11-11T13:07:20Z
(Related: https://d.puremagic.com/issues/show_bug.cgi?id=10848) If you have a function, that needs to do a test/assert, and does it via a lambda block (for example, to declare a variable), then that function will not be inline-able. This seems really crazy to me, since the lambda only exists during compilation anyways. This affects DMD, but not GDC. Here is a test program. It's a reduced case of what currently happens when we call "std.array.array". Variant 1 contains: static assert(is(typeof(*chunk = arg))); Whereas 2 contains: static assert(is(typeof({*chunk = arg;}))); //---- import std.stdio; import std.datetime; void array1(int[] arr) { foreach (int i, e ; arr) { emplace1(&e, i); ++i; } } void emplace1(T, Arg)(T* chunk, Arg arg) { static assert(is(typeof(*chunk = arg))); *chunk = arg; } void array2(T)(T[] arr) { foreach (int i, e ; arr) { emplace2(&e, i); ++i; } } void emplace2(T, Arg)(T* chunk, Arg arg) { static assert(is(typeof({*chunk = arg;}))); *chunk = arg; } void main() { auto arr = new int[] (10_000); StopWatch st1; st1.start; foreach (__; 0 .. 20_00) { array1(arr); } st1.stop; StopWatch st2; st2.start; foreach (__; 0 .. 20_00) { array2(arr); } st2.stop; writefln("1"); writefln("Time: %sms", st1.peek.msecs); writefln("2"); writefln("Time: %sms", st2.peek.msecs); } //---- Resulting times: 1 Time: 11ms 2 Time: 1972ms :/
Comment #1 by monarchdodra — 2013-11-11T13:14:10Z
To add, this happens regardless of optimization flags: > dmd -release -O -inline -run hello.d 1 Time: 11ms 2 Time: 1972ms > dmd -release -O -run hello.d 1 Time: 92ms 2 Time: 1967ms > dmd -release -run hello.d 1 Time: 167ms 2 Time: 2020ms > dmd -run hello.d 1 Time: 148ms 2 Time: 2023ms
Comment #2 by monarchdodra — 2013-11-11T13:15:13Z
EDIT: I'm *assuming* it's an inline problem, I haven't look at the ASM. But I don't see how it could be anything else...
Comment #3 by monarchdodra — 2013-11-12T07:03:35Z
Hum... I did some more investigating, and it would appear the culprit is not "just" having a lambda, but rather, having a lambda that needs access to context. EG: static assert(is(typeof(*chunk = arg))); //FAST static assert(is(typeof({*chunk = Arg.init;))); //FAST static assert(is(typeof({*chunk = arg;}))); //SLOW
Comment #4 by monarchdodra — 2013-11-12T09:20:26Z
(In reply to comment #3) > Hum... I did some more investigating, and it would appear the culprit is not > "just" having a lambda, but rather, having a lambda that needs access to > context. EG: > > static assert(is(typeof(*chunk = arg))); //FAST > static assert(is(typeof({*chunk = Arg.init;))); //FAST > static assert(is(typeof({*chunk = arg;}))); //SLOW Typo: static assert(is(typeof(*chunk = arg))); //FAST static assert(is(typeof({*chunk = Arg.init;}))); //FAST static assert(is(typeof({*chunk = arg;}))); //SLOW
Comment #5 by lomereiter — 2013-11-12T13:44:40Z
Comment #6 by monarchdodra — 2013-11-12T14:20:40Z
(In reply to comment #5) > Also related: https://d.puremagic.com/issues/show_bug.cgi?id=11483 Nice. So indeed, it's not an inlining problem. I *thought* the results were way too catastrophic for a simple inline problem.
Comment #7 by github-bugzilla — 2013-11-17T19:47:18Z
Commits pushed to master at https://github.com/D-Programming-Language/phobos https://github.com/D-Programming-Language/phobos/commit/8f10b877ead5e82e5c9a05fc2ed361ab6b08a398 Workaround Issue 11497 - lambda in "static if"/"assert" prevent inlining of function https://github.com/D-Programming-Language/phobos/commit/1ef29584e992dba98b3ddbbc9c97f564d4e6207f Merge pull request #1688 from monarchdodra/workaround11497 Workaround Issue 11497 - lambda in "static if"/"assert" prevent inlining of functio
Comment #8 by k.hara.pg — 2013-11-21T06:38:00Z
Comment #9 by github-bugzilla — 2013-11-22T17:42:41Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/de32be111bb299612285e2fef82f197e2d4a2764 fix Issue 11497 - lambda in "static if"/"assert" prevent inlining of function https://github.com/D-Programming-Language/dmd/commit/472f8c220f6ce7ca76d7d45afa0b5624575824dd Merge pull request #2845 from 9rnsr/fix11497 Issue 11497 - lambda in "static if"/"assert" prevent inlining of function
Comment #10 by github-bugzilla — 2013-11-23T14:49:16Z
Commits pushed to master at https://github.com/D-Programming-Language/phobos https://github.com/D-Programming-Language/phobos/commit/ad52c5f027d832e7d6064f88c1d64352e7a984d8 Revert "Workaround Issue 11497 - lambda in "static if"/"assert" prevent inlining of function" This reverts commit 8f10b877ead5e82e5c9a05fc2ed361ab6b08a398. Itroduced by pull #1688. Because 11497 is now fixed. https://github.com/D-Programming-Language/phobos/commit/9684fc2f8ebb07bb3f87e1f48fccd1869074a1f5 Merge pull request #1714 from monarchdodra/revert11497 Revert "Workaround Issue 11497 - lambda in "static if"/"assert" prevent ...
Comment #11 by k.hara.pg — 2014-06-12T01:48:37Z
*** Issue 11483 has been marked as a duplicate of this issue. ***