Options That Control Optimization

Asked by Malte Krebs

Currently I am using the gcc 4.7.3 compiling code for a Cortex-M4 device and I have a question regarding the options that control the optimization.

First I checked which flags are enabled/disabled when using the -Os option:
arm-none-eabi-gcc.exe -Q -Os --help=optimizers

The I did the same check for the -O2 option:
arm-none-eabi-gcc.exe -Q -O2 --help=optimizers

I figured out that there are only three differences, so I tried to use the -Os option and set all flags as they would be when using the -O2 option:
-Os -fno-inline-functions -foptimize-strlen -fschedule-insns

I was surprised that I did not get the same result as I would get with the -O2 option:
-Os -fno-inline-functions -foptimize-strlen -fschedule-insns
    text data bss
0x2c06 0x40 0x5dc

-O2
    text data bss
0x34fc 0x44 0x5dc

So, I guess a specific optimization level cannot be cloned with a set of -f options. Is that true? Is there any information available that tells me what exactly the optimizer is doing in the different optimizer levels?

I also looked into the documentation (gcc.pdf), but I haven't found the answer to my question (maybe I overlooked it).

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
Malte Krebs
Solved:
Last query:
Last reply:
Revision history for this message
chengbin (can-finner) said :
#1

Am I missing something? As I though -finline-small-functions is enabled at level -O2, which is conflict with "-fno-inline-functions" literally.

For what optimizations are enabled at each level optimization, please refer to gcc manual document, "3.10 Options That Control Optimization"

HTH.

Revision history for this message
Malte Krebs (mkrebs-k) said :
#2

When I call "arm-none-eabi-gcc.exe -Q -O2 --help=optimizers" I find the -fInline-functions disabled:

  -finline-functions [disabled]

So I disabled it with -fno-inline-functions when I compiled with -Os.

I think the section you refer to in the the gcc manual is not providing the answer to my question. And the information differs compared to what I get out of the gcc help, for example the document says:

‘-Os’ disables the following optimization flags:
-falign-functions -falign-jumps -falign-loops
-falign-labels -freorder-blocks -freorder-blocks-and-partition
-fprefetch-loop-arrays -ftree-vect-loop-version

But "arm-none-eabi-gcc.exe -Q -Os --help=optimizers" tells me the following (just a cut-out)
  -falign-functions [enabled]
  -falign-jumps [enabled]
  -falign-labels [enabled]
  -falign-loops [enabled]
  -freorder-blocks [enabled]
  -freorder-blocks-and-partition [disabled]
  -fprefetch-loop-arrays [enabled]
  -ftree-vect-loop-version [enabled]

What is correct? The documentation or the help of the gcc?

Revision history for this message
chengbin (can-finner) said :
#3

Moreover, it's not uncommon for gcc to make different code transformation for different optimization level (O2/Os), an optimization pass may generate different code even it is enabled for both O2 and Os.

Revision history for this message
chengbin (can-finner) said :
#4

Thanks for reporting.
Seems the documentation and code behavior do not match. I would consider this case a bug.

Revision history for this message
Malte Krebs (mkrebs-k) said :
#5

OK, but is it possible to clone an optimization level by setting the -f flags according to an optimization level?
Here is why I am asking this question: my code is not working with -Os, but it is working with -O2. Assembly I have checked so far seems to be OK. My plan was to set -Os and see which of the -f flags caused the trouble. But this didn't help figuring out the cause.

Revision history for this message
Malte Krebs (mkrebs-k) said :
#6

Can you tell me which information I can trust?
Is the documentation correct or the help of the gcc?

Revision history for this message
chengbin (can-finner) said :
#7

Basically I would trust the code, but won't be surprised if there is a bug in it either.

> OK, but is it possible to clone an optimization level by setting the -f flags according to an optimization level?
I am not sure, since GCC has lots of options and the control system of these options is complicated.

> Here is why I am asking this question: my code is not working with -Os, but it is working with -O2.
This should be a bug. Could you simplify the example? We can help on this if the code can be shared.

> Assembly I have checked so far seems to be OK. My plan was to set -Os and see which of the -f flags
> caused the trouble. But this didn't help figuring out the cause.
This would be far from trivial I think. Maybe you can substitute Os object file with O2 one by one to narrow down.

Revision history for this message
Malte Krebs (mkrebs-k) said :
#8

>> Here is why I am asking this question: my code is not working with -Os, but it is working with -O2.
> This should be a bug. Could you simplify the example? We can help on this if the code can be shared.
Before I can simplify the example or share code, I have to dig deeper into this issue to figure out which part of the software really causes this issue.

> This would be far from trivial I think. Maybe you can substitute Os object file with O2 one by one to narrow down.
Yes, that's what I am doing at the moment. I use the #pragma to prevent functions from being optimized with -Os. I narrowed it down to two modules. But the funny thing is that one of the modules does its job correctly, independent whether it is optimized with -O0 or -Os (there is a simple function that sets a certain bit in a register to deassert the reset from a specific peripheral of the micro and the debugger in both cases tells me that the bit is set after the function call). But the whole software only works when this module is not optimized...

Revision history for this message
chengbin (can-finner) said :
#9

Maybe there is something wrong with optimization on bit-field. There are already some threads about the strict-bit-field problem.

Looking forward to your progress. Thanks.

Revision history for this message
Malte Krebs (mkrebs-k) said :
#10

OK, I found the rootcause - the issue was not caused by the optimizer. It was a fault in the linker script which resulted in wrong alignment of the flash table used for initializing variables in RAM.
When I was using -O2 the alignment accidently was correct while it was wrong with -Os.
Thanks a lot for your support!

But I think the mismatch between compiler help and documentation still needs to be fixed.

Revision history for this message
chengbin (can-finner) said :
#11

Glad to know problem solved. I will follow up the documentation issue.
Thanks again.