> From: Erik > Newsgroups: gmane.comp.gcc.help > Subject: Re: Optimisation puzzle > Date: Fri, 16 Mar 2007 12:53:16 +0100 [] > I tried with the following program: void q(const unsigned int); void > f() {for (unsigned int x = 0; x != 10; x++) q(77);} > > and built it with "gcc -std=c99 -Os -Wall -Wextra -Werror -S": > .L2: > subl $12, %esp > incl %ebx > pushl $77 > call q > addl $16, %esp > cmpl $10, %ebx > jne .L2 > > As you can see, "pushl $77" is still inside the loop even though q > promises to not change its argument. This must be a bug. Maybe this somehow linked to the fact, that parameter by value are always copied and there's no way for caller to know about what happened to that *copy*. E.g. "void q(const unsigned int b);" means b is read-only inside q, but any caller sets up b for q, i.e it create/change it. Anyways this can be optimized. And i think, gdb will be ok with such code. That isn't working program, you've tested, is it? I tried working one, but it was little bit hard to get non-unrolled loop. See even one more instruction, that seems to be useless, unless it somehow speeds-up register access (or any other CPU's magic). Of course things are completely different with q being static. AMD64 code: ..globl q .type q, @function q: _mtune=k8_ q: _mtune=nocona_ ..LFB2: .LFB2: mov %edi, %edi *NOTE* movsd a(%rip), %xmm1 movlpd a(%rip), %xmm1 mov %edi, %edi *NOTE* cvtsi2sdq %rdi, %xmm0 cvtsi2sdq %rdi, %xmm0 sqrtsd %xmm0, %xmm0 sqrtsd %xmm0, %xmm0 addsd %xmm0, %xmm1 addsd %xmm0, %xmm1 movsd %xmm1, a(%rip) movsd %xmm1, a(%rip) ret ret ..LFE2: .LFE2: .size q, .-q ..globl f .type f, @function f: ..LFB3: pushq %rbx ..LCFI0: movl %edi, %ebx ..L7: movl $77, %edi movl $77, %edi .L7_OPERFORMANCE: call q call q decl %ebx decl %ebx jne .L7 jne .L7_OPERFORMANCE popq %rbx ret ..LFE3: .size f, .-f Code is: #include <math.h> static double a; void q(const unsigned int b) { a += sqrt(b); } void f(int c) { do { q(77); } while (--c); } int main(int argc, char *argv[]) { f(argc); return 0; } Kind regards. _____