avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] avr-gcc making really bad inlining decisions.


From: Bill Westfield
Subject: Re: [avr-gcc-list] avr-gcc making really bad inlining decisions.
Date: Thu, 9 Apr 2015 16:45:09 -0700

> -fdump-ipa-cgraph and -fdump-ipa-inline where
> the description looks like it could shed some light on that.

The most obvious problematic function is move3Servos, and I've
attached some info extracted from the cgraph and inline dumps below.
I can't really make heads or tails of it, except...  Separate
evaluations for whether arguments are constants or not?  In this case,
the function is usually called with constant arguments (and "big"
arguments at that) - is the compiler producing a bad estimate of how
much space it can save by taking advantage of those constant
arguments?  I didn't see any params for adjusting the cost of argument
passing...

(BTW, I realize this is pretty awful code to start with; that's not
the point...)

BillW

============ Preprocessed source code ===============

void move3Servos(Servo servo1Name, float target_pos1,Servo servo2Name,
float target_pos2,Servo servo3Name, float target_pos3,float easing){

    target_pos1 =
((target_pos1)<(600)?(600):((target_pos1)>(2400)?(2400):(target_pos1)));
    target_pos2 =
((target_pos2)<(600)?(600):((target_pos2)>(2400)?(2400):(target_pos2)));
    target_pos3 =
((target_pos3)<(600)?(600):((target_pos3)>(2400)?(2400):(target_pos3)));
    easing = ((easing)<(0.0)?(0.0):((easing)>(5.0)?(5.0):(easing)));

   float current_pos1 = servo1Name.readMicroseconds();
   float current_pos2 = servo2Name.readMicroseconds();
   float current_pos3 = servo3Name.readMicroseconds();

   float diff1, diff2, diff3;

  while(true){

     diff1 = target_pos1 - current_pos1;
     diff2 = target_pos2 - current_pos2;
     diff3 = target_pos3 - current_pos3;

     if( fabs(diff1) > 5.0 ) {
       if(easing <= 1.00) current_pos1 += diff1 * easing;
         else {
           if(diff1 > 0.0) current_pos1 += easing;
           else current_pos1 -= easing;
       }
        servo1Name.writeMicroseconds( (int)current_pos1 );
     }
     if( fabs(diff2) > 5.0 ) {
       if(easing <= 1.00) current_pos2 += diff2 * easing;
         else {
           if(diff2 > 0.0) current_pos2 += easing;
           else current_pos2 -= easing;
       }
        servo2Name.writeMicroseconds( (int)current_pos2 );
     }
    if( fabs(diff3) > 5.0 ) {
       if(easing <= 1.00) current_pos3 += diff3 * easing;
         else {
           if(diff3 > 0.0) current_pos3 += easing;
           else current_pos3 -= easing;
       }
        servo3Name.writeMicroseconds( (int)current_pos3 );
     }
     else if(fabs(diff1)<=5.0 && fabs(diff2) <=5.0 && fabs(diff3) <=5.0){
        break;
       }
     delay(15);
  }
}


================= cgraph dump ============================

_Z11move3Servos5ServofS_fS_ff/145 (void move3Servos(Servo, float,
Servo, float, Servo, float, float)) @0x419518c0
  Type: function
  Visibility: public
  Aux: @0x41951960  References:
  Referring:
  Function flags: analyzed body finalized
  Called by: _Z7doseOffv/144 (1.00 per call) _Z7doseOffv/144 (1.00 per
call) _Z7doseOffv/144 (1.00 per call) _Z7doseOffv/144 (1.00 per call)
_Z7doseOffv/144 (1.00 per call) _Z7doseOffv/144 (1.00 per call)
_Z7doseOffv/144 (1.00 per call) _Z7doseOffv/144 (1.00 per call)
_Z7doseOffv/144 (1.00 per call) _Z7doseOffv/144 (1.00 per call)
_Z6sneezev/143 (1.00 per call) _Z6sneezev/143 (1.00 per call)
_Z6sneezev/143 (1.00 per call) _Z6sneezev/143 (1.00 per call) loop/142
(1.00 per call) loop/142 (1.00 per call) loop/142 (1.00 per call)
loop/142 (1.00 per call) loop/142 (1.00 per call) loop/142 (1.00 per
call) loop/142 (1.00 per call) loop/142 (1.00 per call) loop/142 (1.00
per call) loop/142 (1.00 per call) loop/142 (1.00 per call) loop/142
(1.00 per call) loop/142 (1.00 per call) loop/142 (1.00 per call)
loop/142 (1.00 per call) loop/142 (1.00 per call) loop/142 (1.00 per
call) loop/142 (1.00 per call) loop/142 (1.00 per call) loop/142 (1.00
per call) loop/142 (1.00 per call) loop/142 (1.00 per call) loop/142
(1.00 per call) loop/142 (1.00 per call) loop/142 (1.00 per call)
loop/142 (1.00 per call) loop/142 (1.00 per call) loop/142 (1.00 per
call) loop/142 (1.00 per call) loop/142 (1.00 per call) loop/142 (1.00
per call) loop/142 (1.00 per call) loop/142 (1.00 per call) loop/142
(1.00 per call) loop/142 (1.00 per call) loop/142 (1.00 per call)
loop/142 (1.00 per call) loop/142 (1.00 per call) loop/142 (1.00 per
call) loop/142 (1.00 per call) loop/142 (1.00 per call)


================= inline data dump =========================

Analyzing function: void move3Servos(Servo, float, Servo, float,
Servo, float, float)/107
;; 2 loops found
;;
;; Loop 0
;;  header 0, latch 1
;;  depth 0, outer -1
;;  nodes: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
;;
;; Loop 1
;;  header 19, latch 43
;;  depth 1, outer 0
;;  nodes: 19 43 39 40 41 42 33 26 32 28 30 31 29 27 25 21 23 24 22 20
35 37 38 36 34
;; 2 succs { 6 3 }
;; 3 succs { 5 4 }
;; 4 succs { 5 }
;; 5 succs { 6 }
;; 6 succs { 10 7 }
;; 7 succs { 9 8 }
;; 8 succs { 9 }
;; 9 succs { 10 }
;; 10 succs { 14 11 }
;; 11 succs { 13 12 }
;; 12 succs { 13 }
;; 13 succs { 14 }
;; 14 succs { 18 15 }
;; 15 succs { 17 16 }
;; 16 succs { 17 }
;; 17 succs { 18 }
;; 18 succs { 19 }
;; 19 succs { 20 26 }
;; 20 succs { 21 22 }
;; 21 succs { 25 }
;; 22 succs { 23 24 }
;; 23 succs { 25 }
;; 24 succs { 25 }
;; 25 succs { 26 }
;; 26 succs { 27 33 }
;; 27 succs { 28 29 }
;; 28 succs { 32 }
;; 29 succs { 30 31 }
;; 30 succs { 32 }
;; 31 succs { 32 }
;; 32 succs { 33 }
;; 33 succs { 34 40 }
;; 34 succs { 35 36 }
;; 35 succs { 39 }
;; 36 succs { 37 38 }
;; 37 succs { 39 }
;; 38 succs { 39 }
;; 39 succs { 43 }
;; 40 succs { 41 43 }
;; 41 succs { 42 43 }
;; 42 succs { 44 43 }
;; 43 succs { 19 }
;; 44 succs { 1 }

Analyzing function body size: void move3Servos(Servo, float, Servo,
float, Servo, float, float)

Inline summary for void move3Servos(Servo, float, Servo, float, Servo,
float, float)/107 inlinable
  self time:       4586
  global time:     0
  self size:       87
  global size:     0
  self stack:      0
  global stack:    0
    size:0.000000, time:0.000000, predicate:(true)
    size:2.000000, time:0.000000, predicate:(not inlined)
    size:2.000000, time:2.000000, predicate:(op1 changed)
    size:2.000000, time:0.990000, predicate:(op1 changed) && (op1 not constant)
    size:2.000000, time:2.000000, predicate:(op3 changed) && (op1 <
6.0e+2 || op1 > 2.4e+3 || op1 not constant) && (op1 < 6.0e+2 || op1
not constant)
    size:2.000000, time:0.990000, predicate:(op3 changed) && (op3 not
constant) && (op1 < 6.0e+2 || op1 > 2.4e+3 || op1 not constant) &&
(op1 < 6.0e+2 || op1 not constant)
    size:2.000000, time:2.000000, predicate:(op5 changed) && (op3 <
6.0e+2 || op3 > 2.4e+3 || op3 not constant) && (op3 < 6.0e+2 || op3
not constant) && (op1 < 6.0e+2 || op1 > 2.4e+3 || op1 not constant) &&
(op1 < 6.0e+2 || op1 not constant)
    size:2.000000, time:0.990000, predicate:(op5 changed) && (op5 not
constant) && (op3 < 6.0e+2 || op3 > 2.4e+3 || op3 not constant) &&
(op3 < 6.0e+2 || op3 not constant) && (op1 < 6.0e+2 || op1 > 2.4e+3 ||
op1 not constant) && (op1 < 6.0e+2 || op1 not constant)
    size:2.000000, time:2.000000, predicate:(op6 changed) && (op5 <
6.0e+2 || op5 > 2.4e+3 || op5 not constant) && (op5 < 6.0e+2 || op5
not constant) && (op3 < 6.0e+2 || op3 > 2.4e+3 || op3 not constant) &&
(op3 < 6.0e+2 || op3 not constant) && (op1 < 6.0e+2 || op1 > 2.4e+3 ||
op1 not constant) && (op1 < 6.0e+2 || op1 not constant)
    size:2.000000, time:1.450000, predicate:(op6 changed) && (op6 not
constant) && (op5 < 6.0e+2 || op5 > 2.4e+3 || op5 not constant) &&
(op5 < 6.0e+2 || op5 not constant) && (op3 < 6.0e+2 || op3 > 2.4e+3 ||
op3 not constant) && (op3 < 6.0e+2 || op3 not constant) && (op1 <
6.0e+2 || op1 > 2.4e+3 || op1 not constant) && (op1 < 6.0e+2 || op1
not constant)
    size:48.000000, time:1980.374000, predicate:(op6 < 0.0 || op6 >
5.0e+0 || op6 not constant) && (op6 < 0.0 || op6 not constant) && (op5
< 6.0e+2 || op5 > 2.4e+3 || op5 not constant) && (op5 < 6.0e+2 || op5
not constant) && (op3 < 6.0e+2 || op3 > 2.4e+3 || op3 not constant) &&
(op3 < 6.0e+2 || op3 not constant) && (op1 < 6.0e+2 || op1 > 2.4e+3 ||
op1 not constant) && (op1 < 6.0e+2 || op1 not constant)
    size:1.000000, time:1.982000, predicate:(op6 < 0.0 || op6 > 5.0e+0
|| op6 not constant) && (op6 < 0.0 || op6 not constant) && (op5 <
6.0e+2 || op5 > 2.4e+3 || op5 not constant) && (op5 < 6.0e+2 || op5
not constant) && (op3 < 6.0e+2 || op3 > 2.4e+3 || op3 not constant) &&
(op3 < 6.0e+2 || op3 not constant) && (op1 < 6.0e+2 || op1 > 2.4e+3 ||
op1 not constant) && (not inlined)
  calls:
    void delay(long unsigned int)/121 function body not available
      loop depth: 1 freq:87495 size: 2 time: 11 callee size: 0 stack:
0 predicate: (op6 < 0.0 || op6 > 5.0e+0 || op6 not constant) && (op6 <
0.0 || op6 not constant) && (op5 < 6.0e+2 || op5 > 2.4e+3 || op5 not
constant) && (op5 < 6.0e+2 || op5 not constant) && (op3 < 6.0e+2 ||
op3 > 2.4e+3 || op3 not constant) && (op3 < 6.0e+2 || op3 not
constant) && (op1 < 6.0e+2 || op1 > 2.4e+3 || op1 not constant) &&
(op1 < 6.0e+2 || op1 not constant)
       op0 is compile time invariant
    void Servo::writeMicroseconds(int)/120 function body not available
      loop depth: 1 freq:44247 size: 3 time: 12 callee size: 0 stack:
0 predicate: (op6 < 0.0 || op6 > 5.0e+0 || op6 not constant) && (op6 <
0.0 || op6 not constant) && (op5 < 6.0e+2 || op5 > 2.4e+3 || op5 not
constant) && (op5 < 6.0e+2 || op5 not constant) && (op3 < 6.0e+2 ||
op3 > 2.4e+3 || op3 not constant) && (op3 < 6.0e+2 || op3 not
constant) && (op1 < 6.0e+2 || op1 > 2.4e+3 || op1 not constant) &&
(op1 < 6.0e+2 || op1 not constant)
       op0 is compile time invariant
    void Servo::writeMicroseconds(int)/120 function body not available
      loop depth: 1 freq:44247 size: 3 time: 12 callee size: 0 stack:
0 predicate: (op6 < 0.0 || op6 > 5.0e+0 || op6 not constant) && (op6 <
0.0 || op6 not constant) && (op5 < 6.0e+2 || op5 > 2.4e+3 || op5 not
constant) && (op5 < 6.0e+2 || op5 not constant) && (op3 < 6.0e+2 ||
op3 > 2.4e+3 || op3 not constant) && (op3 < 6.0e+2 || op3 not
constant) && (op1 < 6.0e+2 || op1 > 2.4e+3 || op1 not constant) &&
(op1 < 6.0e+2 || op1 not constant)
       op0 is compile time invariant
    void Servo::writeMicroseconds(int)/120 function body not available
      loop depth: 1 freq:44247 size: 3 time: 12 callee size: 0 stack:
0 predicate: (op6 < 0.0 || op6 > 5.0e+0 || op6 not constant) && (op6 <
0.0 || op6 not constant) && (op5 < 6.0e+2 || op5 > 2.4e+3 || op5 not
constant) && (op5 < 6.0e+2 || op5 not constant) && (op3 < 6.0e+2 ||
op3 > 2.4e+3 || op3 not constant) && (op3 < 6.0e+2 || op3 not
constant) && (op1 < 6.0e+2 || op1 > 2.4e+3 || op1 not constant) &&
(op1 < 6.0e+2 || op1 not constant)
       op0 is compile time invariant
    int Servo::readMicroseconds()/129 function body not available
      loop depth: 0 freq:1000 size: 3 time: 12 callee size: 0 stack: 0
predicate: (op6 < 0.0 || op6 > 5.0e+0 || op6 not constant) && (op6 <
0.0 || op6 not constant) && (op5 < 6.0e+2 || op5 > 2.4e+3 || op5 not
constant) && (op5 < 6.0e+2 || op5 not constant) && (op3 < 6.0e+2 ||
op3 > 2.4e+3 || op3 not constant) && (op3 < 6.0e+2 || op3 not
constant) && (op1 < 6.0e+2 || op1 > 2.4e+3 || op1 not constant) &&
(op1 < 6.0e+2 || op1 not constant)
       op0 is compile time invariant
    int Servo::readMicroseconds()/129 function body not available
      loop depth: 0 freq:1000 size: 3 time: 12 callee size: 0 stack: 0
predicate: (op6 < 0.0 || op6 > 5.0e+0 || op6 not constant) && (op6 <
0.0 || op6 not constant) && (op5 < 6.0e+2 || op5 > 2.4e+3 || op5 not
constant) && (op5 < 6.0e+2 || op5 not constant) && (op3 < 6.0e+2 ||
op3 > 2.4e+3 || op3 not constant) && (op3 < 6.0e+2 || op3 not
constant) && (op1 < 6.0e+2 || op1 > 2.4e+3 || op1 not constant) &&
(op1 < 6.0e+2 || op1 not constant)
       op0 is compile time invariant
    int Servo::readMicroseconds()/129 function body not available
      loop depth: 0 freq:1000 size: 3 time: 12 callee size: 0 stack: 0
predicate: (op6 < 0.0 || op6 > 5.0e+0 || op6 not constant) && (op6 <
0.0 || op6 not constant) && (op5 < 6.0e+2 || op5 > 2.4e+3 || op5 not
constant) && (op5 < 6.0e+2 || op5 not constant) && (op3 < 6.0e+2 ||
op3 > 2.4e+3 || op3 not constant) && (op3 < 6.0e+2 || op3 not
constant) && (op1 < 6.0e+2 || op1 > 2.4e+3 || op1 not constant) &&
(op1 < 6.0e+2 || op1 not constant)
       op0 is compile time invariant



reply via email to

[Prev in Thread] Current Thread [Next in Thread]