9

如果链接时优化 (LTO) 与gccclang一起使用,是否可以跨 C 和 C++ 语言边界优化代码?

例如,可以将 C 函数内联到 C++ 调用程序中吗?

4

1 回答 1

12

是的!

链接时优化通常适用于“胖”目标文件中存在的中间表示(IR),它可以包含用于传统链接的机器代码和用于 LTO 链接的 IR。

在这个阶段,没有更多的高级语言结构,因此链接时间优化与语言无关。


海合会

GCC 的链接时间优化(LTO) 适用于 GIMPLE,它是 GCC 的中间表示之一。IR 始终与语言无关,因此任何链接时优化都适用于从任何语言生成的代码。

GCC 优化选项文档:

LTO 的另一个特点是可以对用不同语言编写的文件应用程序间优化:

gcc -c -flto foo.c
g++ -c -flto bar.cc
gfortran -c -flto baz.f90
g++ -o myprog -flto -O3 foo.o bar.o baz.o -lgfortran

请注意,最后一个链接是使用 g++ 完成的,以获取 C++ 运行时库,并-lgfortran添加以获取 Fortran 运行时库。通常,在 LTO 模式下混合语言时,您应该使用与在常规(非 LTO)编译中混合语言时相同的链接命令选项。


这是一个示例,可以向您展示这项技术的强大功能。我们将定义一个 C 函数并从 C++ 程序中调用它:

func.h

#ifndef FUNC_DOT_H
#define FUNC_DOT_H

#ifdef __cplusplus
extern "C" {
#endif

int func(int a, int b, int c);

#ifdef __cplusplus
}
#endif

#endif /* FUNC_DOT_H */

func.c

#include "func.h"

int func(int a, int b, int c)
{
    return 3*a + 2*b + c;
}

main.cpp

#include "func.h"

int main()
{
    int a = 1;
    int b = 2;
    int c = 3;

    return func(a, b, c);
}

编译

gcc -o func.o -c -Wall -Werror -flto -O2 func.c
g++ -o main.o -c -Wall -Werror -flto -O2 main.cpp
g++ -o testlto -flto -O2 main.o func.o

拆机( objdump -Mintel -d -R -C testlto)

Disassembly of section .text:

00000000004003d0 <main>:
  4003d0:   b8 0a 00 00 00          mov    eax,0xa   ; 1*3 + 2*2 + 3 = 10
  4003d5:   c3                      ret

你可以看到它不仅将我的 C 内联func()到我的 C++main()中,而且把整个事情变成了一个常量表达式!


铿锵 / LLVM

使用相同的语法,Clang 能够使用 LLVM IR 发出“胖”目标文件,可以在链接时进行优化。请参阅LLVM 链接时间优化

使用与上面相同的测试代码,clang 产生完全相同的结果:

00000000004004b0 <main>:
  4004b0:   b8 0a 00 00 00          mov    eax,0xa
  4004b5:   c3                      ret
于 2017-12-30T03:43:19.253 回答