对于gcc或clang,LTO可以通过C和C ++方法进行优化 [英] Can LTO for gcc or clang optimize across C and C++ methods
问题描述
如果链接时间优化(LTO)与 gcc 或 clang ,是否有可能在C和C ++语言边界上优化代码?
例如,一个C函数可以内联到一个C ++调用者中吗?
<强大>是!
链接时间优化通常适用于存在于胖目标文件中的中间表示(IR),它可以同时包含传统链接和用于LTO链接的IR。
在这个阶段,没有更多的高级语言结构,所以链接时间优化与语言无关。 / p>
GCC
GCC的链接时优化 (LTO)在GCC的中间表示之一GIMPLE上工作。 IR总是与语言无关,所以任何链接时间优化都可以跨越任何语言生成的代码。
从 LTO的另一个特点是可以对用不同语言编写的文件应用进程间优化: 请注意,最终的链接是使用g ++完成的,以获得C ++运行时库和<$ c添加$ c> -lgfortran 以获取Fortran运行时库。通常,在LTO模式下混合语言时,应该使用与在常规(非LTO)编译中混合语言时相同的链接命令选项。 以下示例显示了该技术的强大程度。我们将定义一个C函数,并从C ++程序中调用它: 编译 反汇编( 您可以看到它不仅将我的C 使用同样的语法,Clang能够发出带有LLVM IR的胖目标文件,这可以在链接期间进行优化。请参阅 LLVM链接时间优化。 使用与上面相同的测试代码,clang产生完全相同的结果: 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'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: Notice that the final link is done with g++ to get the C++ runtime libraries and
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: Compile Disassemble ( You can see that it not only inlined my C 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:
这篇关于对于gcc或clang,LTO可以通过C和C ++方法进行优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
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
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 $ c
$ 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
func()
内联到我的C ++ main()
中,而且它将整个事物到一个常量表达式!
$ hr
$ b Clang / LLVM
00000000004004b0< main> ;:
4004b0:b8 0a 00 00 00 mov eax,0xa
4004b5:c3 ret
GCC
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
-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.
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
func()
into my C++ main()
, but it turned the whole thing into a constant expression!
Clang / LLVM
00000000004004b0 <main>:
4004b0: b8 0a 00 00 00 mov eax,0xa
4004b5: c3 ret