C/C++ compilers optimize single layer functions with constant parameters (known at compile time) only when using -Os, -O1 and -O2. They do not optimize all the layers. Only -O3 can do that. gcc is WinAVR 4.3.3 which does not support attribute "optimize".
void inner(double value)
{
//operations using value
//...
}
void outer(double value)
{
//few operations using value
//...
inner(value);
}
int main()
{
inner(1); //optimize
outer(1); //only optimize by using -O3
}
What are the possible solutions other than the followings?
Update:
//inner function
static inline void _delay_us(double __us) __attribute__((always_inline));
//outer function
void f(double);
inline f1(double);
static inline f2(double);
static f3(double);
f1 is optimized but give warning '_delay_us' is static but used in inline function 'f1' which is not static due to static function problem. Others are not optimized.
Solution:
static inline void outer(double) __attribute__((always_inline));
Inline is the key. My outer function is too large for inline. The attribute always_inline forces the function to be inline. This allows the compiler to optimize the function with less compilation cost than trying to figure out the optimization. -O3 is smart enough to do the optimization but not -Os. -Os may need some compiler options. (The keyword static is required because the inner function is also static inline.)
Somewhat similar to the macro option (3), but without the disadvantages of a macro, you can make specific functions inline
, which will typically result in the desired constant optimizations. Of course this only helps if you're calling the relevant functions from one place (or from a few places), otherwise code bloat becomes an issue.
Note that gcc has a provision for forcing specific inline functions to always be inlined (rather than leaving this to the compiler's discretion): __attribute__ ((always_inline))
. Other compilers will typically have a similar mechanism, although it may be a command line switch or a pragma.
In GCC at least, the -O
flags just turn on a whole load of other flags, see e.g. http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html. You could just enable the ones you're interested in, although that's generally discouraged.
Note that I'm not sure that the behaviour of e.g. GCC at -O2
and -O3
is necessarily any indicator of what a completely different compiler will do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With