Optimizing with GCC

Hi, I have a _VERY_ small program here : A FreeRTOS kernel running one single task (besides idle), where 4 LEDs are blinking. The thing is that the program takes up 44400 bytes !!! The MAP file tells me that a lot of unused functions still are in the hex-file. Functions like AT91F_UDP_GetInterruptMaskStatus from lib_AT91SAM7S256.h and "/cygdrive/c/gnuarm/bin/../lib/gcc/arm-elf/4.1.0/interwork/libgcc.a(_udivsi3.o)" What do I do in order to remove the dead code ? /RaceMouse

Optimizing with GCC

Yuk.  Sound like you have the whole C library library included in your executable.  I presume you are not doing any division (other than compile time constants)? Which GCC distribution are you using?  Is it one targeted at embedded?

Optimizing with GCC

Hi, It’s: arm-elf-gcc 4.1.0 Binutils 2.16.1 Newlib 1.14.0 Basically it’s GnuArm – latest… /RaceMouse

Optimizing with GCC

I am also using the latest gnuarm.  When I compile the LPC2106 demo I get a bin file (after objcopying the default elf file to bin) that is 15K.  This is the whole unmodified demo. Which sam7 project are your compiling?  Is it in the download so I can try it?

Optimizing with GCC

It’s the lwIP_Rowley, where I have removed all lwip/usb and the just addad the one task blinking the LEDs. I changed the heap size to 3000 and changed the AT91SAM7X256 to AT91SAM7S256. /RaceMouse

Optimizing with GCC

I checked the size on the LPC2106_GCC build and i was the ~17K. I cannot, however, seem to find any relevant diffs in the two Makefiles. The Linkerfils from the two projects are also identical (Except the RAM/ROM mapping off course)… Any Ideas ? /RaceMouse

Optimizing with GCC

Not that it helps but I get the same result as you.  I removed all lwIP, demo, emac and usb references from the makefile and edited main so only the setup hardware and check task remains.  I get a 42K binary.  Very odd.  I will take a look at the map file also.  Must be the atmel library?

Optimizing with GCC

Using CrossWorks the demo comes to 8K once the lwIP stuff is removed.

Optimizing with GCC

Ill’ be damned ! So – what is the difference between a normal CLI built executable and one built using Crossworks ? Crossworks don’t use the Makefile, do they ? Is there any way to see what commands they use with GCC ? /RaceMouse

Optimizing with GCC

In FreeRTOSConfig.h, set configUSE_TRACE_FACILITY to 0.  I think this might make a big difference as the trace facility will pull in lot of string handling functions which GCC is not very efficient at. There are ways of controlling this, I read a thread on it somewhere recently but I cannot remember where unfortunately. Let me know if this sorts out your problem. Regards.

Optimizing with GCC

Well, It definately helped a lot. The executable size has now dropped from ~44K to ~9K, so we are getting there… The following is a snippet from the MAP file: .text          0x001004ec      0xe04 lib_AT91SAM7S256_.o                 0x00100cac                AT91F_UDP_EpClear                 0x00100cd8                AT91F_UDP_GetInterruptMaskStatus                 0x001010fc                AT91F_PWMC_IsInterruptMasked                 0x001006ec                AT91F_CKGR_EnableMainOscillator Only a couple of the functions in lib_AT91SAM7S256_ are used and yet they are all included by in the executable. Do you have any idea how I can eliminate them ? /RAceMouse

Optimizing with GCC

I have got my build down to 5.5K, quite nice really ;-) Looking in the map file there are no AT91 functions at all. Looking in the code I find that the portable layer is using AT91F_AIC_ConfigureIt(), but I have #defined this to a macro in the header file, hence it does not use the library functions. The library functions are unfortunately a bit IAR centric.  They use inline functions rather than macros.  You can define away the inline and create a load of functions, but this is not really a good solution.  If you can get the inline functions to work as inline functions you should have the optimised solution.  I believe there was a post some time back on this forum about how to do this.  You had to setup some #define to the correct ‘inline’ keyword, maybe __inline or something like that. My preference is to use the inline functions as a guide, then implement my own equivalents, as I did with the AT91F_AIC_ConfigureIt().  This is fine provided you are not using too many of them. Regards.

Optimizing with GCC

I see your point, but still : Should GCC not be able to optimese away unused code ? I saw an another forum (can’t remember where) that the following Compiler flags should do the trick: CFLAGS += -ffunction-sections CFLAGS += -fdata-sections CFLAGS += -Wl,–gc-sections The linker file would have to edited afterwords. I could, however, not make it work. Has anyone got any experience with this ? /RaceMouse

Optimizing with GCC

The Linker script had to be edited: <–snip–> SECTIONS {     . = 0;     .startup : {         KEEP(*(.startup))     }>flash     .text : <–!snip–> and *(.data) to *(.data.*) *(.text) to *(.text.*) The KEEP() directive did the trick. The OS is now running and uses ~3.7K Flash. Thanks for the help :-)