# Clang's new \`-ftime-trace\` flag

**URL:** <https://internals.rust-lang.org/t/clangs-new-ftime-trace-flag/11037>\
**Category:** compiler\
**Created:** [October 2, 2019, 7:18am UTC](https://internals.rust-lang.org/t/clangs-new-ftime-trace-flag/11037 "2019-10-02T07:18:15Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ryan1729](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ryan1729/32/4770_2.png) [@Ryan1729](https://internals.rust-lang.org/u/Ryan1729)\
**Post date:** [October 2, 2019, 7:18am UTC](https://internals.rust-lang.org/t/clangs-new-ftime-trace-flag/11037/1 "2019-10-02T07:18:16Z")

</div>

Clang has [recently added a `-ftime-trace` flag](https://releases.llvm.org/9.0.0/tools/clang/docs/ReleaseNotes.html#new-compiler-flags) that outputs a flame chart detailing how long different parts of the code being compiled took to do so. I wasn't sure whether this meant that passing flags to `rustc` will produce this info about a given rust program, and searching didn't directly give me the answer to that, so I tried it.

The first step there was running `rustc -C llvm-args="--version"` to confirm that the version matched the version of Clang that has the new flag. The output was as follows:

```rust
LLVM (http://llvm.org/):
  LLVM version 9.0.0-rust-1.38.0-stable
  DEBUG build.

```

Along with some information about the target and host CPU. (By the way, I hope that "DEBUG build." doesn't mean that rustc is using an unoptimized build of LLVM!) The new flag came with Clang version 9.0.0, so that looked promising. However, neither `rustc -C llvm-args="--help"` nor `rustc -C llvm-args="--help-list-hidden"` listed `-ftime-trace`, and just trying it anyway produced an error.

Confusingly, `--time-trace-granularity` was listed, which appears to be an optional flag related to the time trace flag. Running `cargo rustc -- -C llvm-args="--time-trace-granularity=1000000"` successfully builds the project I tried it on, but no `.json` file was produced in the `target/debug` directory.

---

<div class="post-metadata">

**Author:** ![HadrienG](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/hadrieng/32/3294_2.png) [@HadrienG](https://internals.rust-lang.org/u/HadrienG)\
**Post date:** [October 2, 2019, 12:09pm UTC](https://internals.rust-lang.org/t/clangs-new-ftime-trace-flag/11037/2 "2019-10-02T12:09:33Z")

</div>

If this feature is part of the Clang C/++ frontend, and not part of the underlying LLVM language-agnostic compiler backend, then rustc cannot (easily) use it.

You may, however, be interested in rustc's own self-profiling features, possible improvements to which are [being discussed elsewhere on this forum as we speak](https://internals.rust-lang.org/t/compiler-profiling-survey/10969).

---

<div class="post-metadata">

**Author:** ![Ryan1729](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ryan1729/32/4770_2.png) [@Ryan1729](https://internals.rust-lang.org/u/Ryan1729)\
**Post date:** [October 2, 2019, 8:47pm UTC](https://internals.rust-lang.org/t/clangs-new-ftime-trace-flag/11037/3 "2019-10-02T20:47:14Z")

</div>

Ah, I had not seen that thread, thanks for pointing it out! I'm glad that the concept of make data available that can answer the question "what changes can I make to this code to make it compile faster?", rather than just the question "What changes can be made to `rustc` to make this compile faster?" is being discussed. The `-ftime-trace` flag itself was also already linked to from there.

---

<div class="post-metadata">

**Author:** ![HadrienG](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/hadrieng/32/3294_2.png) [@HadrienG](https://internals.rust-lang.org/u/HadrienG)\
**Post date:** [October 2, 2019, 9:23pm UTC](https://internals.rust-lang.org/t/clangs-new-ftime-trace-flag/11037/4 "2019-10-02T21:23:41Z")

</div>

"What changes can I make to this code to make it compile faster?" is a difficult question in Rust, because the language has a rather sophisticated compilation model:

- Monomorphization and macros may generate many copies of the "same" code, but the compiler is smart enough to reuse a given generic instantiation multiple times in a crate.
- Incremental compilation means that code which was built before may not get rebuilt, and the analysis that decides what gets built has sub-source file granularity.
- The emerging lazy "query" model, which was introduced as part of the incremental compilation effort, could also reduce the compilation impact of unused code...
  - Not sure if it does today, but pretty sure it will in the future, once MIR-only rlibs are a thing.

It's not like in C where each function in a .c file will get built exactly once with rather predictable overhead.

* * *

However, there are two classic tricks that can greatly speed up your Rust builds:

- Audit your dependencies. Cargo makes it trivial to bring in plenty of external crates to speed up your development workflow, but with great power comes great responsibility.
  - If initial build times matter to you, consider dropping dependencies which you do not use much (e.g. replacing clap with raw std::env for basic CLI argument needs).
  - If your dependencies have cargo features, only enable those that you need.

- Use `cargo-bloat` to figure out what takes up room in your output binary. Code size is a surprisingly effective indicator of compile-time overhead, considering how indirect it is, and [it can be an easy way to spot classic macro and monomorphization mistakes](https://clap.rs/2018/01/09/new-years-weight-loss/) that can also hurt your compile times.

Here's another interesting discussion of [some common causes of compile times and binary bloat in Rust](https://raphlinus.github.io/rust/2019/08/21/rust-bloat.html).

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [October 2, 2019, 9:38pm UTC](https://internals.rust-lang.org/t/clangs-new-ftime-trace-flag/11037/5 "2019-10-02T21:38:21Z")

</div>

I don't see any option that we could use with `rustc -C llvm-args`, but Clang just calls `llvm::timeTraceProfilerInitialize()` etc. from `llvm/Support/TimeProfiler.h`. We could add bindings for that API in `src/rustllvm` to enable a custom `-C`/`-Z` option.

---

<div class="post-metadata">

**Author:** ![andjo403](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/andjo403/32/2931_2.png) [@andjo403](https://internals.rust-lang.org/u/andjo403)\
**Post date:** [October 5, 2019, 9:49am UTC](https://internals.rust-lang.org/t/clangs-new-ftime-trace-flag/11037/6 "2019-10-05T09:49:21Z")

</div>

the problem with only adding the `llvm::timeTraceProfilerInitialize()` was that the llvm code is not tread safe so you need to use the -Z no-parallel-llvm also.

also made a hack to add the traces to -Z self-profiling to get the thread safety. but then I needed to filter to only what function that was optimized, as I bypassed the `--time-trace-granularity` that was one of the parts that was not thread safe, this due to self-profiling do not support the filter over time and some crates failed to compile due to the 1GB event store was not enough.

see more in the thread [https://github.com/rust-lang/measureme/issues/51](https://github.com/rust-lang/measureme/issues/51)

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [October 5, 2019, 3:50pm UTC](https://internals.rust-lang.org/t/clangs-new-ftime-trace-flag/11037/7 "2019-10-05T15:50:55Z")

</div>

If you're inclined, that could be an LLVM contribution opportunity to make that API thread safe.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [January 3, 2020, 3:51pm UTC](https://internals.rust-lang.org/t/clangs-new-ftime-trace-flag/11037/8 "2020-01-03T15:51:04Z")

</div>

Closed on January 3, 2020, 3:51pm UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
