I don't want unreferenced functions!

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

Hello.
As you all know, the flash space is very limited.. so I don't want avr-gcc to compile unreferenced functions.
How can I do that? Currently I'm using the -Os flag for size optimizations...
Here's a test:

...
void wow()
{
	printf("sunt wow!\n");
	uartTxSync();

}

void wow2()
{
	printf("sunt wow2!\n");
	uartTxSync();
}
...

with those functions:

AVR Memory Usage
----------------
Device: atmega8
Program:    6034 bytes (73.7% Full)
(.text + .data + .bootloader)
Data:        483 bytes (47.2% Full)
(.data + .bss + .noinit)

and without them

AVR Memory Usage
----------------
Device: atmega8
Program:    5892 bytes (71.9% Full)
(.text + .data + .bootloader)
Data:        463 bytes (45.2% Full)
(.data + .bss + .noinit)

Thank you in advance,
Nicu.

Nicu reSpawn.

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

Did you try moving those sometimes referenced functions into separate files? The linker will likely have an easier time excluding an unreferenced function if it is a separate object file.

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

Hi Kevin,
I haven't. If I would do that I would waste time making a special file for every function ... I guess there is a special parameter but I couldn't find it.
later edit:
I've found this post http://gcc.gnu.org/ml/gcc/1999-1... about this.
I've tried those parameters on gcc and ld and I have the same result.

Nicu reSpawn.

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

check this-
https://www.avrfreaks.net/index.p...

don't know if it helps you or not, though

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

reSpawn wrote:
If I would do that I would waste time making a special file for every function ... I guess there is a special parameter but I couldn't find it.
I'm using IAR now so I've not kept up with learning to get the most out of GCC. But, in general, if you are make a library of functions for reuse that may or may not be linked into your project, the time to make a set of small files you maintain may be worth it. The link that curtvm supplied to you has some excellent points about library creation as well as probably the compiler and linker options that you are searching for.

BTW, IAR automatically removes unused functions without a command-line option. Instead, IAR has a C extension to indicate that you want a function or variable included in the output, even if that function/variable is unreferenced.

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

Use static:

Quote:
static void wow()
Since no other code references wow in the same file, the compiler can ignore it. Otherwise, the compiler must include it in case wow is used in another file.

Perhaps the linker has an option to identify dead code, but apparently that behavior is not the default.

C: i = "told you so";

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

reSpawn wrote:
I don't want avr-gcc to compile unreferenced functions.
The two functions that you've written have global scope so the compiler cannot possibly know whether or not they're referenced from other modules. Consequently, the compiler must include them in the .o file. Then, when the linker processes the .o files it includes the entire content even if there are no references to some of the functions within it.

It is possible that the linker has an option to exclude unreferenced code. You'll have to review the linker options to find out.

If you add the static attribute to the functions, I suspect that the compiler will omit them since it can then determine that there are no references. In fact, if you do that the compiler will probably issue a warning that the functions are unused.

If the functions must be public, the only option, as I see it, is to break down your application more finely and place most of the modules in a .a archive. Then the linker can pull from the archive only the modules that it needs for a particular build of your application.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

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

> I haven't. If I would do that I would waste time making a special
> file for every function ...

Curious, where's the time wasted for that?

Yes, there are linker options to remove unused functions. However, I've still
got the feeling that in 99 % of the scenarios, the existence of functions that
aren't needed at all is rather a strong indication of a chaotic design than
a feature that's worth having (at least outside of library code, and for
libraries, the one file per function approach has proven to work for a couple
of decades now).

These linker options have some merit in connection with C++ though, but that's
an entirely differen thing.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Needless to say, as ever, the USER MANUAL has a useful article about this:

http://www.nongnu.org/avr-libc/u...

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

dl8dtl wrote:
the existence of functions that
aren't needed at all is rather a strong indication of a chaotic design
We purchased and incorporated a large body of source code to support a particular wireless protocol. Since we only needed a small portion of the protocol, much of that source code was not needed but contributed to a flash shortage we had to deal with.

I agree with your observation, but based on experience, doubt the 99% estimate. Enhancing the linker's ability to remove dead code should be high on the todo list, especially with regard to memory-limited microcontrollers.

C: i = "told you so";

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

No need for a todo list, the feature is there. You just have to make use
of it.

I don't think a misconfigured protocol stack can be fixed by that though.
Usually, dispatching the protocol event is done based on message types at
run-time, so at link-time, everything is still referenced anyway.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Quote:
No need for a todo list, the feature is there.
Then hopefully someone will provide usage details for reSpawn and anyone else that is interested. I always assume that complex features can be improved to some extent, but as usual may be mistaken in this case.
Quote:
dispatching the protocol event is done based on messages
There were messages and indeed layers that simply would never see the light of day in our app. Sure, we could identify the biggies and #if them out, but this is a hassle when you consider that the source code will be continually rev'ed by the vendor.

C: i = "told you so";

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
CFLAGS += -ffunction-sections
LDFLAGS += -Wl,-gc-sections

Seems to work on some functions(my hex is 10% lighter :) ) but on wow() and wow2() it does not, only if I declare them static.

Nicu reSpawn.

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

Code:
CFLAGS += -ffunction-sections
LDFLAGS += -Wl,-gc-sections

These are the switches needed to remove (Garbage Collect) unused functions, by putting them in their own sections and telling the linker to garbage collect them if they are not referenced.

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

Quote:

CFLAGS += -ffunction-sections
LDFLAGS += -Wl,-gc-sections

yes, it works, but also removes used functions.
tryed to add 'used' attribute, but it don't help.

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

urriz77 wrote:
Quote:

CFLAGS += -ffunction-sections
LDFLAGS += -Wl,-gc-sections
yes, it works, but also removes used functions. tried to add 'used' attribute, but it don't help.
Huh? What do you mean "removes used functions"?

If you are using the optimization level -Os (and you should be using it!), the optimizer will "inline" some functions if it judges that they will be faster and smaller for that. Static functions are the usual candidates for this. The functions will seem to be removed, but are actually still there.

Is this what you mean?

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!