Performance 哪些编译器可以内联间接函数调用?

Performance 哪些编译器可以内联间接函数调用?,performance,language-agnostic,delegates,compiler-construction,compiler-optimization,Performance,Language Agnostic,Delegates,Compiler Construction,Compiler Optimization,LLVM的LDC D编译器在某些情况下可以内联间接函数调用,前提是它可以证明目标是静态已知的。下面是一个玩具示例(在D中),说明可能发生的情况: void main() { uint num; void incNum() { num++; } auto myDelegate = &incNum; myDelegate(); } 在这种情况下,尽管myDelegate()调用名义上是一个间接调用,但对于人类读者和LLVM/LDC

LLVM的LDC D编译器在某些情况下可以内联间接函数调用,前提是它可以证明目标是静态已知的。下面是一个玩具示例(在D中),说明可能发生的情况:

void main() {
    uint num;

    void incNum() {
        num++;
    }

    auto myDelegate = &incNum;
    myDelegate();
}
在这种情况下,尽管
myDelegate()
调用名义上是一个间接调用,但对于人类读者和LLVM/LDC的流分析来说,目标是显而易见的,因此它是内联的


在现代编译器中,将间接函数调用内联到静态已知目标的能力有多广泛?LLVM是唯一一个能够做到这一点的提前编译器吗?JIT编译器是否更常见?

< P>如果大多数C++编译器都进行了这种优化,至少有些变化,我不会感到惊讶。实际上,这是非常特定于语言和编译器的

我不能说是D语言,但对于C/C++,由于指针算法的原因,上面的这种优化可能很难实现。e、 如果是这样的话,你能优化代码吗

++myDelegate;
myDelegate();
它在很大程度上取决于
myDelegate
的类型。上面的内容可以是有效的C/C++,但内联myDelegate()可能不是编译器可以保证的

其他语言(如Java、C#等)没有指针算法,因此可以做出更多假设。例如,sunjvm可以将间接的多态调用转换为直接调用,这非常酷,IMHO。例如:

   public class A2 {
      private final B2 b;
      public A2(B2 b) {
        this.b = b;
      }
      public void run() {
        b.f();
      }
    }

    public interface B2 {
      public void f();
    }

    public class C2 implements B2 {
      public void f() {
      }
    }
a2a2=newa2(newc2())
实际上可以进行优化,Sun JVM可以实现这一点


我从这个例子中得到了这个例子,我建议阅读一下关于WRT java的东西。

< P>如果大多数C++编译器都做了这种优化,至少有些变化,我不会感到惊讶。实际上,这是非常特定于语言和编译器的

我不能说是D语言,但对于C/C++,由于指针算法的原因,上面的这种优化可能很难实现。e、 如果是这样的话,你能优化代码吗

++myDelegate;
myDelegate();
它在很大程度上取决于
myDelegate
的类型。上面的内容可以是有效的C/C++,但内联myDelegate()可能不是编译器可以保证的

其他语言(如Java、C#等)没有指针算法,因此可以做出更多假设。例如,sunjvm可以将间接的多态调用转换为直接调用,这非常酷,IMHO。例如:

   public class A2 {
      private final B2 b;
      public A2(B2 b) {
        this.b = b;
      }
      public void run() {
        b.f();
      }
    }

    public interface B2 {
      public void f();
    }

    public class C2 implements B2 {
      public void f() {
      }
    }
a2a2=newa2(newc2())
实际上可以进行优化,Sun JVM可以实现这一点


我从中得到了这个示例,我建议阅读该示例以了解WRT Java的这类内容。

我假设大多数优化良好的编译器都可以做类似的事情(考虑到它们无论如何都可以做各种流分析)


Jit编译器有时甚至可以进一步内联间接调用,因为它们无法证明目标是静态已知的(或者根本不知道的)。在这种情况下,如果目标是函数调用之前的预期目标,则会插入一个测试,如果不是,则只使用间接调用(并根据每条路径的使用频率重新JIT)。IIRC.Net Jit可以做到这一点,我认为java也可以做到这一点。

我认为大多数优化良好的编译器都可以做到这一点(考虑到它们无论如何都可以进行各种流分析)

Jit编译器有时甚至可以进一步内联间接调用,因为它们无法证明目标是静态已知的(或者根本不知道的)。在这种情况下,如果目标是函数调用之前的预期目标,则会插入一个测试,如果不是,则只使用间接调用(并根据每条路径的使用频率重新JIT)。IIRC.NETJIT就是这样做的,我假设java也是这样做的