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

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3681 - ICE(go.c): when function takes too long to optimize, only with -O.
Summary: ICE(go.c): when function takes too long to optimize, only with -O.
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: Other All
: P2 normal
Assignee: No Owner
URL:
Keywords: ice-on-valid-code, patch
Depends on:
Blocks: 3761
Show dependency tree / graph
Reported: 2010年01月06日 12:05 UTC by brien
Modified: 2014年04月18日 09:12 UTC (History)
4 users (show)

See Also:


Attachments
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description brien 2010年01月06日 12:05:19 UTC
against 1.055
might be a regression of issue 2773
compiling with optimization crashes the compiler.
 public final class A {
 private this() {
 int i =0;
 int j = i +1;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 i = j * 15;
 j = i * 59;
 }
 }
Comment 1 Lars T. Kyllingstad 2010年01月06日 14:00:25 UTC
This also fails with DMD 2.039.
Internal error: backend/go.c 244
Comment 2 Don 2010年01月07日 00:02:12 UTC
(In reply to comment #0)
> against 1.055
> 
> might be a regression of issue 2773 
It isn't a regression. This is ancient -- it fails on DMD 0.175.
Comment 3 Don 2010年01月11日 21:10:35 UTC
The problem is simply that the optimiser needs too much time. The optimiser loops for a maximum of 200 times, but to optimize this example requires 290 loops.
On the line it's faulting on:
- assert(++iter < 200);
+ assert(++iter < 290);
However, there'll always be _some_ example where this happens. So a different approach is required. Maybe after 200 check that the number of elements is still decreasing on each pass through the loop; if it is, then just silently exit the loop without ICEing.
Comment 4 Kosmonaut 2010年02月12日 11:42:15 UTC
SVN Changeset: http://www.dsource.org/projects/dmd/changeset/376 
Comment 5 Don 2010年11月22日 00:50:30 UTC
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
Comment 6 Walter Bright 2010年12月26日 23:46:39 UTC
http://www.dsource.org/projects/dmd/changeset/821 


AltStyle によって変換されたページ (->オリジナル) /