While trying to compile GtkD dmd was trapped in an infinite loop.
It happens when running 'dmd -v -release -O -inline -m64 -Isrc -c src/gtkc/gtk.d -ofsrc/gtkc/gtk.o' and doesn't occur when removing -inline.
Unfortunately I couldn't reduce it yet, so here's the original:
http://www.dsource.org/projects/gtkd/browser/trunk/src/gtkc/gtk.d?rev=865
#3300 0x00000000004d513f in accumaecpx (n=0x7d9cfec) at backend/gflow.c:1041
#3301 0x00000000004d513f in accumaecpx (n=0x7d9bac0) at backend/gflow.c:1041
else if (OTbinary(op))
{
if (OTrtol(op) && ERTOL(n))
{ accumaecpx(n->E2);
accumaecpx(n->E1);
}
else
{ accumaecpx(n->E1);
---> accumaecpx(n->E2);
}
if (OTassign(op)) // if assignment operator
t = Elvalue(n);
}
Comment #1 by bugzilla — 2013-10-05T16:47:15Z
Can you please try dustmite to cut it down to size?
Comment #2 by hoganmeier — 2013-10-12T15:29:17Z
I tried back then but didn't succeed.
IIRC we need a way to quickly and reliably detect the infinite loop from a script.
Comment #3 by bus_dbugzilla — 2014-05-05T23:13:20Z
Some notes for Walter.
The bottleneck is the `static this()` in gtk.d starting line 36.
This function itself is over 3800 lines long.
Notable problematic functions.
1. dmd/backend/gflow.d: initDNunambigVectors()
This function is a massive bottleneck, as you're effectively doing:
---
// In initDNunambigVectors()
foreach (uint i; 0 .. go.deftop)
{
// In fillInDNunambig()
foreach (uint i; 0 .. go.deftop)
{
// ...
}
}
---
In the unreduced test, go.deftop = 25144. You are also calling this function twice in dmd/backend/go.d:optfunc. The main entrypoint being constprop().
2. dmd/backend/gother.d: accumda()
Suffers from a similar problem. It is recursively called 25144 times in the OTbinary path.
3. dmd/backend/gflow.d: accumaecpx():
Likewise, it is recursively called
- 56572 times in the first iteration (before accumda).
- 28286 times in a second iteration (after accumda).
4. dmd/backend/gdag.d: aewalk():
Likewise, it is recursively called 50287 times.
Comment #5 by ibuclaw — 2018-10-10T22:09:44Z
I can't reproduce an infinite loop, but...
$ time ../../generated/linux/release/64/dmd -v -release -O -inline -m64 -Isrc -c src/gtkc/gtk.d
real 1m38.327s
user 1m37.710s
sys 0m0.512s
Getting close to two minutes compilation time.
Comment #6 by ibuclaw — 2018-10-10T22:49:55Z
Somewhat reduced test:
---
enum LIBRARY
{
GTK
}
struct Linker
{
static void link(T)(ref T funct, string symbol, LIBRARY[] libraries ...)
{
}
}
static this()
{
static foreach(i; 0 .. 10_000)
Linker.link(somefunc, "somefunc", LIBRARY.GTK);
}
void function() c_somefunc;
alias c_somefunc somefunc;
---
To prove that this isn't too much of a contrived test, I checked the compile times of other compilers.
dmd -O -release -inline | 3 minutes 12 seconds.
gdc -O2 -frelease | 6 seconds.
ldc -O2 -release | 8 seconds.
Actually, the dmd compiler segfaults, I assume because I managed to hit a stack overflow.
Comment #7 by b2.temp — 2019-03-03T12:20:49Z
the game changer is more the -O switch than -inline.
The test case with -release -inline gets successfully compiled, even if it's slow (50 secs here).
Comment #8 by safety0ff.bugz — 2020-04-29T23:53:32Z
Once the patch for bug 19550 is applied, this bug should be a duplicate of bug #7157.
The common issue with #7157 is that `aewalk` use an O(N) search for available expressions to reduce expressions. This subsequently leads to a blow of `el_match` calls.
It should be possible to fix this by changing the O(N) search to a sorted search or hashing scheme.