重用编译器前端的结果,加快多配置/平台的 C++ 代码编译

Posted

技术标签:

【中文标题】重用编译器前端的结果,加快多配置/平台的 C++ 代码编译【英文标题】:Reuse result of compiler's front-end to speed up compilation of C++ code for multiple configurations/platforms 【发布时间】:2019-04-04 07:46:25 【问题描述】:

我想缩短项目的编译时间。我支持多种平台:OSX、Linux、androidios。我为他们每个人构建项目以进行调试和发布。

假设我的代码没有特定于平台或特定于配置的代码。

任何编译器都可以在以下之后保存其中间表示:

1) 解析代码或

2) 优化阶段

这样我就可以通过(分别)重用结果来缩短编译时间:

1) 调试/发布配置

2) 平台(Android、iOS、OSX、Linux 版本)?

【问题讨论】:

你试过precompiled headers:gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html吗? 所有编译器都能够转储预处理的翻译单元,clang 甚至可以生成中间 LLVM 表示。但是,即使您的项目不包含任何特定于平台的代码,它也可能存在于标准库和其他依赖项中,因此肯定无法重用编译产品。 你说你想加快编译时间,但是你确定瓶颈是什么了吗?鉴于单个变体的编译速度相当快,我会并行构建所有必需的变体。 @VTT:平台特定的代码应该不是问题,除非我动态链接库。关于瓶颈:我还没有检查过。我只有数千个翻译单元,我需要在我们的 CI 上构建它们,我得出的结论是编译器的大部分前端工作都是重复的。 Probably related: SCU 另外,我认为您对 “平台特定代码不应该成为问题” 相当乐观 - 我敢打赌,所有这些平台都有非常不同的预处理器定义集和内在函数。 【参考方案1】:

如果你使用 clang - 答案是肯定的,有可能:

clang -S -emit-llvm something.c

生成something.ll,这是 LLVM IR 文件。下一步是使用llc 工具生成汇编文件:

llc -march=x86 something.ll

应该使用特定于 x86 的程序集创建 something.s

但是我建议不要将它用于大型项目(如果您正在寻找加快编译速度的选项,那么您可能有一个很大的选项)。原因是在您的代码或第三方中,可能使用了特定于平台的宏。例如:

#ifdef UNIX
...
#else
...

预处理器阶段是第一个,它在发出 IR 之前进行。因此,如果您要为另一个平台生成程序集,则它可能是格式错误的。

【讨论】:

谢谢@Dmitry Gordon!我想可以将预处理器阶段从发出 llvm IR 中分离出来,这样我就可以确保预处理代码在给定的平台/配置上是相同的。 是的,您可以将预处理器从 IR 生成中分离出来(-E 标志用于 clang)。但我的观点是 IR 取决于预处理器结果,这可能是特定于平台的。所以不会有针对不同平台的可重用工件。 还有更多...大多数前端会出于某种原因调用 LLVM 的 DataLayout,如果只是为了在调用 new Foo() 时生成 malloc(132),并且在使用 DataLayout 时,LLVM IR 经常包含与目标相关的幻数,例如 132。sizeof(Foo) 在一个 64 位平台上可能是 124,而在另一个平台上可能是 132。

以上是关于重用编译器前端的结果,加快多配置/平台的 C++ 代码编译的主要内容,如果未能解决你的问题,请参考以下文章

笔记:C++加快template的编译

c++中的快速编译

distcc 问题:它真的可以加快编译速度吗?

zookeeper支持c++吗

JAVA编程思想中总结的与C++的区别

开启多线程加快编译速度