Reply
Posts: 4
Registered: ‎05-21-2017
Accepted Solution

GCC 4.93 increases the size in contrast to GCC 4.83, both with size optimized compiled.

I am still compiling my project with GCC 4.8.3 size optimized. Because the new GCC 4.93 with size optimized increases significant the size.

 

Size:

GCC 4.8.3 65444 Byte

GCC 4.9.3 69560

GCC 6.3.1 69060

 

6% more

 

Have anybody an idea which compiler switch can improve the size again? Or which statement I should not use in my code?

 

Best regards

Posts: 561
Registered: ‎09-18-2015

Re: GCC 4.93 increases the size in contrast to GCC 4.83, both with size optimized compiled.

Hi @JulianC,

 

I don't have a clue why there would be a difference. We just integrate new versions of GCC into Studio as they come along.

 

One possibility you should check is the build configuration for your project. There is a distinct difference between code size and performance in the Debug vs. Release configuration.

 

Also, you should check if your build configurations are using different versions of emlib, as there could be added code in newer versions responsible for some of the size increase.

 

John

Posts: 75
Registered: ‎09-03-2015

Re: GCC 4.93 increases the size in contrast to GCC 4.83, both with size optimized compiled.

Hi @JulianC

 

One thing I like to do to figure out exactly what is causing code size to grow is to use the .map file that is generated by GCC. By comparing the map file for different GCC compiler version you can see which functions are being added by the compiler and also what size the different functions are.

 

The two main flags when optimizing for size is the -Os flag and the -specs=nano.specs flag. The -Os flag will optimize for size and the -specs=nano.specs flag will link in the size optimized version of the newlib c runtime library called newlib-nano.

 

Posts: 4
Registered: ‎05-21-2017

Re: GCC 4.93 increases the size in contrast to GCC 4.83, both with size optimized compiled.

I have searched in view of your recommendation. From my view the most consumption caused by the library functions:

 

In

GCC 4.8

gmtime: size 0x24

gmtime_r: size 0x8

 

GCC4.9

gmtime: size 0x24

gmtime_r: size 0x124

 

The same happened with localtime. 

 

The function _tzset_unlocked is only in the GCC 4.9 map and needs 0x308 + 0xc bytes.

The same is with: 

.ARM.attributes
0x00000000000018b7 0x1b lib_a-strcmp.o)
.ARM.attributes
0x00000000000018d2 0x2d lib_a-strcpy.o)
.ARM.attributes
0x00000000000018ff 0x2d lib_a-strlen.o)
.ARM.attributes
0x000000000000192c 0x2d lib_a-strncmp.o)
.ARM.attributes
0x0000000000001959 0x2d lib_a-strtoul.o)
.ARM.attributes
0x0000000000001986 0x2d lib_a-ctype_.o)
.ARM.attributes
0x00000000000019b3 0x2d lib_a-environ.o)
.ARM.attributes
0x00000000000019e0 0x2d lib_a-envlock.o)
.ARM.attributes
0x0000000000001a0d 0x2d lib_a-nano-msizer.o)
.ARM.attributes
0x0000000000001a3a 0x2d lib_a-nano-svfscanf.o)
.ARM.attributes
0x0000000000001a67 0x2d lib_a-nano-vfscanf_i.o)
.ARM.attributes
0x0000000000001a94 0x2d lib_a-sccl.o)
.ARM.attributes
0x0000000000001ac1 0x2d lib_a-strtol.o)
.ARM.attributes
0x0000000000001aee 0x2d lib_a-ungetc.o)
.ARM.attributes
0x0000000000001b1b 0x2d lib_a-findfp.o)
.ARM.attributes
0x0000000000001b48 0x2d lib_a-memchr.o)

 

I compiled both in the same way:

gcc 4.9

arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb -std=c99 '-DEFM32LG840F128=1' -I"***" -Os -Wall -c -fmessage-length=0 -ffunction-sections -fdata-sections -MMD -MP -MF"emlib/em_usart.d" -MT"emlib/em_usart.o" -o "emlib/em_usart.o" "../emlib/em_usart.c"
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb -T "***.ld" -Xlinker --gc-sections -Xlinker -Map="***.map" --specs=nano.specs -o ***.axf "./CMSIS/EFM32LG/startup_gcc_efm32lg.o" "./CMSIS/EFM32LG/system_efm32lg.o" "***" -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group

---

gcc 4.8

arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb -std=c99 '-DEFM32LG840F128=1' -I"***" -Os -Wall -c -fmessage-length=0 -ffunction-sections -fdata-sections -MMD -MP -MF"emlib/em_usart.d" -MT"emlib/em_usart.o" -o "emlib/em_usart.o" "../emlib/em_usart.c"
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb -T "***.ld" -Xlinker --gc-sections -Xlinker -Map="***.map" --specs=nano.specs -o ***.axf "./CMSIS/EFM32LG/startup_gcc_efm32lg.o" "./CMSIS/EFM32LG/system_efm32lg.o" "***" -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group

 

For me it seems as -Os don't throws not needed functions away. 

 

More information is in the attachment.

 

 

 

 

 

Posts: 75
Registered: ‎09-03-2015

Re: GCC 4.93 increases the size in contrast to GCC 4.83, both with size optimized compiled.

It looks to me like some functions that you call in your application has changed implementation in the version of newlib-nano which is shipped with GCC 4.93. I see that the linker is bringing in symbols related to timezone so it looks like your application is using some library functions that rely on timezone configurations. This could be a call to time() or localtime() from the time.h header for instance.

 

If you want to keep code size down you can try to minimize the use of the time.h header. I have also seen cases where switching from time() to gmtime() reduced the code size. This was because time() need timezone functionality, while gmtime() does not.

 

Don't worry about the ".ARM.attributes" section, that does not end up in your binary it's debug information.

 

 

Posts: 4
Registered: ‎05-21-2017

Re: GCC 4.93 increases the size in contrast to GCC 4.83, both with size optimized compiled.

Hello @kjostera thank you! That is the reason! I replace all localtime() calls with gmtime() and the size shrinks, but not very much.

 

I also commit out the mktime() function and the size reduces by 9kB. 

Posts: 3,100
Registered: ‎02-07-2002

Re: GCC 4.93 increases the size in contrast to GCC 4.83, both with size optimized compiled.


JulianC wrote:

 

For me it seems as -Os don't throws not needed functions away.  


AFAIK it's the LTO linker option that can throw away unused functions.

Highlighted
Posts: 435
Registered: ‎07-13-2015

Re: GCC 4.93 increases the size in contrast to GCC 4.83, both with size optimized compiled.

@JulianCI've encountered a similar issue which might also be relevant to you. You can check the newlib code here and according to this thread building newlib-nano is just a configuration option when building newlib. Anyway, you can take a look at the code and figure out what the suspicious functions do.

 

In my case, the trouble was newlib's timezone handling code which involves environment variable checking and uses dynamic memory allocations. I personally don't want any of that on my MCU, and also don't want to use dynamic memory allocations.

 

Fortunately, you can use the --wrap linker option to switch that ugly function to your own implementation.

 

On the linker command line, you need:

 

 

--wrap=_tzset_unlocked

And then in your own code, you have to specify your own implementation:

 

 

 

    // This function is a reimplementation of a newlib function
    // which checks the "TZ" environment variable and unfortunately
    // uses dynamic memory allocation.
    // Fortunately, there are no environment variables at all in
    // this project, so this can be safely ignored.
    void __wrap__tzset_unlocked() {
        // Do nothing.
    }

In this case, here's what will happen:

 

  • The --wrap=_tzset_unlocked linker flag will make the linker use __wrap__tzset_unlocked instead of the original implementation.
  • If you have the -ffunction-sections compiler flag and the --gc-sections linker flag, the original implementation will be thrown out from your binary.

 

Just FYI, I encountered this problem when trying to disable heap usage entirely.

 

Posts: 4
Registered: ‎05-21-2017

Re: GCC 4.93 increases the size in contrast to GCC 4.83, both with size optimized compiled.

The way with the linker option --wrap is very good. I tested it with my code. 

 

If I have a little bit more time I will figure out what happened in the newlib code exactly. 

Posts: 435
Registered: ‎07-13-2015

Re: GCC 4.93 increases the size in contrast to GCC 4.83, both with size optimized compiled.

@JulianCI've got one additional tip for you with regards to code size: if you don't use C++ exceptions, add -fno-exceptions to your compiler command line, even if you just use plain C code. (Explanation: in order to be standards-compliant, the compiler has to generate code even in C functions, even if you don't use C++ at all.) Using -fno-exceptions reduced code size for me by approx 18k. (From 117k to 99k.)

 

Hope this helps,

Timur