Skip to content

Instantly share code, notes, and snippets.

@erikzenker
Last active July 15, 2020 12:15
Show Gist options
  • Save erikzenker/a318fd59cdb4de87db3d659cf425cc1a to your computer and use it in GitHub Desktop.
Save erikzenker/a318fd59cdb4de87db3d659cf425cc1a to your computer and use it in GitHub Desktop.

Clang Compile Time Cookbook

In this cookbook I will discuss several techniques to reduce the compile time of the llvm frontend clang. I will put the focus on heavy template and constexpr code.

Clang Tools Pipeline

First it is important to understand the internals of clang. Clang is a collection of tools which are pipelined.

Preprocessor

  • Performs the actions of the C preprocessor
  • The command line option -E stops clang after this stage

Parsing

  • Parses the source code and generates the AST
  • The command line option -precompile stops clang after this stage

IR generation

  • Converts the AST into an optimizer-specific intermediate representation (IR)
    • Source
    • InstantiateClass / InstantiateFunction
    • PerformPendingInstantiations
    • CodeGen Function
    • PerfFunctionPasses
    • PerfModulePasses / OptModule
  • The command line option -emit-llvm stops clang after this stage

Compiler backend

  • Converts the IR into target-specific assembly code
    • CodeGenPasses
  • The command line option -S stops clang after this stage

Assembler

  • Converts target-specific assembly code into target-specific machine code object files
  • The command line option -c stops clang after this stage

Linker

  • Combines multiple object files into a single image

Analyse Clang Compile Time

Since clang 9 you can analyse compile time very detailed with the cxx flag -ftime-trace. This flag generates a json file which can be loaded into the chrome trace analyser chrome://tracing/ or an online tool

Once you have generated the json file and opened it in chrome you will notice the different stages of the clang pipeline e.g. source, frontend, and backend.

  • It can be hard to read through the trace if you use anonymous functions (lambdas) since they will be listed as (anonymous class)::operator(). For better readability you should use templated functions or Functors.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment