How to get rid of unused functions to reduce code size

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

Hi,
in my map file I see 2 versions are present:

.text._Z18IsSameDirectionDEGff
                0x00005d18       0x70 UAVDEV.o
                0x00005d18                IsSameDirectionDEG(float, float)

 .text._Z18IsSameDirectionRADff
                0x00005d88       0x52 UAVDEV.o
                0x00005d88                IsSameDirectionRAD(float, float)

However only Z18IsSameDirectionRADff is being used in the code (100% sure). This concerns many cases in my code.

My compilation options:

Build started 9.9.2009 at 11:01:39
avr-g++ -I"C:\WinAVR-20090313\avr\include\avr"  -mmcu=atmega128 -Wall --pedantic -fno-exceptions -DATMEGA128 -fno-threadsafe-statics  -ffunction-sections -fdata-sections     -ansi  -DF_CPU=14745600UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -
fshort-enums -MD -MP -MT UAVDEV.o -MF dep/UAVDEV.o.d  -c  ../UAVDEV.c
avr-g++ -mmcu=atmega128 -Wl,-u,vfprintf -Wl,-u,vfscanf -lm  -Wl,--gc-sections -Wl,-Map=UAVDEV.map UAVDEV.o    -lc -lm -lprintf_flt -lscanf_flt  -o UAVDEV.elf
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature  UAVDEV.elf UAVDEV.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex UAVDEV.elf UAVDEV.eep || exit 0
avr-objdump -h -S UAVDEV.elf > UAVDEV.lss

AVR Memory Usage
----------------
Device: atmega128

Program:  130982 bytes (99.9% Full)
(.text + .data + .bootloader)

Data:       3779 bytes (92.3% Full)
(.data + .bss + .noinit)

Now the question is what next.
I have tried various options with little success.
I am missing something basic about gcc for AVR :-(
BTW the whole code is "include all" so everybody sees everybody. This should be easiest for space optimization.
Help!

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

I think you will find that Z18IsSameDirectionDEGff() is referenced on line 47 of your code.

I would assume that the avr-gcc linker will remove an unreferenced function. However the traditional behaviour of "ld" is to link every function in a specified compilation unit and only be selective with libraries.

You can probably alter any avr-gcc action with an appropriate command option.

But if your functions are essentially the same, I am surprised that you do not just write a macro:

#define Z18IsSameDirectionDEGff(x) Z18IsSameDirectionRADff((x)/57.2957795)   

Your code would be easier to maintain, and you would have a single function.

But the simple answer is to grep your source files for your mystery function. That is of course if you have enough fingers to type your identifiers. (or will to live)

David.

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

Quote:

I would assume that the avr-gcc linker will remove an unreferenced function. However the traditional behaviour of "ld" is to link every function in a specified compilation unit and only be selective with libraries.

You can probably alter any avr-gcc action with an appropriate command option.


David,

The linker does not do that by default (only if .o's in .'a are used in which case only the used .o's will be linked - as with the system .a's)

However the OP is using "-ffunction-sections" to the compiler and "Wl,--gc-sections" to the linker. The effect of this is to put each function into a separate named section then the command to the linker causes it to "garbage collect" the unused memory sections. So this *SHOULD* have ensured that uncalled functions are discarded.

The implication of this is either (a) the function IS being called or (b) there's something wrong with func-sects/gc-sects

My vote goes for (a).

One thing to try is to add options to the .map file generation to get an Xref table included.

Cliff

PS actually grep'ing the source is almost certainly the easiest option