main.cpp: 51:1: error: unable to find a register to spill in class 'NO_REGS

I assume the cited error message has to do with register optimization, but how on earth do I figure out what the actual problem is?

Here is the whole error output:

Compiling 'TwoHeadTest' for 'Arduino/Genuino Mega w/ ATmega2560 (Mega 2560)'
Build Folder: file:///C:/Users/RayL/AppData/Local/Temp/VMBuilds/TwoHeadTest/mega_atmega2560/Debug
 
main.cpp: In function main

Error linking for board Arduino/Genuino Mega w/ ATmega2560 (Mega 2560)
 
Build failed for project 'TwoHeadTest'
main.cpp: 51:1: error: unable to find a register to spill in class 'NO_REGS
 
main.cpp: 51:1: error: this is the insn
(insn 1010 1007 1013 53 (set (mem*: QI (post_dec:HI (reg\f:HI 32 __SP_L__)) [0  S1 A8])
        (subreg*: QI (reg\f:HI 635) 1)) C:\Users\RayL\AppData\Local\Temp\VMBuilds\TwoHeadTest\mega_atmega2560\Debug\TwoHeadTest.cpp:413 1 {pushqi1}
     (expr_list*: REG_ARGS_SIZE (const_int 1 [0x1])
   (nil)))
main.cpp:51: confused by earlier errors, bailing out
lto-wrapper*: C:\Users\RayL\Documents\AppData\Arduino\arduino-1.8.2\hardware\tools\avr\bin\avr-gcc returned 1 exit status
 
ld.exe: error: lto-wrapper failed
 
collect2.exe*: error: ld returned 1 exit status

The source line cited in (413:1 in TwoHeadTest.cpp) contains nothing but an #endif directive, and the code compiles without error when the #if is true. Full code is attached.

Regards,
Ray L.

TwoHeadTest.ino (10.7 KB)

Wonderful.... Compiler bug. Adding this at the top of the file works around it:

void loop() attribute((optimize("O2")));

Regards,
Ray L.

Now this is kinda pi**ing me off.... Forcing the optimization on loop() made the problem go away. UNTIL I made some edits, then it came back. So, I UNcommented the line forcing optimization, and it again compiled ok. UNTIL I made some more edits, at which point it started giving me completely BS errors! IT complains about variables that don't exist, but they DO exist. It complains InitializeAP() cannot be used as a function but it IS a perfectly valid function!

This frickin' compiler seems to have lost it's mind! I'm using v1.8.2. Is there a better, more stable version now?

Here is the error output from compiling the attached sketch. The error message complains that TimerMode is undefined, but it flags a line BEFORE it is defined, or used! It complains that function InitializeAP is being re-defined as another type, yet there is NOTHING else with that name anywhere. Get a load of the last error message - it quotes a line of source code, but what it quotes DOES NOT MATCH that line in the source code! It has been corrupted!

Compiling 'TwoHeadTest' for 'Arduino/Genuino Mega w/ ATmega2560 (Mega 2560)'
Build Folder: file:///C:/Users/RayL/AppData/Local/Temp/VMBuilds/TwoHeadTest/mega_atmega2560/Debug
 
TwoHeadTest.ino: 12:22: error: 'TimerModes' was not declared in this scope
   boolean InitializeAP(TimerModes mode)
 
TwoHeadTest.ino: 13:22: error: variable or field 'InitializeTimer' declared void
   void InitializeTimer(TimerModes mode)
 
TwoHeadTest.ino: 13:22: error: 'TimerModes' was not declared in this scope
Error compiling .ino project source
Build failed for project 'TwoHeadTest'
 
TwoHeadTest.ino: In function boolean InitializeAP(TimerModes)
 
TwoHeadTest.ino: 222:37: error: 'boolean InitializeAP(TimerModes)' redeclared as different kind of symbol
   boolean InitializeAP(TimerModes mode)
TwoHeadTest.ino:12: note  previous declaration boolean InitializeAP
   boolean InitializeAP(TimerModes mode)
 
TwoHeadTest.ino: In function void setup()
 
TwoHeadTest.ino: 326:26: error: 'InitializeAP' cannot be used as a function
   InitializeAP(TimerMode)
 
TwoHeadTest.ino: 336:26: error: 'InitializeAP' cannot be used as a function
   InitializeAP(TimerMode)
 
TwoHeadTest.ino: 344:4: error: expected ')' before 'TimerMode
    TimerMode = TimerModes*: TIMER

Regards,
Ray L.

TwoHeadTest.ino (12.9 KB)

v1.8.4 gives the same results....

Regards,
Ray L.

In the code you posted, there's a missing parenthesis and semicolon at the end of the call to InitializeTimer:

		default:
			// Timer
			InitializeTimer(TimerMode
			TimerMode = TimerModes::TIMER;
			break;

Pete

Interesting, because it's correct in the code I have. But if you fix that, does it compile for you?

There is no question this is a serious compiler bug, and it's been there for some time, as it happens in v1.8.1, v1.8.4 and v1.8.5. I can comment out blocks of code, somewhat randomly, and the problem either goes away, or simply moves to another place in the code. The register optimization bug comes and goes at random as well.

I was making great progress on this project until this hit and now Im completely dead in the water, and have no clue what to do...

Regards,
Ray L.

I don't have the ESP libraries installed so I can't play with the code.
I have also encountered that same error message. In that case, the problem was that an algebraic statement was too complicated and breaking it up into several separate steps fixed it.
Another user had the same problem in [this thread]=Help, I have error: unable to find a register to spill in class 'POINTER_REGS' - Programming Questions - Arduino Forum]this thread](http://=https://forum.arduino.cc/index.php?topic=397909.0). The solution turned out to be to move some of the code into a function. I suspect that this solution may fix your problem too but at the moment, I'm not sure which code should be moved although my shot from the hip is to try cutting down on the if/else/if/... that involves strcmp.

Pete

You nailed it! I moved the whole "parser" out of loop() and into a function, and now it compiles. Though with what I've seen today, I won't be surprised if another change makes it come back.

I'd sure like to know what's really going on....

Thanks much!

Regards,
Ray L.

Same trouble here. Tried all the versions, all the different optimizations. The only workaround so far has been to reduce or change code until the damn thing compiles. The common message is "main.cpp:51:1: error: unable to find a register to spill in class 'NO_REGS'".

I thought this might be related to a possibility that the compiler may have trouble handling resources when the code and data usages become too large as mine reports 90% of dynamic memory usage. However, I've seen other users reduce code all the way down to 1K or less and still see problems.

I looking forward to really seeing a final fix to this, hopefully the new GCC 7.0 or above will finally banish this - if it ever gets into this IDE. Otherwise, I might have to switch to AVR commercial tools - ugh.

Nothing to do with code size or compiler resources, the gcc compiler routinely handles vast code bases.
What's happening is a specific pattern of use that's found a bug in the AVR code-generator. You should
try and report this (find the bug tracker for avr-gcc, not gcc itself - and have a good search for any existing bug report that might be the same thing - don't report it if its already in the system, that hinders rather than helping)

This might be the place: AVR Toolchain Bugs

MarkT, what you say makes sense. In the interrim, I was able to get my code to compile by switching to the AVR Studio 7 package from Microchip. But after loading the Arduino extension, it appears that their IDE just uses the same compiler and AVR-gcc from the Arduino installation. Yet, it compiles nicely! The MicroAVR extension has a free trial period.

me too, but i think i gained a bit of (unhelpful) insight into the issue.

i ran into this error on 1.8.4 on my two debian machines, so i installed 1.8.5 on my sole remaining windows 10 machine (from the microsoft toy store; bodes poorly for my relationship with Arduino). still fails, but now i get error messages. below.

1.8.4 (avr 4.9.2?) and gcc segfaults. no help there. but 1.8.5 actually returns errors, lo!

(btw, the O2 optimization made the error go hide, but i'm sure it will be back, too.)

with compiler verbosity on, i got ...

Arduino: 1.8.5 (Windows Store 1.8.10.0) (Windows 10), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

much blah blah removed here...


C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.10.0_x86__mdqgnx93n4wtt\hardware\arduino\avr\cores\arduino\main.cpp: In function 'main':

C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.10.0_x86__mdqgnx93n4wtt\hardware\arduino\avr\cores\arduino\main.cpp:51:1: error: unable to find a register to spill in class 'NO_REGS'

 }

 ^

C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.10.0_x86__mdqgnx93n4wtt\hardware\arduino\avr\cores\arduino\main.cpp:51:1: error: this is the insn:

(insn 3339 3336 3342 248 (set (mem:QI (post_dec:HI (reg/f:HI 32 __SP_L__)) [0  S1 A8])

        (subreg:QI (reg/f:HI 2151) 1)) C:\Users\tomic\Documents\Arduino\libraries\SR_Resources/SRLog.h:304 1 {pushqi1}

     (expr_list:REG_ARGS_SIZE (const_int 9 [0x9])

        (nil)))

C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.10.0_x86__mdqgnx93n4wtt\hardware\arduino\avr\cores\arduino\main.cpp:51: confused by earlier errors, bailing out

SRLog.h is my code, it's simple, old, and OK, badly written:

(simplified)

struct _time {
    uint8_t sec; 
    uint8_t min;
    uint8_t hour;
    uint8_t mday;
    uint8_t mon; 
    int16_t year;
    uint8_t wday;
    uint8_t yday;
};

struct _time t;

char * timeStr (char buff[]) {

  gtod (&t);
  sprintf (buff, "%2u:%2u:%2u", t.hour, t.min, t.sec);
  return buff;
}

char * dateStr (char buff[]) {

  gtod (&t);
  sprintf (buff, "%04u/%2u/%02u", t.year, t.mon, t.mday);
  return buff;
}

**** if EITHER or both sprintf() is commented out, it compiles fine.

obviously the struct t elements are uint8 hence wrong size on the stack, but i think the compiler's been fixing my misteak for me... but this isn't it, as casts to unsigned nor even conversion to actual local unsigned vars doesn't fix this.

commenting out either sprintf does. so whatever optimization is being done in the compiler, gcc may only be able to handle N of them, and i have N + 1, or other gcc-internal variable management issue.