2

I'd like to improve compilation time of my project. I support multiple platforms: OSX, Linux, Android, iOS. For each of them I build project for debug and release.

Let's assume that my code has no platform specific nor configuration specific code.

Is it possible by any compiler to save its intermediate representation after:

1) parsing code or

2) optimisation phase

so that I can improve compilation time by reusing results for (respectively):

1) debug/release configurations

2) platform (release of Android, iOS, OSX, Linux)?

mkk
  • 675
  • 6
  • 17
  • 1
    Did you try `precompiled headers`: https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html? – vahancho Apr 04 '19 at 07:58
  • 1
    All compilers are capable of dumping preprocessed translation unit, clang can even produce intermediate LLVM representation. However even if your project does not contain any platform specific code it may be present in standard library and other dependencies so there is certainly no way to reuse compilation products. – user7860670 Apr 04 '19 at 08:02
  • You say you want to speed up compilation time, but have you determined what is the bottleneck? Given that compilation of single variant is reasonably fast I would go with building all the required variants in parallel. – user7860670 Apr 04 '19 at 08:05
  • @VTT: platform specific code should not be a problem unless I link libraries dynamically. Regarding bottlenecks: I haven't checked that. I just have thousands of translation units, I need to build them all on our CI and I came to conclusion that most of compiler's front-end work is repeated. – mkk Apr 04 '19 at 08:26
  • [Probably related: SCU](https://stackoverflow.com/questions/46319579/what-are-the-drawbacks-of-single-source-project-structures/46321758#46321758) Also I think you are rather optimistic about *"platform specific code should not be a problem"* - I bet all those platforms have very different sets of preprocessor defines and intrinsics. – user7860670 Apr 04 '19 at 08:30
  • So it seems it is worth to run preprocessor on each platform/configuration so that I can compare if the output is the same or not on various platforms and then decide if I want to proceed with single or multiple parsing phase. – mkk Apr 04 '19 at 09:09

1 Answers1

2

If you use clang - the answer is yes, it's possible:

clang -S -emit-llvm something.c

produces something.ll which is LLVM IR file. The next step is to use llc utility to produce assembly file:

llc -march=x86 something.ll

should create something.s with x86-specific assembly.

However I would advise not to use it for a big project (if you're seeking for an options to speed up compilation, possibly you have a big one). The reason is that in your code or in third-parties there maybe used macros that are platform-specific. For example:

#ifdef UNIX
...
#else
...

The preprocessor stage is the first one, it goes before emiting IR. So if you will generate assembly for another platform it can be ill-formed.

Dmitry Gordon
  • 2,229
  • 12
  • 20
  • Thanks @Dmitry Gordon! I guess it is possible to split preprocessor phase from emitting llvm IR, so that I could ensure that preprocessed code is the same on given platform/configuration. – mkk Apr 04 '19 at 09:11
  • Yes, you can split preprocessor from IR generation (-E flag for clang). But my point was that the IR depends on the preprocessor result, which may be platform-specific. So there will be no reusable artifacts for different platforms. – Dmitry Gordon Apr 04 '19 at 09:55
  • 1
    There's more... most frontends will call LLVM's DataLayout for one reason or another, if only to generate `malloc(132)` in a call to `new Foo()`, and when DataLayout is used, the LLVM IR often contains target-dependent magic numbers like that 132. sizeof(Foo) might be 124 on one 64-bit platform and 132 on another. – arnt Apr 05 '19 at 07:34