Hacker News new | past | comments | ask | show | jobs | submit login

No, there is more to it than that. It has to perform an aliasing analysis to prove that nothing that s points to changes. Consider this code:

    unsigned sum(const unsigned char *s, char *t) {
        unsigned result = 0;
        for (size_t i=0; i < strlen(s); i++) {
            result += s[i];
            *t = 'x';
        }
        return result;
    }
gcc can't hoist strlen() in this case, because *t = 'x' could potentially overwrite the null termination of s.



Note that C99 has added "restrict" for such cases, which essentially promises that the restricted pointer (and any pointers derived from it) is the only pointer to that chunk of memory.


Can GCC handle more complicated loops? For example what if I go several functions deep in in my loop with s? What if I call a function in a shared object? Does gcc do this analysis for all cases where a function is marked pure or is strlen a specific case?


The compiler can't see inside functions in the general case (because they're opaque binary blobs in a library that hasn't been linked yet), so no. It's limited to optimizing stuff it can "see", which broadly means the current function and anything inlinable into it.

But yes, if all your functions are marked inline and visible to the compiler, there's no theoretical limit to GCC's ability to hoist constants out of the innermost parts of the loop. In practice, there are surely some performance limits to how much inlining will be expanded.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: