I’m currently developing on an embedded ARM cpu (cortex M0+). I have very limited ROM, so I’ve been playing around with function attributes to try to pack things down a little bit extra. My thought was to do some manual hot and cold path annotating to help the optimizer. For example, I annotated interrupt handlers with [[gnu::hot]] and initialization code which only ever runs once with [[gnu::cold]].
This does not have the expected result. On -Os, [[gnu::hot]] never does anything, as far as I can tell, and [[gnu::cold]] almost universally increases the binary size.
On -O2, it’s a little bit better. Once again [[gnu::hot]] has no effect, but [[gnu::cold]] sometimes decreases function size and sometimes increases it. Overall, it’s basically a wash if I apply it across the whole codebase.
[[clang::minsize]] seems to either slightly reduce binary size (by like 4-8 bytes for a function), or massively increase it on both -Os and -O2.
Does anyone have any insight to what’s going on here? For reference, here are my compiler flags:
-fno-rtti
-fno-exceptions
-ffunction-sections
-fdata-sections
-fomit-frame-pointer
-flto=full
-Xclang -fexperimental-omit-vtable-rtti
-Xclang -fmerge-functions
And for linking:
-Wl,–-icf=safe
-Wl,–-as-needed
-Wl,–-gc-sections
-Wl,-O2
-Wl,--lto-O3