We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I am having a problem with the Keil compiler not performing an optimization that looks trivial. I am using Keil 4.50. The issue can be reproduced with the following simple code:
extern int g(int arg1); extern int extint1; int f( int arg1) { int a; int b; a = g(arg1); b = (int) &extint1 + a - a + 10 -5; return b; }
When compiled with maximum optimization (O2 or O3), I would expect the compiler to optimize away the ‘a-a’ in the computation of b, but it doesn’t. When compiled with –O3 the result is
; generated by ARM C/C++ Compiler, 4.1 [Build 791] ; commandline ArmCC [--list --debug -c --asm --interleave -ocompileroptimization.o --asm_dir=.\ --list_dir=.\ --depend=compileroptimization.d --cpu=Cortex-M3 --apcs=interwork -O3 -IC:\Keil\ARM\CMSIS\Include -IC:\Keil\ARM\INC\STMicroelectronics --omf_browse=compileroptimization.crf CompilerOptimization.c] THUMB AREA ||.text||, CODE, READONLY, ALIGN=2 f PROC ;;;3 ;;;4 int f( int arg1) 000000 b510 PUSH {r4,lr} ;;;5 { ;;;6 int a; ;;;7 int b; ;;;8 ;;;9 a = g(arg1); 000002 f7fffffe BL g ;;;10 b = (int) &extint1 + a - a + 10 -5; 000006 4902 LDR r1,|L1.16| 000008 4401 ADD r1,r1,r0 00000a 1a08 SUBS r0,r1,r0 00000c 1d40 ADDS r0,r0,#5 ;;;11 ;;;12 return b; ;;;13 } 00000e bd10 POP {r4,pc} ENDP |L1.16| DCD extint1
Note the ADD r1,r1,r0 immediately followed by the SUBS r0,r1,r0; not what I expect from an optimizer. Without the presence of extint1, the compiler optimizes correctly. The trivial answer is of course not to write code that does ‘a-a’, but that is not a realistic option in my project. I need to rely on the compiler to optimize this code.
Does anyone have an idea on why the compiler behaves like this and how I can let it optimize this correctly?
b = a - a + 10 -5; b += (int) &extint1;
If the compiler is coming up with the correct result, then the optimizer is correct.
Thanks, but changing the expression is in practice not going to work for me. The example is a simplification; in practice the expression has many terms like extint1 and a, and is generated by some complex preprocessor macro expressions. Changing that is my plan B, as it is not trivial. I was hoping for a solution that did not involve rewriting the C code.
The generated code is indeed correct, but to large, which is a problem on my memory constraint product.
... it would, probably, have more bugs.
An optimizer is a 'helper', not a 'master'
If you want the ultimate in optimization write in assembler.
I would assume an optimizer is " a work in progress", I can visualize release 1.0 doing some, 2.0 doing more, .....
Erik
You could switch to a different compiler. I hear IAR make good optimizing compilers, but they do have nasty compiler bugs once in a while.
The generated code is indeed correct, but to large, which is a problem on my memory constraint product is the doo-doo youi are in that deep? I'd say if you use more thn 80% of memory non-optimized, you set out with too little.
One nitpick regarding your post's subject line. Please be aware that the thing you want optimized is not, actually, an initializer expression. It's the right hand side of an assignment expression.
Correct.