9 ms·
This already exists. gcc has optimization pragmas and function attributes that allow optimization to be set on a per-function level. However, they don't really
by Hello71 4y ago
This already exists. gcc has optimization pragmas and function attributes that allow optimization to be set on a per-function level. However, they don't really work as expected, mainly because inlining exists. Example:
int foo(void) { return 42; }
int bar(void) { return foo() + foo(); }
If the whole file is compiled as -O0, foo and bar must be compiled as-is. If the whole file is compiled as -O2, bar will be optimized to "return 84;". But what if foo is compiled as -O0 and bar is compiled as -O2? Can bar still be optimized to "return 84;"? What about "return 42+42;"? Can it do "int x = foo(); return x+x;"? What about "int x = foo(); if (x == 42) return 84; else return x+x;"? All of these are permitted in -O2 if gcc thinks it's a good idea, but in our "mixed mode" the semantics are unclear. It might be theoretically possible to come up with a consistent definition; it might start with "functions specified as -O0 cannot be inlined or have other functions inlined into them", but there are still more things to consider, like the behavior of global memory, thread-local storage, floating-point environment, and so on (what if one or more functions is static inline or __attribute__((always_inline))?).
The real solution with current gcc is to simply compile different files ("translation units") with different optimization flags if you want. This has always been supported. Unfortunately, it comes with a potentially significant performance penalty; the whole point of LTO is to avoid this performance penalty, but this once again returns the issue of the semantics of mixing functions with different optimization levels.