2 ms·
Can you describe in more details what you mean? An inlined function with restrict parameters is of course inlined as if the variables are restricted. Indeed, a
by personZ 12y ago
Can you describe in more details what you mean? An inlined function with restrict parameters is of course inlined as if the variables are restricted. Indeed, a test of an inline of an inline of an inline was still optimized (or rather, not guarded) per the restrict.
- cwzwarich 12y agoConsider the simple loop void f(int *a, const int *b, unsigned size) { for (unsigned i = 0; i < size; ++i) { a[i] = b[i] * 2; } } This is the LLVM IR generated by `clang -Ofast -c -o - -emit-llvm -S`: https://gist.github.com/zwarich/21cf3a0b2387302ea48b https://gist.github.com/zwarich/21cf3a0b2387302ea48b Notice the `vector.memcheck` block, which is doing a dynamic aliasing check to decide whether to use the vectorized code. If I add `restrict`, e.g. void f(int *restrict a, const int *b, unsigned size) { for (unsigned i = 0; i < size; ++i) { a[i] = b[i] * 2; } } then that dynamic check goes away: https://gist.github.com/zwarich/48fd374becf5f891cb5a https://gist.github.com/zwarich/48fd374becf5f891cb5a However, if I put the vectorized loop in a function that gets inlined, e.g. static void f(int *restrict a, const int *b, unsigned size) { for (unsigned i = 0; i < size; ++i) { a[i] = b[i] * 2; } } void g(int *a, int *b, unsigned size) { f(a, b, size); } the dynamic aliasing check reappears: https://gist.github.com/zwarich/3e75f17de835dd9064ee https://gist.github.com/zwarich/3e75f17de835dd9064ee This is because LLVM's loop vectorizer runs after inlining and the standard optimization passes (which are run in a bottom-up traversal of the SCCs of the callgraph, interleaved with inlining). The `noalias` attribute on function parameters, which is what represents `restrict` in LLVM IR, disappears upon inlining. Many other compilers do something similar, although some like IBM's XLC can preserve `restrict` upon inlining.