mspgcc and armgcc difference in behaviour - Page 1
Forum section: electronics / general

author: jmrubillon
author_rank: Newbie
timestamp: December 15, 2017, 01:29:40 pm
content: Hi folks,I'm trying to figure out the reason for a difference in behaviour between armgcc and mspgcc.In an existing codebase (berkley-openwsn) there are a number of variables defined in a header file in the style:static const uint8_t var[] ="astring";This header file is included in a lot of C files....I modified the code toIn the .hextern const uint8_t var[];in one .cconst uint8_t var[] = "astring"Not modifying any other files I get for armgcc a reduction in overall image size of 1488 bytes while with mspgcc the image size increases by 32 bytes.I'm rather confused by this rather dramatic difference.Any ideas?

author: coppice
author_rank: Super Contributor
timestamp: December 15, 2017, 01:45:26 pm
content: It sounds like the linking for ARM did not eliminate common constant strings, and the linking for MSP430 did. So, after your change, the ARM build size was reduced by one less than the number of times "astring" occurred, but the linker had already made this reduction for the MSP430 case. However, less optimisation is possible with your new code, since the full scope of "var" is not known during compilation. That probably incurs the extra 32 bytes you see in the MSP430 build.

author: RoGeorge
author_rank: Super Contributor
timestamp: December 15, 2017, 01:46:51 pm
content: Why did you give-up on the "static"?Without static, the variable will be created and initialized at each call, with "static", it will be created and initialized only once just before running "main()".For the code size, optimization switches can behave very different from one platform to another.

author: jmrubillon
author_rank: Newbie
timestamp: December 15, 2017, 01:58:13 pm
content: Quote from: coppice on December 15, 2017, 01:45:26 pmNot sure I get the full scope of "var" being a hinderence to optimisation. Could you explain this one to me?

author: andersm
author_rank: Super Contributor
timestamp: December 15, 2017, 02:06:13 pm
content: For example:Code:static const char *str = "string";...size_t len = strlen(str);In the above case, the compiler can eliminate the call to strlen and emit "size_t len = 6;" If the string is not in scope, the compiler can't perform this optimization (at least without some kind of whole-program optimizations).

author: coppice
author_rank: Super Contributor
timestamp: December 15, 2017, 02:13:27 pm
content: Quote from: jmrubillon on December 15, 2017, 01:58:13 pmAn example: compare using "var" in both cases. In the original case 'a' can be used without even referencing the array. In the modified case only the compilation unit in which "astring" is defined can use 'a' directly. The other units need to reference the actual array, occupying more code space.

author: SiliconWizard
author_rank: Super Contributor
timestamp: December 15, 2017, 03:27:13 pm
content: Quote from: coppice on December 15, 2017, 01:45:26 pmI would second that.Have you enabled any optimizations with armgcc?GCC's option '-fmerge-constants' is enabled starting with the first optimization level (-O1).I'd suggest successively trying -O1, -O2, -O3 and -Os, and comparing the resulting code size.

author: bson
author_rank: Unknown
timestamp: December 23, 2017, 05:14:53 am
content: A wild guess is it's due to the ARM toolchain using ELF and MSP430 using DWARF. ELF has much more comprehensive symbol, data and section attributes so the linker can be smarter.

author: mikerj
author_rank: Super Contributor
timestamp: December 23, 2017, 03:45:11 pm
content: Quote from: RoGeorge on December 15, 2017, 01:46:51 pmIf he made it static that it would not be visible to other modules, defeating the purpose of the change.