This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: g++keeps unused objects with virtual functions


On Wed, Apr 8, 2015 at 10:02 AM, Stefan Ehrlich
<stefan.ehrlich@ehrlich.eu> 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:richard.guenther@gmail.com]
> Gesendet: Dienstag, 07. April 2015 18:42
> An: Stefan Ehrlich; gcc@gcc.gnu.org
> Betreff: Re: g++keeps unused objects with virtual functions
>
> On April 7, 2015 5:00:27 PM GMT+02:00, Stefan Ehrlich <stefan.ehrlich@ehrlich.eu> 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
>>
>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]