Do C and C++ optimizers typically know which functions have no side effects?

前端 未结 4 1226
隐瞒了意图╮
隐瞒了意图╮ 2020-12-13 06:08

Say for very common math functions, such as sin, cos, etc... does the compiler realise they have no side effects and have the ability to move them to outer loops? For examp

4条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-13 06:45

    What is needed to permit hoisting this subexpression outside the loop is not purity, but idempotence.

    Idempotence means that a function will have the same side-effects and result if it is called once as if it is called many times with the same arguments. Therefore, the compiler can put the function call outside the loop, protected only by a conditional (would the loop iterate at least once?). The actual code after the hoisting optimization then would be:

    double YSinX(double x,int y)
    {
       double total = 0.0;
       int i = 0;
       if (i < y) {
           double sinx = sin(x);  // <- this goes between the loop-initialization
                                  // first test of the condition expression
                                  // and the loop body
           do {
              total += sinx;
              i++;
           } while (i < y);
       }
       return total;
    }
    

    The distinction between __attribute__(pure) and idempotent is important because, as adl notes in his comment, these functions do have a side-effect of setting errno.

    Be careful, though, because idempotence only applies to repeated calls with no intervening instructions. The compiler will have to perform dataflow analysis to prove that the function and the intervening code don't interact (for example, the intervening code uses only locals whose addresses are never taken), before it can take advantage of idempotence. This isn't necessary when the function is known to be pure. But purity is a much stronger condition that doesn't apply to very many functions.

提交回复
热议问题