ISR prologue/epilogue register optimization

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

After looking at the ISR() generated code in detail I have a question relating to register optimisation in the actual prologue/epilogue.
I looked through the avr-gcc buglist pointed to in the sticky and didn't see anything that looked similar.

Consider the following simple C isr example:

#include 

volatile int x;
ISR(INT0_vect)
{       
        x = 1;
} 

If you look at the compiled output you will see this
code:

        .file   "isr.c"
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__CCP__  = 0x34
__tmp_reg__ = 0
__zero_reg__ = 1
        .global __do_copy_data
        .global __do_clear_bss
        .text
.global __vector_1
        .type   __vector_1, @function
__vector_1:
        push __zero_reg__
        push r0
        in r0,__SREG__
        push r0
        clr __zero_reg__
        push r24
        push r25
/* prologue: Signal */
/* frame size = 0 */
        ldi r24,lo8(1)
        ldi r25,hi8(1)
        sts (x)+1,r25
        sts x,r24
/* epilogue start */
        pop r25
        pop r24
        pop r0
        out __SREG__,r0
        pop r0
        pop __zero_reg__
        reti
        .size   __vector_1, .-__vector_1
        .comm x,2,1

Pretty much as expected except notice that __zero_reg__
is not used. There is no need to save,clear, and restore this register in this simple case as it is not used and there is no call to other C code that might need it.

If you change the x variable to a "char" you will see that r25 will no longer be used and will not be pushed/popped.
So it looks like the compiler is smart enough to optimize
the register saves/restores in the prologue for those used by the actual code within the function but not smart enough to detect that the __zero_reg__ setup was not necessary.

While this is not a fatal error, it does seem to be a missed optimization.

I have seen this on 3 different versions of the compiler.
8.10 ubuntu 4.3.0-2, 9.04 ubuntus 4.3.2-1 and the
main line gcc version 4.4.0

While I have not yet installed either the sticky or
brad's versions of the compiler, I'm assuming (perhaps incorrectly) this is also in the patched versions since I see it in mainline 4.4 version of gcc and there was no mention of anything similar in the avr gcc buglist.

Can someone with a patched up gcc try this out and see
if it exists in those versions as well?

--- bill

Last Edited: Fri. May 22, 2009 - 10:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

_zero_reg_ is always pushed and popped. I believe that it is simply hardcoded that way (along with _SREG_).

Regards,
Steve A.

The Board helps those that help themselves.

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

If you look at the open bug/change entries I think this is already there isn't it?

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

Somehow I can't add code to my post. So please look at my attachment to get an example how to shorten the ISR prologue/epilogue

Regards
Sebastian

EDIT: For your ISR it isn't neccessary to push/pop SREG. because the LDI and the STS instruction don't change the content of the SREG. (See attachment v2)

Attachment(s): 

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

As I thought - this is an open bug:

http://gcc.gnu.org/bugzilla/show...

Note the reply there from Björn Haase

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

I figured that it might have already been seen.
And it does look like a total pain to fix correctly.

I assume that if timing and code space is that critical it will be best to simply write the entire vector routine in straight assembler rather than C or even mixing C and assembler so you always know what you will get.

S-John, as a minor clarification point, I thought that AVR-gcc stored 16 bit values as little endian. The example code you provided seems to be storing the value of 1 as big endian.
i.e. 0 in &x and 1 in &x+1?
Perhaps just an oops....
Or am I missing something?

As far as the C ISR register "optimization/enhancement" goes,
I guess I should have looked at the official gnu.org Bugzilla list first before I posted this.
(I only looked at the list on nongnu.org - my mistake)

Thank you all for the input and I apologize for wasting peoples time.

--- bill