[Issue 3681] ICE(go.c): when function takes too long to optimize, only with -O.

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon Nov 22 00:51:53 PST 2010


http://d.puremagic.com/issues/show_bug.cgi?id=3681


Don <clugdbug at yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch


--- Comment #5 from Don <clugdbug at yahoo.com.au> 2010-11-22 00:50:30 PST ---
CAUSE: This section of the optimiser can only remove one comma expression per
pass. So, the limit should be set based on the depth of comma expressions.
I don't know what the minimum iteration limit should be (the number of passes
for performing all other optimisations) -- when setting it to 10, as in the
code below, the test suite passes; a level of 5 is too low.

Note that the total limit used to be set to 80, before it was increased to 200.
I am certain that the 80 was caused by comma expressions. Need to run this
through the DMC test suite, to see what the minimum iteration limit should be.

----------


PATCH: Add this function to go.c. Actually it needs to used in the fix for bug
4379, as well. So maybe it should go into another file, or appear in a header
file.


/*
   Return the maximum nesting of comma expressions in the elem tree.
   For example,  (((a, b) + c),d) * (e,f)  has comma depth 2.
*/
int commaDepth(elem *e)
{
    if ( EBIN(e))
    {
        int depth = (e->Eoper == OPcomma) ? 1 : 0;
        return depth + commaDepth(e->E1) + commaDepth(e->E2);
    }
    else if (EUNA(e))
        return commaDepth(e->E1);
    return 0;
}

Then, go.c, optfunc(), around line 230:

   if (localgot)
    {   // Initialize with:
        //      localgot = OPgot;
        elem *e = el_long(TYnptr, 0);
        e->Eoper = OPgot;
        e = el_bin(OPeq, TYnptr, el_var(localgot), e);
        startblock->Belem = el_combine(e, startblock->Belem);
    }

+    // Each pass through the loop can reduce only one level of comma
expression.
+    // The infinite loop check needs to take this into account.
+    int iterationLimit = 10;
+    for (b = startblock; b; b = b->Bnext)
+    {
+        if (!b->Belem)
+            continue;
+        int d = commaDepth(b->Belem);
+        if (d > iterationLimit)
+            iterationLimit = d;
+    }       

    // Some functions can take enormous amounts of time to optimize.
    // We try to put a lid on it.
    starttime = clock();
    do
    {
        //printf("iter = %d\n", iter);
#if TX86
        //assert(++iter < 80);          /* infinite loop check           */
-        assert(++iter < 200);           /* infinite loop 
+        assert(++iter < iterationLimit);           /* infinite loop check     
     */
#else

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list