对于gcc或clang,LTO可以通过C和C ++方法进行优化 [英] Can LTO for gcc or clang optimize across C and C++ methods

查看:608
本文介绍了对于gcc或clang,LTO可以通过C和C ++方法进行优化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果链接时间优化(LTO)与 gcc clang ,是否有可能在C和C ++语言边界上优化代码?



例如,一个C函数可以内联到一个C ++调用者中吗?

解决方案

<强大>是!



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



在这个阶段,没有更多的高级语言结构,所以链接时间优化与语言无关。 / p>




GCC



GCC的链接时优化 (LTO)在GCC的中间表示之一GIMPLE上工作。 IR总是与语言无关,所以任何链接时间优化都可以跨越任何语言生成的代码。




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 ++运行时库和<$ c添加$ c> -lgfortran 以获取Fortran运行时库。通常,在LTO模式下混合语言时,应该使用与在常规(非LTO)编译中混合语言时相同的链接命令选项。







以下示例显示了该技术的强大程度。我们将定义一个C函数,并从C ++程序中调用它:

func.h

  #ifndef FUNC_DOT_H 
#define FUNC_DOT_H

#ifdef __cplusplus
externC{
#endif

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

#ifdef __cplusplus
}
#endif

#endif / * FUNC_DOT_H * /

func.c

  #includefunc.h

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

main.cpp
$ b $ #includefunc.h

int main()

{
int a = 1;
int b = 2;
int c = 3;

返回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

反汇编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()中,而且它将整个事物到一个常量表达式!

$ hr
$ b

Clang / LLVM



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



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

  00000000004004b0< main> ;: 
4004b0:b8 0a 00 00 00 mov eax,0xa
4004b5:c3 ret


If link-time optimization (LTO) is being used with gcc or clang, is it possible that code can be optimized across the C and C++ language boundary?

For example, can a C function be inlined into a C++ caller?

解决方案

Yes!

Link-time optimization typically works on intermediate representation (IR) present in "fat" object files, which can contain both machine code for traditional linking, and IR for LTO linking.

At this stage, there are no more high-level language constructs, so link-time-optimization is language-agnostic.


GCC

GCC's link-time optimization (LTO) works on GIMPLE, one of GCC's intermediate representations. The IR is always language-agnostic, so any link-time optimizations will work across code generated from any language.

From the GCC Optimization Options documentation:

Another feature of LTO is that it is possible to apply interprocedural optimizations on files written in different languages:

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

Notice that the final link is done with g++ to get the C++ runtime libraries and -lgfortran is added to get the Fortran runtime libraries. In general, when mixing languages in LTO mode, you should use the same link command options as when mixing languages in a regular (non-LTO) compilation.


Here's an example to show you just how powerful this technology is. We'll define a C function and call it from a C++ program:

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);
}

Compile

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

Disassemble (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

You can see that it not only inlined my C func() into my C++ main(), but it turned the whole thing into a constant expression!


Clang / LLVM

Using the same syntax, Clang is capable of emitting "fat" object files with LLVM IR, which can be optimized during link time. See LLVM Link Time Optimization.

Using the same test code as above, clang produces the exact same result:

00000000004004b0 <main>:
  4004b0:   b8 0a 00 00 00          mov    eax,0xa
  4004b5:   c3                      ret

这篇关于对于gcc或clang,LTO可以通过C和C ++方法进行优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆