unable to find a register to spill in class 'POINTER_REGS' error

I’m implementing ‘trainable neural network’ (a code by Giorgi Butbaia ) in my ATTINY85 chip and can’t fix this error.

what I implemented :

//Code by Giorgi Butbaia

//Define Weights
float w_111 = 0.4*random(256)/255.0 - 0.2;
float w_112 = 0.4*random(256)/255.0 - 0.2;
float w_113 = 0.4*random(256)/255.0 - 0.2;

float w_121 = 0.4*random(256)/255.0 - 0.2;
float w_122 = 0.4*random(256)/255.0 - 0.2;
float w_123 = 0.4*random(256)/255.0 - 0.2;

float b_21 = 0.4*random(256)/255.0 - 0.2;
float b_22 = 0.4*random(256)/255.0 - 0.2;
float b_23 = 0.4*random(256)/255.0 - 0.2;

float w_211 = 0.4*random(256)/255.0 - 0.2;
float w_221 = 0.4*random(256)/255.0 - 0.2;
float w_231 = 0.4*random(256)/255.0 - 0.2;

float b_31 = 0.4*random(256)/255.0 - 0.2;

//Define Helper Functions
float sigmoid(float z)
{
  return 1.0/(1.0+exp(-z));
}

float forwardProp(float y_11, float y_12)
{
  float y_21 = sigmoid(b_21 + w_111*y_11 + w_121*y_12);
  float y_22 = sigmoid(b_22 + w_112*y_11 + w_122*y_12);
  float y_23 = sigmoid(b_23 + w_113*y_11 + w_123*y_12);
  
  float y_31 = sigmoid(b_31 + w_211*y_21 + w_221*y_22 + w_231*y_23);
  return y_31;
}

float error(float T[], float y_11_d[], float y_12_d[], int dataSize)
{
  //Initialize variables
  float err = 0.0; 
  float y_31 = 0.0;
  for(int i = 0; i < dataSize; i++)
  {
    y_31 = forwardProp(y_11_d, y_12_d);
    err += exp(pow(y_31 - T,2));
  }
  return err - dataSize;
}

float train(float T[], float y_11_d[], float y_12_d[], int num_iter, float rate, boolean reinitializeWeights, int dataSize) //Returns error on dataset
{
  //Serial.println("Initializing Variables");
  if(reinitializeWeights)
  {
    w_111 = 0.4*random(256)/255.0 - 0.2;
    w_112 = 0.4*random(256)/255.0 - 0.2;
    w_113 = 0.4*random(256)/255.0 - 0.2;
  
    w_121 = 0.4*random(256)/255.0 - 0.2;
    w_122 = 0.4*random(256)/255.0 - 0.2;
    w_123 = 0.4*random(256)/255.0 - 0.2;
  
    b_21 = 0.4*random(256)/255.0 - 0.2;
    b_22 = 0.4*random(256)/255.0 - 0.2;
    b_23 = 0.4*random(256)/255.0 - 0.2;
  
    w_211 = 0.4*random(256)/255.0 - 0.2;
    w_221 = 0.4*random(256)/255.0 - 0.2;
    w_231 = 0.4*random(256)/255.0 - 0.2;
  
    b_31 = 0.4*random(256)/255.0 - 0.2;
  }
  //Initialize variables, to avoid reinitialization during each iteration
  float dw_111 = 0.0;
  float dw_112 = 0.0;
  float dw_113 = 0.0;
      
  float dw_121 = 0.0;
  float dw_122 = 0.0;
  float dw_123 = 0.0;
      
  float db_21 = 0.0;
  float db_22 = 0.0;
  float db_23 = 0.0;
      
  float dw_211 = 0.0;
  float dw_221 = 0.0;
  float dw_231 = 0.0;
      
  float db_31 = 0.0;
  
  float t_n = 0.0;
  float y_11 = 0.0;
  float y_12 = 0.0;
      
  float y_21 = 0.0;
  float y_22 = 0.0;
  float y_23 = 0.0;
      
  float y_31 = 0.0;
  //Start training
  //Serial.print("Starting Loop, dataSize: "); Serial.println(dataSize);
  for(int iteration = 0; iteration < num_iter; iteration++)
  {
    //Serial.println("Iteration");
    for(int i = 0; i < dataSize; i++)
    {
      //Gather data
      t_n = T;
      y_11 = y_11_d;
      y_12 = y_12_d;
      
      y_21 = sigmoid(b_21 + w_111*y_11 + w_121*y_12);
      y_22 = sigmoid(b_22 + w_112*y_11 + w_122*y_12);
      y_23 = sigmoid(b_23 + w_113*y_11 + w_123*y_12);
      
      y_31 = sigmoid(b_31 + w_211*y_21 + w_221*y_22 + w_231*y_23);
      //Compute derivatives
      dw_111 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_211 * y_21*(1.0-y_21) * y_11;
      dw_112 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_221 * y_22*(1.0-y_22) * y_11;
      dw_113 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_231 * y_23*(1.0-y_23) * y_11;
      
      dw_121 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_211 * y_21*(1.0-y_21) * y_12;
      dw_122 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_221 * y_22*(1.0-y_22) * y_12;
      dw_123 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_231 * y_23*(1.0-y_23) * y_12;
      
      db_21 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_211 * y_21*(1.0-y_21);
      db_22 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_221 * y_22*(1.0-y_22);
      db_23 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_231 * y_23*(1.0-y_23);
      
      dw_211 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * y_21;
      dw_221 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * y_22;
      dw_231 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * y_23;
      
      db_31 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31);
      
      //Update weights
      w_111 -= rate*dw_111;
      w_112 -= rate*dw_112;
      w_113 -= rate*dw_113;
      
      w_121 -= rate*dw_121;
      w_122 -= rate*dw_122;
      w_123 -= rate*dw_123;
      
      b_21 -= rate*db_21;
      b_22 -= rate*db_22;
      b_23 -= rate*db_23;
      
      w_211 -= rate*dw_211;
      w_221 -= rate*dw_221;
      w_231 -= rate*dw_231;
      
      b_31 -= rate*db_31;
    }
  }
  //Serial.println("Training has Finished");
  return error(T, y_11_d, y_12_d, dataSize);
}

//Initialize arrays, with maximum number of entries 10
float T[20];
float y_11_d[20];
float y_12_d[20];
//TODO delete this:
//float T[] = {0.0, 1.0, 1.0, 0.0};
//float y_11_d[] = {0.0, 0.0, 1.0, 1.0};
//float y_12_d[] = {0.0, 1.0, 0.0, 1.0};

int y_11_P = A3; //Input neuron y_1^(1)
int y_12_P = A2; //Input neuron y_1^(2)

int y_31_IN = A1; //Input for the result t_n

int add_to_dataset = 1; //Training Mode: Adding Entry in dataset
int y_31_OUT = 1; //Acting Mode: Outputing the result of the forward propagation algorithm

int switchPin = 0;

boolean mode = true; //True corresponds to training mode, whereas false cooresponds to acting mode
void setup()
{
  pinMode(switchPin, INPUT);
  pinMode(y_11_P, INPUT);
  pinMode(y_12_P, INPUT);
  pinMode(add_to_dataset, INPUT);
}

//Debouncing variables
boolean prevAddState = LOW; //Previous state of the add_to_dataset pin, to avoid duplicates
boolean prevSwitchState = LOW; //Previous state of switchPin

int dataSize = 0;//since data is dynamically allocated sizeof method will not work
void loop()
{
  if(mode) //Training Mode
  {
    /////////////////////////////////////////////////////////////////
    ///////////////// add_to_dataset pin ////////////////////////////
    /////////////////////////////////////////////////////////////////
    if(digitalRead(add_to_dataset) == HIGH && prevAddState == LOW)
    {
      dataSize++;
      T[dataSize - 1] = analogRead(y_31_IN)/1023.0;
      y_11_d[dataSize -1] = analogRead(y_11_P)/1023.0;
      y_12_d[dataSize -1 ] = analogRead(y_12_P)/1023.0;
      
      prevAddState = HIGH;
      delay(500); //To avoid bouncing effect
    }
    else
    {
      prevAddState = LOW;
    }
    
    
    //////////////////////////////////////////////////////////////
    /////////////////// Switch Pin ///////////////////////////////
    //////////////////////////////////////////////////////////////
    if(digitalRead(switchPin) == HIGH && prevSwitchState == LOW)
    {
      //Start the training process
      if(dataSize != 0)
      {
        pinMode(y_31_OUT, OUTPUT); //Set DDR of y_31_OUT pin 
        analogWrite(y_31_OUT, 255.0);
        
        train(T, y_11_d, y_12_d, 2000, 0.5, true, dataSize); //train without weight re-initialization
        
        for(int i = 0; i < 5; i++) //Blinking is equivalent to switching mode
        {
          analogWrite(y_31_OUT, 255);
          delay(500);
          analogWrite(y_31_OUT, 0);
          delay(500);
        }
        mode = false; //Switch Mode
      }
      
      prevSwitchState = HIGH;
      delay(100); //To avoid bouncing effect
    }
    else {
      prevSwitchState = LOW;
    }
  }
  else {
    //Forward Propagate during each iteration
    analogWrite(y_31_OUT, 255.0*forwardProp(analogRead(y_11_P)/1023.0, analogRead(y_12_P)/1023.0));
    if(digitalRead(switchPin) == HIGH && prevSwitchState == LOW)
    {      
      //Indicate switch of mode by means of blinking LED
      for(int i = 0; i < 5; i++)
      {
        analogWrite(y_31_OUT, 255);
        delay(500);
        analogWrite(y_31_OUT, 0);
        delay(500);
      }
      
      mode = true; //Switch mode
      pinMode(add_to_dataset, INPUT);
      prevSwitchState = HIGH;
      delay(500);
    }
    else
    {
      prevSwitchState = LOW;
    }
  }
}
//}

And this throws the following error when compiled:

Trainable_Neural_Net:160: error: unable to find a register to spill in class 'POINTER_REGS'

Trainable_Neural_Net:160: error: this is the insn:

(insn 269 268 271 5 (set (reg/v:SF 109 [ t_n ])

        (mem:SF (post_inc:HI (reg:HI 150 [ ivtmp.129 ])) [2 MEM[base: _228, offset: 0B]+0 S4 A8])) C:\Users\user\Desktop\000?뿰援?\0怨쇳깘\?떊寃쎈쭩\?븘?몢?씠?끂肄붾뱶\Trainable_Neural_Net\Trainable_Neural_Net.ino:110 100 {*movsf}

     (expr_list:REG_INC (reg:HI 150 [ ivtmp.129 ])

        (nil)))

Why can't you post your code like you posted your error message?

You've hit what seems to be a known compiler bug. Which version of the IDE? One solution (for older IDE) suggests to change the optimising; might still be applicable.

Google results for unable to find a register to spill in class

I just get a bunch of "cannot convert 'float*' to 'float' in assignment" errors when I compile that code. Did you, perhaps, lose a bunch of subscripts when the sketch got posted somewhere without code tags? I indexed all the array references with 'i' and it now it compiles without error for me. Target: Arduino UNO, Arduino Version: 1.8.5

That is a well-known compiler bug that has existed for some time (I first saw it about a year ago). A different version of the IDE might get around it. IME, simply making inane changes to the code - like moving functions to a different place in the source file, will often make the error go away.

Regards, Ray L.

Here's the relevant issue in the arduino/Arduino repository: https://github.com/arduino/Arduino/issues/3972 @nanabi did you try the workaround described in that thread here?: https://github.com/arduino/Arduino/issues/3972#issuecomment-147707385