NO

Author Topic: fatal error #3001: Register pressure too high; try to rearrange the code...  (Read 6599 times)

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
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 ...
« Last Edit: May 25, 2014, 11:56:42 PM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

czerny

  • Guest
Same with V8 RC3, 32bits!

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
frankie: I will look at it, but I can't promise I can do anything about it...
/Pelle

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
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...
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
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...
/Pelle

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
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).
« Last Edit: June 01, 2014, 09:34:41 PM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
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".

/Pelle

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
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.
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
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).
/Pelle

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
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.
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Fixed with V8 RC5!
Great!  8)
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide