The importance of the toolchain version (in embedded space) by Olivier on 17/11/2015 12:54

This article will compare the following toolchains:

To compare the generated binaries, we will use the simple Baremetal example from PolyMCU project.

Build instructions

export CROSS_COMPILE=<gcc-toolchain-path>/bin/arm-none-eabi-
cmake -DBOARD=AppNearMe/MicroNFCBoard -DAPPLICATION=Examples/Baremetal -DCMAKE_BUILD_TYPE=Release ../..
make
export CROSS_COMPILE=<gcc-toolchain-path>/bin/arm-none-eabi-
CC=clang-3.x cmake -DBOARD=AppNearMe/MicroNFCBoard -DAPPLICATION=Examples/Baremetal -DCMAKE_BUILD_TYPE=Release ../..
make

Analysis

LLVM also uses GCC toolchain linker ld and share the same linking command as GCC.

Here are the sizes in byte of the different sections and final binaries:

Build text data bss text+data+bss final binary
GCC 4.9 2014q4 - Debug 8548 184 92 8824 8732
GCC 4.9 2014q4 - Release 5084 176 92 5352 5260
GCC 4.9 2015q3 - Debug 8596 184 92 8872 8780
GCC 4.9 2015q3 - Release 5136 176 92 5404 5312
LLVM 3.6 + GCC 4.9 2015q3 - Debug 9272 184 96 9552 9456
LLVM 3.6 + GCC 4.9 2015q3 - Release 5532 176 96 5804 5708
LLVM 3.8 + GCC 4.9 2015q3 - Debug 8844 184 96 9124 9028
LLVM 3.8 + GCC 4.9 2015q3 - Release 5168 176 96 5440 5344

We can notice the size of the final binary for LLVM 3.8 release build (ie: 5344 Bytes) is not so far from the size of the final binary built by GCC 4.9 2015q3 (ie: 5312 Bytes).

LLVM 3.8 not far from GCC 4.9-2015q3

Let's compare the size of the largest symbols (with the command arm-none-eabi-nm -S --size-sort Baremetal_Example.elf)

GCC 4_9-2015q3 Release LLVM 3.8 + GCC 4_9-2015q3 Release
(...)
00000080 T Chip_SystemInit
00000080 t VCOM_bulk_out_hdlr
0000008c T _free_r
000000a0 T leds_init
000000a8 T ARM_USART_Send
000000b0 T _malloc_r
000000b0 T __smakebuf_r
000000b0 T __swbuf_r
000000c0 T g_pfnVectors
000000c0 T vcom_init
000000e8 T __swsetup_r
000000f8 T _puts_r
00000100 T usbd_rom_init
00000112 T __sflush_r
(...)
00000084 t VCOM_bulk_out_hdlr
00000088 T Chip_SystemInit
0000008c T _free_r
000000a8 T ARM_USART_Send
000000b0 T _malloc_r
000000b0 T __smakebuf_r
000000b0 T __swbuf_r
000000b0 T vcom_init
000000c0 T g_pfnVectors
000000d0 T leds_init
000000e8 T __swsetup_r
000000f0 T usbd_rom_init
000000f8 T _puts_r
00000112 T __sflush_r

We also noticed LLVM uses __aeabi_memclr*(), __aeabi_memset*() while GCC does not.

No comment yet

Login to comment Comment as anonymous