[Issue 17135] DMD hangs when compiling in release mode

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Sat Feb 4 12:05:11 PST 2017


https://issues.dlang.org/show_bug.cgi?id=17135

ag0aep6g at gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ag0aep6g at gmail.com

--- Comment #2 from ag0aep6g at gmail.com ---
1) Use dub's -v switch to get the dmd command. Then get rid of dub. From the
dmd command, throw unneeded arguments away one by one; both switches and source
files.

Result: dmd -c -O -unittest -Isrc src/sdlang/lexer.d

2) Remove all unittests from lexer.d. Compiles quickly now. Check unittest
blocks individually.

It's the large one at line 1552.

3) Reduce that beast. Just delete from the end.

Turns out when I delete just that last `stderr.writeln` part, compilation
finishes in 14 seconds on my machine. If I leave it in, it takes forever. Huh.
Seems that `if (numErrors > 0) writeln();` makes the optimizer take much
longer.

4) Minimize the code of the unittest by generating many identical testLex
calls. Delete almost all the rest of lexer.d.

Result:

----
module sdlang.lexer;

import sdlang.symbol;
import sdlang.token;
import sdlang.util;

int numErrors = 0;
void testLex(string source, Token[] expected) {}

unittest
{
    enum n = 110;
    import std.array: replicate;
    mixin(
        `testLex("", [ Token(symbol!"Value", Location.init, Value(0)) ]);`
        .replicate(n)
    );

    import std.stdio;
    if (numErrors > 0) writeln();
}
----

That compiles in about 10 seconds on my machine. If I remove the writeln line,
it compiles in under 2 seconds. Can make the ratio more extreme by increasing
n.

5) Incorporate Token, Symbol, Location. Get rid of most of Phobos. Generally
reduce.

Final result:

----
int numErrors = 0;
void testLex(Token expected) {}
void writeln();

void main()
{
    enum n = 110;
    import std.array: replicate;
    mixin(
        `testLex(Token(Symbol.init, Location.init));`
        .replicate(n)
    );

    if (numErrors > 0) writeln();
}

struct Token
{
    Symbol symbol;
    Location location;

    this(Symbol symbol, Location location) {}
}

struct Location { ubyte[32] data; }
    /* The size of Location.data matters:
        * 8 bytes or less - problem much less pronounced,
        * 9 through 32 bytes (didn't check every number) - very slow
optimization,
        * more than 32 bytes - problem much, much less pronounced.
    */
struct Symbol {}
----

Call that file file test.d. Delete everything else.

Compile with `dmd -c -O test.d`. Takes about 10 seconds on my machine. Remove
the writeln line in main and it takes under one second. Increase n to make the
ratio more extreme. At n = 200, compilation takes 1m42s for me. Seems to be
quadratic.

--


More information about the Digitalmars-d-bugs mailing list