2015-10-13 84 views
3

我想整理一个嵌入式项目,其中开发人员可以选择将所有h和c文件包含到ac文件中,然后他们可以使用-whole-program选项编译该文件良好的尺寸优化。大小优化选项

我讨厌这个,并且决心把它变成传统的使用LTO的程序来实现。

开发工具包附带的版本是; APS-GCC(海湾合作委员会)4.7.3 20130524(Cortus) GNU LD(GNU Binutils的)2.22

有了一个.o文件将是的.text 0x1c7ac,分裂成67个.o文件的.text出来作为0x2f73c,我添加LTO的东西,并减少到0x20a44,很好,但远远不够。

我已经尝试过--gc-sections和使用链接器插件选项,但他们没有进一步的改进。

任何建议,我看到从LTO正确的改进?

+0

碰撞toolchain版本的选项呢? – Joe

+2

我打算建议一样,IIRC后来的GCC版本在LTO领域做了显着的改进。此外,使用配置文件反馈来进一步减少可执行文件大小当然,用'-Os'编译。 –

+0

为什么不编译时编译生成最终产品时编译时创建单个大文件的工具。这就是sqlite团队的工作 – pm100

回答

0

要获得LTO完美地工作,你需要有可在链接阶段相同的信息和优化算法,你必须在编译阶段。 GNU工具无法做到这一点,我相信这实际上是创建LLVM/Clang的动机之一。

如果你想检查细节的差异,我建议你为每个选项生成一个Map文件(ld选项-Map <filename>),看看是否有函数没有内联或函数较大。通过将函数的定义移动到一个头文件并将其定义为extern inline,将其有效地转换为一个宏(这是一个GNU扩展),可以通过强制这些函数内联来手动解决缺乏内联问题。

较大的功能可能不是受常量传播,我不认为有什么你可以做的。您可以通过仔细声明函数属性做一些改进,如constleafnoreturnpurereturns_nonnull。这些实际上保证了函数将以一种特殊的方式运行,即如果使用单个编译单元,编译器可能会检测到这种方式,并允许进行其他优化。相比之下,Clang可以将你的目标代码编译成一种特殊的字节码(LLVM代表低级虚拟机,比如JVM是Java虚拟机,并且运行字节码),然后可以在链接上优化这个字节码时间(或者确实是运行时间,这很酷)。由于无论您是否使用LTO,此字节码都是最优化的,并且优化算法在编译器和链接器之间是常见的,理论上,无论您是否使用LTO,Clang/LLVM都应该提供完全相同的结果。

不幸的是,现在的C后端已经从LLVM删除我不知道任何方式使用LLVM LTO功能,为您指定的定制CPU。

0

在我看来,以前的开发者选择的方法是正确的。这是为编译器提供最多信息的方法,因此也是执行所需优化的最多机会。这是一种可怕的编译方式(任何修改都需要编译整个项目),所以将其标记为只是一个选项是个好主意。

当然,你将不得不对这样的构建运行你所有的集成测试,但是这应该是微不足道的事。除了编译时间之外,所选方法的缺点是什么(这不应该成为一个问题,因为您不需要始终以这种方式构建......仅用于集成测试)。