avoid inline function

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I use WinAVR-20100110 (and it should not be changed for this project)
I have this function

void smalldelay(){
volatile int i ;
  for (i=0;i<100;i++)
    ;
}

And even when I compile with -Os it make the function inline (I call it 20+ times)
First why ?
And how to avoid it ?

Correction I call it 14 times,

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

And how to avoid it ?

__attribute__((noinline)) void smalldelay(void){
volatile int i ;
  for (i=0;i<100;i++)
    ;
} 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks it just cut off about 350 bytes of code.
But why does the compiler want to make inline code when used so many times.
I would understand that -O3 and even -O2 would do so, but not -Os

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess the question is whether -finline-small-functions is part of -Os ?

EDIT: user manual:

http://gcc.gnu.org/onlinedocs/gc...

reveals:

-O2
    Optimize even more. GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff. As compared to -O, this option increases both compilation time and the performance of the generated code.

    -O2 turns on all optimization flags specified by -O. It also turns on the following optimization flags:
...
          -finline-small-functions 
...

and

-Os
    Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size.

    -Os disables the following optimization flags:

              -falign-functions  -falign-jumps  -falign-loops 
              -falign-labels  -freorder-blocks  -freorder-blocks-and-partition 
              -fprefetch-loop-arrays

I guess that leaves -finline-small-functions as part of -Os.

I did forget to say that as well as the attribute that just acts on that one function you can use -Os and then -fnoinline-small-functions to over-ride it for everything.

(in fact you can use -fno to turn off any of the options that have been activated)

EDIT2: actually that text does say "that do not typically increase code size" - I guess it's wrong about -finline-small-functions if it is left active.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Perhaps a bit stupid but I'm not used to change anything inside the file

__attribute__((noinline)) void smalldelay(void){ 
volatile int i ; 
  for (i=0;i<100;i++) 
    ; 
}

Will that only disable inline for this function, or will it be for the rest of the file?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why would that be a stupid question.

__attribute__(()) is similar to qualifiers or specifiers - it applies only to the "object" next to which it is "written".

http://gcc.gnu.org/onlinedocs/gc...

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks
Now I looked at -finline-limit=n
where n set the limit of what is a small-function
but it does not really explain how to set n
any examples for a AVR?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sorry an extra question
now I gave the compiler -fno-inline
and the code got even smaller
How do I see which functions the compiler/linker make inline?
The LSS and MAP files does not seem to change, so I must assume that the optimizer run after those files are made.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

The LSS and MAP files does not seem to change

Then something's wrong - if the code changes the .lss should.

You could of course also -save-temps and study the .s file. What's more you could make it even easier to read:

http://spaces.atmel.com/gf/proje...

;-)

Quote:
Will that only disable inline for this function, or will it be for the rest of the file?

You possibly missed the EDIT: I added later above.
I wrote:
I did forget to say that as well as the attribute that just acts on that one function you can use -Os and then -fnoinline-small-functions to over-ride it for everything.

(in fact you can use -fno to turn off any of the options that have been activated)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK correction
the LSS file change but the code for the function itself so the function code exist even when not used.
But worse this code

smalldelay();
smalldelay();
smalldelay();

Is wrong in the inline version it make two delays then my IO flip and then the last delay. I think I better write this in ASM so the timing can be better controlled.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you want specific timing then why on Earth would you use a C function in the first place? C knows nothing about timing. That is why the developers of avr-gcc included the functions in .

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't need an accurate timing just at least a delay, and this way (with no parameters) I expected a rcall each time instead of the way the delay function does it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why would you care whether or not there is an rcall? Surely you just want the time that it takes to be enough. What opcodes the delay routine uses to take up that time is irrelevant.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Because he optimize for size and don't want 14 copies of the same piece of code?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can eliminate inlining by placing the called function in its own file (compilation unit).
Absent link-time or other multi-file optimizations, inlining will not occur.

Iluvatar is the better part of Valar.