Clang build analysis tool using -ftime-trace
UNLICENSE License
Clang C/C++ build analysis tool when using Clang 9+ -ftime-trace
. The -ftime-trace
compiler flag
(see blog post or
Clang 9 release notes) can be useful
to figure out what takes time during compilation of one source file. This tool helps to aggregate time trace
reports from multiple compilations, and output "what took the most time" summary:
ClangBuildAnalyzer --start <artifacts_folder>
ClangBuildAnalyzerSession.txt
file under the given artifacts_folder
. The artifacts-ftime-trace
flag to the compiler (Clang 9.0 or later is required for this).ClangBuildAnalyzer --stop <artifacts_folder> <capture_file>
*.json
files under the given artifacts_folder
that were modified after--start
step was done (Clang -ftime-trace
produces one JSON file next to each object file), process them and store data file intocapture_file
.ClangBuildAnalyzer --analyze <capture_file>
capture_file
produced by --stop
step, calculate the slowest things and print them. If aClangBuildAnalyzer.ini
file exists in the current folder, it will be read to control how many of various things to print.Aternatively, instead of doing --start
and --stop
steps, you can do ClangBuildAnalyzer --all <artifacts_folder> <capture_file>
after your build; that will
include all the compatible *.json
files for analysis, no matter when they were produced.
The analysis output will look something like this:
Analyzing build trace from 'artifacts/FullCapture.bin'...
**** Time summary:
Compilation (7664 times):
Parsing (frontend): 2118.9 s
Codegen & opts (backend): 1204.1 s
**** Files that took longest to parse (compiler frontend):
5084 ms: cycles_scene.build/RelWithDebInfo/volume.o
4471 ms: extern_ceres.build/RelWithDebInfo/covariance_impl.o
4225 ms: bf_intern_libmv.build/RelWithDebInfo/resect.o
4121 ms: bf_blenkernel.build/RelWithDebInfo/volume_to_mesh.o
**** Files that took longest to codegen (compiler backend):
47123 ms: bf_blenkernel.build/RelWithDebInfo/volume.o
39617 ms: bf_blenkernel.build/RelWithDebInfo/volume_to_mesh.o
37488 ms: bf_modifiers.build/RelWithDebInfo/MOD_volume_displace.o
30676 ms: bf_gpu.build/RelWithDebInfo/gpu_shader_create_info.o
**** Templates that took longest to instantiate:
11172 ms: fmt::detail::vformat_to<char> (142 times, avg 78 ms)
6662 ms: std::__scalar_hash<std::_PairT, 2>::operator() (3549 times, avg 1 ms)
6281 ms: std::__murmur2_or_cityhash<unsigned long, 64>::operator() (3549 times, avg 1 ms)
5757 ms: std::basic_string<char>::basic_string (3597 times, avg 1 ms)
5541 ms: blender::CPPType::to_static_type_tag<float, blender::VecBase<float, ... (70 times, avg 79 ms)
**** Template sets that took longest to instantiate:
32421 ms: std::unique_ptr<$> (30461 times, avg 1 ms)
30098 ms: Eigen::MatrixBase<$> (8639 times, avg 3 ms)
27524 ms: Eigen::internal::call_assignment_no_alias<$> (2397 times, avg 11 ms)
**** Functions that took longest to compile:
28359 ms: gpu_shader_create_info_init (source/blender/gpu/intern/gpu_shader_create_info.cc)
4090 ms: ccl::GetConstantValues(ccl::KernelData const*) (intern/cycles/device/metal/kernel.mm)
3996 ms: gpu_shader_dependency_init (source/blender/gpu/intern/gpu_shader_dependency.cc)
**** Function sets that took longest to compile / optimize:
10606 ms: bool openvdb::v10_0::tree::NodeList<$>::initNodeChildren<$>(openvdb:... (470 times, avg 22 ms)
9640 ms: void tbb::interface9::internal::dynamic_grainsize_mode<$>::work_bala... (919 times, avg 10 ms)
9459 ms: void tbb::interface9::internal::dynamic_grainsize_mode<$>::work_bala... (715 times, avg 13 ms)
7279 ms: blender::Vector<$>::realloc_to_at_least(long long) (1840 times, avg 3 ms)
**** Expensive headers:
261580 ms: /Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/algorithm (included 3389 times, avg 77 ms), included via:
341x: BKE_context.h BLI_string_ref.hh string
180x: DNA_mesh_types.h BLI_math_vector_types.hh array
125x: DNA_space_types.h DNA_node_types.h DNA_node_tree_interface_types.h BLI_function_ref.hh BLI_memory_utils.hh
...
188777 ms: /Developer/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/string (included 3447 times, avg 54 ms), included via:
353x: BKE_context.h BLI_string_ref.hh
184x: DNA_mesh_types.h BLI_offset_indices.hh BLI_index_mask.hh BLI_linear_allocator.hh BLI_string_ref.hh
131x: DNA_node_types.h DNA_node_tree_interface_types.h BLI_span.hh
...
174792 ms: source/blender/makesdna/DNA_node_types.h (included 1653 times, avg 105 ms), included via:
316x: ED_screen.hh DNA_space_types.h
181x: DNA_space_types.h
173x: <direct include>
...
Granularity and amount of most expensive things (files, functions, templates, includes) that are reported can be controlled by having an
ClangBuildAnalyzer.ini
file in the working directory. Take a look at ClangBuildAnalyzer.ini
for an example.
projects/vs2019/ClangBuildAnalyzer.sln
.projects/xcode/ClangBuildAnalyzer.xcodeproj
.make -f projects/make/Makefile
.CMakeLists.txt
, if you want to build using CMake
.License for the Clang Build Analyzer itself is Unlicense, i.e. public domain. However, the source code
includes several external library source files (all under src/external
), each with their own license:
cute_files.h
from RandyGaul/cute_headers: zlib or public domain,cwalk
from likle/cwalk: MIT,enkiTS
, from dougbinks/enkiTS: zlib,flat_hash_map
, from skarupke/flat_hash_map: Boost 1.0,inih
, from benhoyt/inih: BSD 3 clause,llvm-Demangle
, part of LLVM: Apache-2.0 with LLVM-exception,simdjson
from lemire/simdjson: Apache-2.0, version 3.2.2 (2023 Aug),sokol_time.h
from floooh/sokol: zlib/libpng,xxHash
from Cyan4973/xxHash: BSD 2 clause.