2

I am working in a platform with limited flash memory, and I recently hit the wall and tried to reduce the ReadOnly area. and strings used in printf seemed to be a good place to start. while doing this I came across the following code snippet. and I happened to find that the following reuses "failed" for multiple prints ( looking at the executable). where as normal printf doesn't do this optimization even when the same string parts are used. is there any optimization options in GCC (GCC 4.8.4) which can lead to less storage space for debug strings?

#define printf_failed(str) printf("%s failed", str); // reuses failed
bare_metal
  • 1,134
  • 9
  • 20
  • A simpler, and perhaps even faster variation might be to say: `fputs(str, stdout); fputs(kFailed, stdout);`... – Kerrek SB May 06 '16 at 15:09
  • Are the macro invocations in separate compilation units? Can you compile with link time optimization enabled? – ninjalj May 06 '16 at 18:13
  • I tried -flto flag,, still the executable has the same strings present – bare_metal May 06 '16 at 21:59
  • @bare_metal: that's strange. Did you use it both when compiling and when linking? – ninjalj May 06 '16 at 22:02
  • To test it i tried it in a single .c file , gcc -Os -flto test_c.c , and i looked at the a.out, i can find the same strings. by the way LTO is expected to compact or share part of strings ( not full strings) ? – bare_metal May 06 '16 at 22:08
  • LTO allows the optimizer to see the whole program at once. I did a test with two files invoking `printf_failed` once from each file on Debian Wheezy (GCC 4.7.2) x86_64, and without LTO `"%s failed"` appeared twice in `.rodata`, while with LTO it only appeared once. – ninjalj May 06 '16 at 22:15
  • so LTO allows to share string across translation units, that is a good thing. it can be helpful for me in some situations. but what i am more interested is the part of the string as the debug logs mostly share string such as "success", "failure", "error" etc. I recently noticed a 5K increase in rom size when the macro in question replaced with equivalent full strings. by the way if you post the LTO option as an answer it might be useful for someone. – bare_metal May 06 '16 at 22:21

1 Answers1

2

You can use the option -fmerge-constants in gcc. This option is option enabled with -O, -O2, -O3 and -Os.

blatinox
  • 833
  • 6
  • 18
  • This app has already -Os enabled. but i tried -fmerge-constants in a PC environment. but don't see the recurring "part of string" being merged ( looking at a.out) – bare_metal May 06 '16 at 15:25
  • http://stackoverflow.com/questions/26433563/same-strings-in-array-have-same-memory-address/26433626#26433626 , -fmerge-constants only merges identical full length strings and not "part of strings". anyway thanks. – bare_metal May 06 '16 at 15:37
  • Yes, because of the '\0', you can not merge part of strings. But your "%s failed" is not a part of string, each time your macro is expanded, it should be a mergeable string. – blatinox May 08 '16 at 10:32