Pelles C forum

Pelles C => Bug reports => Topic started by: frankie on May 25, 2014, 11:38:54 PM

Title: fatal error #3001: Register pressure too high; try to rearrange the code...
Post by: frankie on May 25, 2014, 11:38:54 PM
Not sure this is a bug or not.
PellesC V8 RC4, 32bits.
Try to compile this snippet:
Code: [Select]
void Filler(COLORREF color[][512] )
{
for (int j=0; j<256; j++)
{
//   basic colors:
color[0][j] = RGB(j, 0, 0) ; //red 255,0,0
color[1][j] = RGB(j, j/2, 0); //orange 255,127,0
color[2][j] = RGB(j, j, 0) ; //yellow 255,255,0
color[3][j] = RGB(0, j, 0) ; //green 0,255,0
color[4][j] = RGB(0, j/2, 0 ); //dgreen  0,128,0
color[5][j] = RGB(j/4, j/2, j/2 );  //bluegreen 64,127,127
color[6][j] = RGB(0, j, j) ; //sky blue 0,255,255
color[7][j] = RGB(0, 0, j) ; //blue 0,0,255
color[8][j] = RGB(j, 0, j) ; //pink 255,0,255
color[9][j] = RGB(j/2, 0, (2*j)/3 ); //purple 127,0,170
color[10][j]= RGB(j/2, 0, j/4 );  //burgundy 128,0,64
color[11][j]= RGB(j/2, j/3, j/6 );  //brown 127,85,42
color[12][j]= RGB(j/2, j/2, j/2 );  //gray 127,127,127


}

for (int j=0; j<256; j++)
{
color[0][j+256] = RGB(255, j, j) ;
color[1][j+256] = RGB(255, 127+j/2, j) ;
color[2][j+256] = RGB(255, 255, j) ;
color[3][j+256] = RGB(j, 255, j) ;
color[4][j+256] = RGB(j, 127+j/2, j );
color[5][j+256] = RGB(64+3*j/4, 127+j/2, 127+j/2 );
color[6][j+256] = RGB(j, 255, 255) ;
color[7][j+256] = RGB(j, j, 255) ;
color[8][j+256] = RGB(255, j, 255) ;
color[9][j+256] = RGB(127+j/2, j, 170+j/3 ) ;
color[10][j+256]= RGB(127+j/2, j, 64+3*j/4 );
color[11][j+256]= RGB(127+j/2, 85+2*j/3, 42+5*j/6 );
color[12][j+256]= RGB(127+j/2, 127+j/2, 127+j/2 );
}
}

You'll get the error " fatal error #3001: Register pressure too high; try to rearrange the code (around line ...)".
The lines are that of first index == 11 (if you comment the line in the first for loop it will appear on the next one).
The point is that honestly can't understand what can be rearrenged ...
Title: Re: fatal error #3001: Register pressure too high; try to rearrange the code...
Post by: czerny on May 26, 2014, 08:17:52 AM
Same with V8 RC3, 32bits!
Title: Re: fatal error #3001: Register pressure too high; try to rearrange the code...
Post by: Pelle on May 29, 2014, 11:49:37 AM
frankie: I will look at it, but I can't promise I can do anything about it...
Title: Re: fatal error #3001: Register pressure too high; try to rearrange the code...
Post by: frankie on May 29, 2014, 09:15:57 PM
Thanks Pelle,
can you please just add some explanation about the issue, what could be the workaround ?
You know it's a little bit confusing because it is involved just a window macro...
Title: Re: fatal error #3001: Register pressure too high; try to rearrange the code...
Post by: Pelle on June 01, 2014, 01:02:20 PM
The sequence of expressions is the main point. There are too many simultaneously alive expressions (subexpressions).

For this case, you can get around the problem by changing:
Code: [Select]
color[11][j]= RGB(j/2,  j/3,    j/6 );to:
Code: [Select]
volatile int r = j/2, g = j/3, b = j/6;
color[11][j]= RGB(r, g, b);

This should be handle by the code generator and/or register allocator, but I can't say why it fails right now...
Title: Re: fatal error #3001: Register pressure too high; try to rearrange the code...
Post by: frankie on June 01, 2014, 09:32:55 PM
Thanks,
but what I worry is that a failure on a such apparently simple line could be source of other problems on apparently trivial code.
I would suggest to put it on todo list...  ;)

P.S. this is an existing code that compiled well on previous versions, I'll try to check when the trouble started maybe could help (tracing register allocator changes).
Title: Re: fatal error #3001: Register pressure too high; try to rearrange the code...
Post by: Pelle on June 06, 2014, 10:20:21 AM
The register allocator itself is not to blame, it's has been virtually unchanged for a number of versions. It's machine-independent and does what it's supposed to do well, AFAICT.

The register allocator works on the code produced by the code generators (X86 and X64 today, ARM in past, maybe something else in the future), and above all the *constraints* added by the code generators. Both X86 and X64 are "irregular" in the sense that not all register can be used everywhere. Some instructions, like divide, expects input/output in one or more specific registers. The X86 machine is also constrained by having just six 16/32-bit registers and only four 8-bit registers. Compare this with X64 where you have sixteen registers for 8/16/32/64 bits as well as floating-point.

The code produced by the code generators can change with each version because of new optimizations etc. The constraints can change too, for various reasons that are too long to explain. I certainly expect problems like this happening for X86 again, but not for X64 (which we are heading, but too slow in my opinion).

What I can do here is to replace a "hack" in the register allocator that reserves one of the four byte-register for X86 (as a "scratch" register) with a proper interface function (located in the code generator) that has more knowledge about the specific machine (X86). This seems to solve this case, as well as older cases that introduced the "hack".

Title: Re: fatal error #3001: Register pressure too high; try to rearrange the code...
Post by: frankie on June 07, 2014, 11:02:25 PM
Thanks Pelle,
it's clear now.
A hack is a right solution, a compiler failure on such trivial code lines could be a real limit to the whole compiler.
I understood that reserving a register as scratch on a register limited CPU like the X86 will limit the code optimizations, but could be a reasonable price to pay.
Title: Re: fatal error #3001: Register pressure too high; try to rearrange the code...
Post by: Pelle on June 09, 2014, 06:25:03 PM
I will *remove* a hack and replace it with something better (more work, that's why a hack was choosen the first time around).
You may think this code is trivial, but the way the code and macro is written this is a good stress test for the register allocator (in X86 mode).
Title: Re: fatal error #3001: Register pressure too high; try to rearrange the code...
Post by: frankie on June 10, 2014, 11:11:31 AM
You may think this code is trivial, but the way the code and macro is written this is a good stress test for the register allocator (in X86 mode).
Pelle I didn't meant that the macro expansion gave *trivial*code, this macro is complex indeed.
I meant that it is trivial the use of the macro, code like this can be everywhere. A beginner, or even standard programmers, can't imagine what headheach can come out after expansion, but sure they will complain on compiler failure for apparently simple code.
Thanks.
Title: Re: fatal error #3001: Register pressure too high; try to rearrange the code...
Post by: frankie on July 06, 2014, 10:07:30 PM
Fixed with V8 RC5!
Great!  8)