Author Topic: How to exclude unused functions  (Read 11570 times)

Offline joneewheelock

  • Multiple posting newcomer
  • *
  • Posts: 11
How to exclude unused functions
« on: November 19, 2016, 02:21:29 am »
I am using Code::Blocks with avr8-gnu-toolchain. Everything is smooth except that code size is not optimized even after I opted for optimize size. I am not an expert. So  in my final object file how to exclude the functions that are not called.
Secondly, I opted for generate list file. But CB is not generating that. Attached is the work space template.

Offline stahta01

  • Lives here!
  • ****
  • Posts: 7592
    • My Best Post
Re: How to exclude unused functions
« Reply #1 on: November 19, 2016, 07:30:22 am »
1. Please try to post your questions in the correct sub-forum [ in the future].
    Edit: Continue using this sub-forum for now with this question; the people on this site do NOT like multiple threads for same question.
2. Please read and follow this site rules http://forums.codeblocks.org/index.php/topic,9996.0.html

If you know, the Compiler Option you need to add and needs help on how to add it; that is a valid question for this site.
If you have no idea what the compiler option is; that is NOT a valid question for this site.

Edit2: My guess is this line is wrong in your project file.
Code
-Wl,-Map=$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).map,--cref

You might try this line instead.
Code
-Wl,-Map=$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).map

But, I do NOT use your Compiler.

Tim S.
« Last Edit: November 19, 2016, 08:03:56 am by stahta01 »
C Programmer working to learn more about C++ and Git.
On Windows 7 64 bit and Windows 10 64 bit.
--
When in doubt, read the CB WiKi FAQ. http://wiki.codeblocks.org

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: How to exclude unused functions
« Reply #2 on: November 19, 2016, 01:50:40 pm »
Try these two options:
Code
-ffunction-sections
-fdata-sections

Read here for more info: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
If your compiler is recent enough you can try to use lto or whole-program optimizations.
Search the internet how to enable it.
You can search the arduino project for details why options to use to get minimal code.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline joneewheelock

  • Multiple posting newcomer
  • *
  • Posts: 11
Re: How to exclude unused functions
« Reply #3 on: November 20, 2016, 09:04:41 am »
The options -ffunction-sections -fdata-sections are for linker right? I tried for both compiler and linker. But still size of the unused function is added to the final object file.
Also why .lss file is not getting generated any idea? I am new to CB so need some help to set this up. My log is given below.

avr-gcc.exe -Os -Wextra -Wall -mmcu=atmega328p -std=gnu99 -fshort-enums -ffunction-sections -fdata-sections -DF_CPU=16000000UL -g -Os -Wmain -Wextra -Wall  -c main.c -o Debug\main.o
avr-g++.exe  -o Debug\AVR_Project.elf Debug\main.o  -mmcu=atmega328p -Wl,-Map=Debug\AVR_Project.map -ffunction-sections -fdata-sections 
Output file is Debug\AVR_Project.elf with size 7.41 KB
Running project post-build steps
avr-objcopy -O ihex -j .text -j .data Debug\AVR_Project.elf Debug\AVR_Project.elf.hex
avr-objcopy --no-change-warnings -j .eeprom --change-section-lma .eeprom=0 -O ihex Debug\AVR_Project.elf Debug\AVR_Project.elf.eep.hex
avr-size --mcu=atmega328p --format=avr Debug\AVR_Project.elf
AVR Memory Usage
----------------
Device: atmega328p
Program:     182 bytes (0.6% Full)
(.text + .data + .bootloader)
Data:          2 bytes (0.1% Full)
(.data + .bss + .noinit)

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3353
Re: How to exclude unused functions
« Reply #4 on: November 20, 2016, 01:15:51 pm »
well according your example project, there is only a main function. I don't know what the compiler should optimize there...

Quote
But still size of the unused function is added to the final object file.
From what do you conclude that?

[EDIT:] NOTE: The linker removes the excessive function, not the compiler. So they are still present in the object file!!! But not in the binary file...

Quote
Device: atmega328p
Program:     182 bytes (0.6% Full)
(.text + .data + .bootloader)
Data:          2 bytes (0.1% Full)
(.data + .bss + .noinit)
128 Bytes are not that much...

Quote
Also why .lss file is not getting generated any idea?
Because according your build log, you don't ask the compiler to generate a ls file:
add this line to post build steps:
Code
cmd /c "avr-objdump -h -S $(TARGET_OUTPUT_FILE) > $(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).lss"
If you work on linux you have to modify it for your environment...

greetings
« Last Edit: November 20, 2016, 01:18:06 pm by BlueHazzard »

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: How to exclude unused functions
« Reply #5 on: November 20, 2016, 01:53:02 pm »
The options -ffunction-sections -fdata-sections are for linker right?
They are only compiler options. It tells the compiler to put every function in a separate section, this means that if the linker finds that a section is not used it can remove it. I don't remember if some linking option should be passed to tell the linker to do this optimization. But this is easily testable - add a function you don't use and check the log if the sizes stay the same then the optimization is working.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline joneewheelock

  • Multiple posting newcomer
  • *
  • Posts: 11
Re: How to exclude unused functions
« Reply #6 on: November 20, 2016, 05:03:18 pm »
Thanks for good response.
well according your example project, there is only a main function. I don't know what the compiler should optimize there...
Sorry that I did not give the complete code. I gave only project folder with main just to give the project settings to you people. Below is the main code (compilable, but does not do anything). Even if f1() is commented or uncommented, the final size remains the same except 4 byte variation for function call itself  (182 or 186 bytes) .

Quote
The linker removes the excessive function, not the compiler. So they are still present in the object file!!! But not in the binary file.
Sorry, could you pl. elaborate this point? I am not clear. Did you mean to say the size 182 bytes displayed is not that of binary file to be written to the controller? When I burn the file, the same 182 byte is displayed as the size written to flash.

Quote
Because according your build log, you don't ask the compiler to generate a ls file

I added avr-objdump -h -S $(TARGET_OUTPUT_FILE) > $(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).ls.
But the listing is getting displayed in build log itself (Causing inconvenience because log will be huge) and no .lss file is getting created. I see a warning message at the end saying "Warning: '>' is not an ordinary file". Also note that while creating new project, I had opted for creating list file. But CB is not generating automatically.

Code
#include <avr/io.h>
#include <util/delay.h>
uint8_t a =12;
void f1 (void);
int main(void)
{


    while (1)
    {
        PORTB=a;
       //f1();

    }

}
void f1 (void)
{
    DDRD=0;
    DDRC=0xff;
    DDRD=0xff;
    uint8_t m=0x50;
    if(m>12)
    {
        PORTD=12;
        PORTC=16;
    }
}


Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3353
Re: How to exclude unused functions
« Reply #7 on: November 21, 2016, 04:02:34 pm »
Sorry that I did not give the complete code. I gave only project folder with main just to give the project settings to you people. Below is the main code (compilable, but does not do anything). Even if f1() is commented or uncommented, the final size remains the same except 4 byte variation for function call itself  (182 or 186 bytes) .
yea, the output of avr-size is the amount of bytes that could be written on the controller

I added avr-objdump -h -S $(TARGET_OUTPUT_FILE) > $(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).ls.But the listing is getting displayed in build log itself (Causing inconvenience because log will be huge) and no .lss file is getting created. I see a warning message at the end saying "Warning: '>' is not an ordinary file". Also note that while creating new project, I had opted for creating list file. But CB is not generating automatically.
i think the problem with this is, that the redirect/stream operator ">" does not work in the pre/post build steps in codeblocks. You have to use the line
Code
cmd /c "avr-objdump -h -S $(TARGET_OUTPUT_FILE) > $(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).lss"
or
Code
xterm -e "avr-objdump -h -S $(TARGET_OUTPUT_FILE) > $(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).lss"
on linux (i did not test this, and obviously you need xterm installed)

i think you need to add
Code
-ffunction-sections -fdata-sections
to the compiler settings
and
Code
--gc-sections

or
Code
-Wl,--gc-sections
to the linker settings. I am not quite sure if codeblocks calls the linker directly

the first command:
The options -ffunction-sections -fdata-sections are for linker right?
They are only compiler options. It tells the compiler to put every function in a separate section, this means that if the linker finds that a section is not used it can remove it.
So the functions are still present in the object file
then you call the linker with the second command and the linker will garbage collect your unused functions...

greetings

Offline joneewheelock

  • Multiple posting newcomer
  • *
  • Posts: 11
Re: How to exclude unused functions
« Reply #8 on: November 21, 2016, 06:00:48 pm »
Quote
From BlueHazzard

Perfect. Now everything seems to be OK after I added -Wl,--gc-sections to linker settings and also adding cmd /c "avr-objdump -h -S $(TARGET_OUTPUT_FILE) > $(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).lss" to post build.
Now codeblock is setup completely for AVR. Attached is the template if someone else need this. In case anyone finds any other issues, please let me know. I can correct and update the template.

For those who are not familiar with templates:
Where to copy the template?
Type %appdata% in start menu and then go to codeblocks folder. Copy the UserTemplates folder from the attached zip file file to this codeblocks location. Now you can go to New->From Template option and then create your new project.

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3353
Re: How to exclude unused functions
« Reply #9 on: November 21, 2016, 07:04:20 pm »

Beside from the garbage collection compiler switches Codeblocks has an embedded template (wizard script) for avr. Why are you not using this? From there i have the lss command line ;)

Offline joneewheelock

  • Multiple posting newcomer
  • *
  • Posts: 11
Re: How to exclude unused functions
« Reply #10 on: November 23, 2016, 04:03:31 am »

Beside from the garbage collection compiler switches Codeblocks has an embedded template (wizard script) for avr. Why are you not using this? From there i have the lss command line ;)

Compared to Atmel Studio, Codeblocks is very fast. I felt codeblocks very good barring few issues. But  I do not think AVR template is completely usable. Even in AVRFreaks I saw some comments about this usage issues. I myself struggled to build with default settings and now comfortable to some extent. I hope someone will update the template. The issues I had faced are:
Codeblocks makes use of WINAVR2010. There is a latest tool-chain available from atmel and it should be used for addressing few issues.
-std=gnu99 is not by default.
-ffunction-sections -fdata-sections is not by default.
size option is not by default.
.lss is not getting generated even if we opt for that
There are few other default settings that could be set in the avr template I guess.

I will be very happy to see updated CB template.



Offline stahta01

  • Lives here!
  • ****
  • Posts: 7592
    • My Best Post
Re: How to exclude unused functions
« Reply #11 on: November 23, 2016, 05:44:51 am »
Do you know the difference between an CB Wizard and a CB Template?

Edit: Because I have no idea if your issues is with the CB Wizard or with a CB Template!

Tim S.
« Last Edit: November 23, 2016, 07:12:20 am by stahta01 »
C Programmer working to learn more about C++ and Git.
On Windows 7 64 bit and Windows 10 64 bit.
--
When in doubt, read the CB WiKi FAQ. http://wiki.codeblocks.org

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3353
Re: How to exclude unused functions
« Reply #12 on: November 23, 2016, 01:55:58 pm »
I think we are interested to help and make the wizard as usable as possible, so lets please work on this:
It is a long time since i last developed for AVR so i need some refreshing:
Quote
Codeblocks makes use of WINAVR2010. There is a latest tool-chain available from atmel and it should be used for addressing few issues.
Codeblocks does not come with any compiler/library so where is the difference on USING the newer compiler? Do you mean the auto detection of the compiler?
I know there are problems with the fuses, so have you some tips how fuses work on the new compiler?

Quote
-ffunction-sections -fdata-sections is not by default.
Can be added, but i don't think this is a good idea, i mean you develop on a 8 bit controller with no memory. You should know what the thing do. If you let it up to the compiler to remove functions you don't use, why not remove them from the code. If you only code without thinking about optimization and relay only on the compiler to do the work you end with this shitty coded phone apps ;). But as i noted at the beginning, this could be added.

Quote
size option is not by default.
Is easy to change. Can be done

Quote
.lss is not getting generated even if we opt for that
The command line I gave you is the exact same as generated by the wizard, so i don't know why this does not work. The biggest problem with the actual implementation is that it can't be used platform independent. But this can be fixed...

Quote
There are few other default settings that could be set in the avr template I guess.
Can you please elaborate? As I/we are really interested to fix this

greetings

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: How to exclude unused functions
« Reply #13 on: November 24, 2016, 09:48:13 pm »
joneewheelock: The wizard is a simple squirrel script that anyone can edit. When you're finished you can propose patches.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline joneewheelock

  • Multiple posting newcomer
  • *
  • Posts: 11
Re: How to exclude unused functions
« Reply #14 on: November 25, 2016, 03:40:23 am »
I think we are interested to help and make the wizard as usable as possible, so lets please work on this:
I really appreciate the support. It will help new uses like me. I am not expert. So definitely there are some issues in my explanation earlier or below.
 
Quote
Codeblocks does not come with any compiler/library so where is the difference on USING the newer compiler? Do you mean the auto detection of the compiler?
Yes, I mean default compiler now must be changed to latest one. If there is a plugin, it would be better so that compiler is also installed after installing CB.
Also please exclude selecting fuse.c. I do not know much about it. But I usually exclude that.

The biggest problem is adding new tool for programming and getting it working. The moment we add a tool such as AVRdude+Arduino, I get below error message. I have to change in post build settings every time I create a new project. This is what my major headache. It will be very good if you can add a wizard to add programming tools with USBASP and Arduino UNO options. Arduino is the big market and if some plugins can be added so that arduino code can be directly run after the installation, it might click. Biggest problem with arduino is very bad IDE.

Attached is the instructions I prepared for setting up codeblocks. You may understand few issues from this. Today when I tried, lss file and size information was getting generated. Let me try this with fresh CB installation and see. I had issues even if they were selected in wizard. Need to duplicate the problem and update you after a week or so.

Error message when burning (Refer post build settings in the instructions attached to fix the problem)

Tool execution terminated with status 1
Launching tool 'nano': C:\Atmega\programmers\avrdude\avrdude.exe -C"C:\Atmega\programmers\avrdude\avrdude.conf" -patmega328p -carduino -PCOM4 -b57600 -Uflash:w:tempPrj.elf.hex (in C:\temp\tempPrj\Debug)
stderr>
stderr> avrdude.exe: AVR device initialized and ready to accept instructions
stderr>
stderr> Reading | ################################################## | 100% 0.00s
stderr>
stderr> avrdude.exe: Device signature = 0x1e950f
stderr> avrdude.exe: NOTE: "flash" memory has been specified, an erase cycle will be performed
stderr>              To disable this feature, specify the -D option.
stderr> avrdude.exe: erasing chip
stderr> avrdude.exe: reading input file "tempPrj.elf.hex"
stderr> avrdude.exe: error opening tempPrj.elf.hex: No such file or directory
stderr> avrdude.exe: input file tempPrj.elf.hex auto detected as invalid format
stderr> avrdude.exe: can't open input file tempPrj.elf.hex: No such file or directory
stderr> avrdude.exe: read from file 'tempPrj.elf.hex' failed
stderr>
stderr> avrdude.exe done.  Thank you.
stderr>
Tool execution terminated with status 1

Offline Krice

  • Almost regular
  • **
  • Posts: 150
Re: How to exclude unused functions
« Reply #15 on: November 25, 2016, 01:05:23 pm »
Everything is smooth except that code size is not optimized even after I opted for optimize size. I am not an expert. So  in my final object file how to exclude the functions that are not called.

If the program is extremely small then optimization flags (-Ox) are not that effective. More depends on how you write the code. Compiler optimization is mainly designed for "normal" projects and has varying results depending on a lot of stuff. Sometimes different levels of -O is giving surprising results both in speed and size of the program, so you should try every level. And the last tip, don't write functions that are not used in the project, it's considered bad design.