【问题标题】:What is the difference between Early inliner and IPA inliner in GCC?GCC 中的 Early inliner 和 IPA inliner 有什么区别?
【发布时间】:2018-07-16 21:02:54
【问题描述】:

阅读 GCC 代码 cmets 和在线文档,似乎有两种类型的内联程序 - 早期内联程序和 IPA 内联程序。 例如,在 gcc/ipa-fnsummary.c

/* IPA内联优化分析时,初始化循环 优化器,以便我们可以生成适当的内联提示。

在优化和分析早期内联时,初始化节点 参数,以便我们可以生成正确的 BB 谓词。 */

这两种内联是什么?而这两者有什么区别呢?

【问题讨论】:

    标签: gcc compiler-optimization inlining


    【解决方案1】:

    简单地说:

    • 在编译单个文件时,早期的内联程序在单个源文件级别上运行。它将仅在编译的源文件及其包含的头文件(单个编译单元的范围)范围内内联函数。

    • 在整个程序优化期间,IPA 内联器在链接时间上运行。它在激活-flto 选项时发生,代表链接时间 优化。

    当指定-flto 时,gcc 将称为GIMPLE 树的中间程序表示嵌入到每个目标文件的专门部分中。稍后,链接时间优化器(GCC 的lto1 可执行文件)读取此信息,并执行不同的优化过程,包括 IPA 内联程序,以生成最终优化的可执行文件。

    两个内联的影响可以用一个简单的例子来说明:

    // foo.h
    void foo() {}
    
    // goo.h
    int goo();
    
    // goo.cpp
    #include "goo.h"
    int goo() { return 0x123; }
    
    // foo.cpp
    #include "foo.h"
    #include "goo.h"
    
    int main()
    {
        foo();
        return goo();
    }
    

    首先,通常-O3编译:

    g++ -O3 foo.cpp goo.cpp

    通过反汇编a.out (objdump a.out -d) 我们得到main的以下代码:

    00000000000004f0 <main>:
     4f0:   e9 0b 01 00 00          jmpq   600 <_Z3goov>
     4f5:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
     4fc:   00 00 00 
     4ff:   90                      nop
    

    foo() 的调用消失了——这是早期内联的工作。而goo()函数在编译foo.cpp的过程中对编译器是不可见的,所以无法对其进行优化。

    现在,用-flto 重复编译:

    g++ -O3 -flto foo.cpp goo.cpp

    我们会得到以下反汇编:

    00000000000004f0 <main>:
     4f0:   b8 23 01 00 00          mov    $0x123,%eax
     4f5:   c3                      retq   
     4f6:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
     4fd:   00 00 00 
    

    这一次,对 goo 的调用被内联并替换为它的结果 0x123 - 这是 IPA 内联的工作。

    【讨论】:

    • IPA 内联独立于 LTO,即使没有 LTO 也会发生。您可以通过 LTO 获得 more IPA 内联,因为编译器可以跨模块查看。但它仍然可以在没有 LTO 的情况下工作(仅在单个翻译单元内)。
    【解决方案2】:

    根据 ipa-inline.c 中的内部文档,早期内联是一个简单的本地内联传递,它仅基于本地属性在当前函数中内联被调用者。此通道的主要优势在于它能够消除大多数 C++ 代码中存在的抽象损失,并为更高级的过程间分析 (IPA) 准备代码。

    IPA 内联程序是基于在 IPA 期间收集的信息的更高级的内联程序。由于它有更多信息,它可以更好地估计哪些被调用者对内联最有利。它还将修剪调用图并删除所有调用站点都已内联的函数。

    更多信息请参考ipa-inline.c的内部文档

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 2011-08-16
      • 2017-07-16
      • 1970-01-01
      • 2010-10-20
      • 2010-09-15
      相关资源
      最近更新 更多