This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Optimization attributes const vs. pure


Johannes Bauer <dfnsonfsduifb@gmx.de> writes:

> I have a question about the optimizations conducted by gcc when
> functions are declared pure or const. I'm using gcc 4.6.2 on Gentoo
> Linux x86-64. Here's a minimal example:
>
> ----8<----8<---- int.c ----8<----8<----8<
> #include <string.h>
> #include "int.h"
> int intcmp(const struct mi *a, const struct mi *b) {
> 	return memcmp(a, b, sizeof(struct mi));
> }
>
>
>
> ----8<----8<---- int.h ----8<----8<----8<
> struct mi {
> 	int foo;
> 	unsigned char x[16];
> };
>
> int intcmp(const struct mi *a, const struct mi *b) __attribute__ ((pure));
>
>
> ----8<----8<---- main.c ----8<----8<----8<
> #include <stdio.h>
> #include <string.h>
> #include "int.h"
> int main() {
> 	struct mi a, b;
> 	memset(&a, 0, sizeof(struct mi));
> 	memset(&b, 0, sizeof(struct mi));
> 	for (unsigned int i = 0; i < 100; i++) {
> 		fprintf(stderr, "%d\n", intcmp(&a, &b));
> 	}
> 	return 0;
> }
>
>
> I'm compiling using
>
> $ gcc -O3 -march=nocona -std=c99 main.c int.c -o out
>
> This is the observation I'm making: The generated assembly does not
> differ from a function declared as "pure" from a function not declared
> with any special attribute.
>
> As soon as I declare the function (wrongly!) as const, the optimization
> that I'd expect with "pure" occurs (i.e. intcmp() is only called once).
>
> Now from my understanding I cannot use the attribute "const" for
> intcmp() since intcmp() dereferences the pointers that it's passed (and
> thus accesses global memory in a reading fashion).
>
> So "pure" would be the perfect fit: Global memory is read but not
> modified (which is also asserted by passing the arguments as "const").
> Why is gcc then not doing the optimization that I'd want it to perform?

GCC does not know that the function fprintf does not modify global
memory.  In fact, the function does modify global memory, in that it
will change stderr structure.  For example, for all GCC knows, the
function intcmp could call ferror(stderr)--that would be permitted by a
pure function.  And that means that the call can not be hoisted out of
the loop.

Ian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]