重用编译器前端的结果,加快多配置/平台的 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、android、ios。我为他们每个人构建项目以进行调试和发布。
假设我的代码没有特定于平台或特定于配置的代码。
任何编译器都可以在以下之后保存其中间表示:
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++ 代码编译的主要内容,如果未能解决你的问题,请参考以下文章