编译器如何将函数消除应用于不纯函数?

时间:2012-09-04 23:16:11

标签: function optimization language-agnostic compiler-construction compiler-optimization

通常在编写代码时,我发现自己多次使用来自特定函数调用的值。我意识到明显的优化是在变量中捕获这些重复使用的值。 这(伪代码):

function add1(foo){ foo + 1; }
...
do_something(foo(1));
do_something_else(foo(1));

变为:

function add1(foo){ foo + 1; }
...
bar = foo(1);
do_something(bar);
do_something_else(bar);

然而,根据我的经验,明确地这样做会使代码的可读性降低。如果我们选择的语言允许函数产生副作用,我认为编译器无法进行这种优化。

最近我调查了这个,如果我理解正确的话,这个优化是/可以用于功能必须纯粹的语言。这并不让我感到惊讶,但据说这也可以用于不纯的功能。通过几次快速Google搜索,我发现了以下代码段: GCC 4.7 Fortran improvement

  

执行前端优化时,-faggressive-function-elimination选项允许删除重复的函数调用,即使对于不纯的函数也是如此。

Compiler Optimization (Wikipedia)

  

例如,在某些语言中,不允许函数产生副作用。因此,如果程序使用相同的参数对同一函数进行多次调用,则编译器可以立即推断出函数的结果只需要计算一次。在允许函数具有副作用的语言中,可以采用另一种策略。优化器可以确定哪个函数没有副作用,并将此类优化限制为无副作用函数。只有在优化程序可以访问被调用函数时才能进行此优化。

根据我的理解,这意味着优化器可以确定函数何时是纯的,并且在函数执行时执行此优化。我这样说是因为如果一个函数在给定相同的输入时总是产生相同的输出,并且没有副作用,那么它将满足两个条件被认为是纯粹的。

这两个片段为我提出了两个问题。

  1. 如果函数不纯,编译器如何才能安全地进行优化? (如in -faggressive-function-elimination)
  2. 编译器如何确定函数是否纯粹? (如维基百科文章中提出的策略)
  3. 最后:

    • 这种优化是否可以应用于任何语言,或仅在满足某些条件时才会应用?
    • 即使对于非常简单的功能,这种优化是否也是值得的?
    • 从堆栈中存储和检索值会产生多少开销?

    如果这些是愚蠢或不合逻辑的问题,我道歉。它们只是我最近一直很好奇的一些东西。 :)

0 个答案:

没有答案