[Top][All Lists]

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

Re: [avr-libc-dev] Definition of putchar/getchar causes code growth

From: Bernard Fouché
Subject: Re: [avr-libc-dev] Definition of putchar/getchar causes code growth
Date: Fri, 04 Jul 2008 16:54:13 +0200
User-agent: Thunderbird (Windows/20080421)


I just began yesterday to move from gcc-4.2.0/avr-libc-1.4.6 to gcc-4.3.0/avr-libc-1.6.2 (with the patches taken from WINAVR0610).

I first experienced a significant code growth (about 4%) because of:

- functions like eeprom_read/write_byte() that now inline more code, hence I had to write wrapper functions like you did in your example for putchar(). In a previous run of 'hand optimization', I did replace fputc() calls directly to 'myputc' (stream->putc()), sparing even more bytes (the size of fputc()) while getting more speed (often the checks performed in fputc() (i.e. (if((stream->flags...)) are useless (depends on the application considered)).

- gcc-4.3.0 seems to automatically inline bigger static functions than gcc-4.2.0. I have to use -finline-limit to a very low value like 10.

I now have a code size with gcc-4.3.0/avr-libc-1.6.2 a litle bit smaller than with gcc-4.2.0/avr-libc-1.4.6. (and I will have to perform extensive tests to check that the application still works :)) and I reclaimed the 256 bytes of RAM that were previously lost because of __clz_tab (my main reason for moving to a newer compilation chain)

IMHO the 'stock' distribution of avr-gcc/avr-libc should be tuned to give results as good (hence small) as possible with -Os since most of the traffic in the mailing lists seems code size oriented, so I have a point of view similar to Wouter.

Or have link options like '-lprintf_min' for features that would be compiled in different ways to meet the user goals.

Or have conditional compilation of headers according to the optimization required, (so in Wouter's case putchar() would be kept as a function call with -Os, but replaced with fputc() with -O2/3), however I dunno if there is a macro or something already defined allowing this without passing yet another -D option to the compiler.


Wouter van Gulik wrote:
Hi list,

Currently putchar is defined as
#define     putchar(__c)   fputc(__c, stdout)

which causes C code like this:
putchar(' ')

To generate assembler like this:
lds r22,__iob+2
lds r23,(__iob+2)+1
ldi r24,lo8(32)
ldi r25,hi8(32)
call fputc

This is 8 bytes (lds == 4 bytes) for loading the stream pointer.
If we change this to a "real" putchar call we would save 8 bytes per putchar call. the putchar call would then load the correct stream:

int putchar(int c)
{ return fputc(stdout, c);

The cycle penalty would be the extra call and return.
IMHO losing 7,8 or 10 cycles per call for a gain of 8 bytes per call seems very acceptable to me. Especially if it concerns functions like putchar and friends.

Other opinions? Otherwise I will file a bug report.


AVR-libc-dev mailing list

reply via email to

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