开发者

What compilers can detect pure mathematical functions and optimize them (without telling you so)?

开发者 https://www.devze.com 2023-01-09 15:35 出处:网络
I have seen that GCC is not able to detect pure mathematical functions and it needs you to provide the attribute \"const\" to indicate that.

I have seen that GCC is not able to detect pure mathematical functions and it needs you to provide the attribute "const" to indicate that.

What compilers can detect pure mathematical functions and optimize them (without tel开发者_开发知识库ling you so)?


To do so is inherently risky in languages that have pointers and lack global compilation & analysis. So, if a an operation is declared non-const, the compiler must assume it could have side-effects.

Example:

//getx.cpp
int GetX(int input)
{
   int* pData = (int*) input;
   *pData = 50;
   return 0;
}
// gety.cpp
int GetY(int input)
{
   return GetX(input + 4);
}
// main.cpp
int main()
{
   int arg[] { 0, 4 };
   return GetY((int)arg);
}

The compiler while compiling GetY can't tell that GetX treats its argument as a pointer and dereferences and modifies data in a non-functional, side-effect-prone manner. That information is only available during linking so you'd have to re-invent the concept of linking to include a lot of code generation and analysis to support such a feature.


It's not really (afaik) the compiler that does this, but when writing C# in Visual Studio when using the plugin ReSharper, you can get compile time hints that indicate that it is possible to declare something as const. On the other hand, that doesn't go under the category "without telling you so", so it might not be what you're looking for...


It seems that gcc now does: doing "gcc -O2 -S" on the following code, and reading the assembly, the call to foo() from within test() is identified as pure and moved outside of the loop:

#include <stdio.h>

double __attribute__((noinline)) foo(double x)
{
    x = x + 1;
    x = x * x;
    if (x > 20)
        x -= 1;
    x -= x * x;

    return x;
}

void test(int iters, double x)
{
    int i;
    for (i = 0; i < iters; ++i) {
        printf("%g\n", foo(x));
    }
}

This is Fedora 22, gcc 5.1.1, x86_64. I haven't tried, but with -flto, I would expect this to work across compilation units.

Also, it is worth noting that today gcc has the command line options -Wsuggest-attribute=pure and -Wsuggest-attribute=const.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号