On Wed, Apr 8, 2015 at 10:02 AM, Stefan Ehrlich
<[email protected]> wrote:
> Dear Richard, Zan,
>
> There are no target specifics present. The program will be flashed to the µC
> via a programmer and that's it.
> Therefore I want to have the output hex file as small as possible.
>
> When I play around with my demo program and the keyword virtual, I can
> clearly see that the keywork virtual is generating the additional memory
> usage (by the way it's strange that RAM is used)
>
> Following program will generate 160 bytes of flash and 8 bytes of RAM
> class CObject
> {
> public: virtual void virtFunction() { }
> };
>
> CObject NotUsedObject;
>
> int main()
> {
> return 0;
> }
Ok. So when trying on x86_64 I see that somehow
NotUsedObject/4 (CObject NotUsedObject) @0x7f70d41fe580
Type: variable definition analyzed
Visibility: public
References:
Referring: _Z41__static_initialization_and_destruction_0ii/9 (addr)
Availability: not-ready
Varpool flags:
_Z41__static_initialization_and_destruction_0ii/9 (void
__static_initialization_and_destruction_0(int, int)) @0x7f70d4206000
Type: function definition analyzed
Visibility: artificial
Aux: @0x1815c60 References: NotUsedObject/4 (addr)
Referring:
First run: 0
Function flags: body optimize_size
Called by: _GLOBAL__sub_I_NotUsedObject/10 (1.00 per call)
Calls: _ZN7CObjectC1Ev/3 (1.00 per call)
_GLOBAL__sub_I_NotUsedObject/10 ((static initializers for )) @0x7f70d4206188
Type: function definition analyzed
Visibility: artificial constructor
References:
Referring:
First run: 0
Function flags: body static_constructor (priority:65535) optimize_size
Called by:
Calls: _Z41__static_initialization_and_destruction_0ii/9 (1.00 per call)
which shows how the global objects initialization keeps things live.
Early optimization turns it into
(static initializers for t.C) ()
{
<bb 2>:
NotUsedObject._vptr.CObject = &MEM[(void *)&_ZTV7CObject + 16B];
return;
}
but we don't have any pass removing stores to globals never read. IPA
reference computes this
in some way but doesn't get to export this in a reasonable way - its
transform stage could DSE
those though.
Richard.
> By removing the virtual keyword, the linker is able to find out it is no
> longer needed and will be removed
> class CObject
> {
> public: /*virtual*/ void virtFunction() { }
> };
>
> CObject NotUsedObject;
>
> int main()
> {
> return 0;
> }
>
> --> 66 bytes of flash and 0 bytes of RAM
>
> I added the complete make file steps here:
> avr-g++.exe -c -Os -Wall -fdata-sections -ffunction-sections
> -fvisibility=hidden -fvisibility-inlines-hidden -fno-rtti -flto
> -fwhole-program -fuse-linker-plugin -mmcu=atmega8 -DF_CPU=16000000L
> -DABUILD_BATCH=1 -DARDUINO=158 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR
> -fno-exceptions -D__PLATFORM__=Atmel_AVR_ATmega8_gcc
> -D__Atmel_AVR_ATmega8_gcc -D__RELEASE__=rel_1_3_2 -I. ./main.cpp -o
> obj/./main.obj
> avr-gcc.exe -Wall -Os -Wl,-static -flto -fwhole-program -fuse-linker-plugin
> -Wl,--strip-all -Wl,-s -Wl,--gc-sections -mmcu=atmega8
> -Wl,-Map=out/Virtual_Atmega8.map,--cref -o out/Virtual_Atmega8.elf
> obj/./main.obj -lm
> avr-strip.exe -s -R .comment -R .gnu.version --strip-unneeded
> out/Virtual_Atmega8.elf
> avr-objcopy.exe -O srec -R .eeprom out/Virtual_Atmega8.elf
> out/Virtual_Atmega8.hex
> avr-objcopy.exe -O ihex -R .flash out/Virtual_Atmega8.elf
> out/Virtual_Atmega8.hex
> avr-size_atmel.exe -C --mcu=atmega8 out/Virtual_Atmega8.elf
> AVR Memory Usage
> ----------------
> Device: atmega8
>
> Program: 66 bytes (0.8% Full)
> (.text + .data + .bootloader)
>
> Data: 0 bytes (0.0% Full)
> (.data + .bss + .noinit)
>
>
> I added the -fwhole-program flag (as mentioned by Zan Lynx) but without any
> effect.
> Is here something missing or too much?
>
> Lg
>
> Stefan
>
>
> -----Ursprüngliche Nachricht-----
> Von: Richard Biener [mailto:[email protected]]
> Gesendet: Dienstag, 07. April 2015 18:42
> An: Stefan Ehrlich; [email protected]
> Betreff: Re: g++keeps unused objects with virtual functions
>
> On April 7, 2015 5:00:27 PM GMT+02:00, Stefan Ehrlich
> <[email protected]> wrote:
>>Hello GCC developer team,
>>I hope I am right here to address my problem with memory usage and g++:
>>
>>I am writing C++ software for several very small embedded systems (8k
>>and smaller) and a feature with the virtual tables and the linker does
>>not make my life easy :-) I have a lot of objects with virtual
>>functions, where not all of them are used in each application, but they
>>remain existing in the source code.
>>Until now I could not find a way to get rid of them in the output
>>elf/hex file automatically (they are not removed by the linker).
>>
>>For better understanding an example:
>>
>>The program:
>>int main()
>>{
>> for(;;)
>> {
>> // Nothing to do
>> }
>> // unreachable code
>> //return 0;
>>}
>>
>>uses 62 bytes of flash and 0 bytes of RAM on an atmega8 µC (compiled
>>with gcc 4.9.2)
>>
>>When I add a not used object with virtual functions (in the below
>>listed example named as Derived0):
>>
>>class CBase
>>{
>>public:
>> virtual void virtFunction() = 0;
>>};
>>
>>class CDerived : public CBase
>>{
>>public:
>> virtual void virtFunction() { }
>>};
>>
>>CDerived Derived0;
>>
>>int main()
>>{
>> for(;;)
>> {
>> // Nothing to do
>> }
>> // unreachable code
>> //return 0;
>>}
>>
>>the memory usage jumps up to 156 bytes flash and 8 bytes RAM usage
>>(same compiler 4.9.2)
>>
>>compiler and linker options are:
>>avr-g++.exe -c -Os -Wall -fdata-sections -ffunction-sections
>>-fvisibility=hidden -fvisibility-inlines-hidden -fno-rtti -flto
>>-fuse-linker-plugin -mmcu=atmega8 ...
>>avr-gcc.exe -Wall -Os -Wl,-static -Wl,-flto -fuse-linker-plugin
>>-Wl,--strip-all -Wl,-s -Wl,--gc-sections -mmcu=atmega8 ...
>>
>>The more not used objects I use the worse the problem gets.
>>
>>Is there any possibility to remove unused virtual functions or at least
>>the objects, which are not used? I have not find any solution so far.
>>If not, is there a plan to add this feature to the linker?
>
> I think it should already work with LTO. Maybe there are some target
> specifics which make the vtables referenced?
>
> Richard.
>
>>greetings from Austria
>>
>>Stefan
>>
>
>