I tried out WinAVR 20080411 and found that code size grew for a my current project by about 10% (was about 10K). After investigating I found the major reason was inlining.
It seems very strange to me that the compiler would inline so agressively with -Os. I would prefer the compiler leave inlining decisions to me. I believe I found the way to do that with this optimization switch:
Code size shrunk right back down to about the same size as WinAVR 20071221 - actually slightly smaller, and nothing was inlined without my say so.
However, the code could be smaller still. The compiler is unrolling small loops (3 iterations), bloating the code. For example:
for (i = 3; i > 0; i--) bTmp = SpiByte(0xFF); // eat byte from SPI
This generates a nice tight loop of 6 instruction words in 20071221, and inlines to 9 instruction words with 20080411.
I spent a while studying the GCC manual for switches to turn off this unrolling without success. The most likely candidate would seem to be -fno-unroll-loops, but it didn't help.
Does anyone know a way to prevent unrolling loops? It seems weird the compiler wants to do this even though I've told it I want the smallest possible code.