Change:
In the 2017-12-14 Nightly I've seen a significant (almost 20%) compilation-time increase when I use on my code. And the successive day (2017-12-15) the compilation got a bit slower still and the run-time of the binary also got about 8% slower. The successive days the situation kept going slightly worse. Extracting parts of my code to show compiler/code performance is not easy, so I've composed this benchmark function (that solves an Euler problem. If this code isn't enough I will write other similar benchmarks): <details<summarySource code</summary</detailsCompiled with: host: x86_64-pc-windows-gnu Runtime: 2017-12-13: 0.30 seconds 2017-12-20: 0.53 seconds Asm from the the 2017-12-13 compiler: Asm from the the 2017-12-20 compiler:
Could someone try to reproduce and bisect this?
cc I think
We shouldn't have such big asm differences between successive nightlies, and I don't see anything suspicious in the middle, so it would be good to try and nail down the commit that made the difference.
I see a regression with this code (note: this is distinct from ). the bad code accesses the stack pointer (%rsp) You have a fast network connection and know how to use . Could you please do so? You should grep for to tell if the code is bad - the bad code includes the following line:
I bisected original example, just testing the speed of the executable created by a stage 1 and came upon (PR ) as the culprit: the runtime on my machine is around 0.3 seconds before that commit and around 0.7 seconds after. latest example also has a clear difference. The code before that commit (just disassembling the ): And after:
That's unfortunate. cc
cc
Thanks We're looking into it
just testing the speed of the executable I am not sure if they share the same cause, first a significant compiler performance decrease using --emit=metadata , then the successive Nightly the decrease of the produced binary performance.
They should not. However, quite a few big commits landed in the Dec 14 nightly. If you could provide an example that exhibits the slowdown with , that would allow us to fix it (is the Dec 13 nightly faster than the Dec 14 nightly which has the same speed, but worse runtime performance, than the Dec 15 nightly?)
The last nightly (2017-12-21) has fixed all three problems. Despite some attempts I failed finding a small amount of code that shows a significant compilation slowdown from 2017-12-14 to 2017-12-20, perhaps it's a more diffuse problem that emerges from compiling my whole big amount of code. I am sorry. I don't fully understand your question, but I try to answer creating a table with some data for some of the last Nightlies: Rustc version --emit=metadata Opt build Binary size Run-time 1.24.0-nightly 2017-12-11 4.32 49.78 12.93 1.24.0-nightly 2017-12-12 4.31 48.50 12.84 1.24.0-nightly 2017-12-13 5.15 50.69 12.86 1.24.0-nightly 2017-12-15 5.33 52.98 14.04 1.24.0-nightly 2017-12-17 5.44 53.31 14.03 1.24.0-nightly 2017-12-20 5.47 54.49 14.14 1.24.0-nightly 2017-12-21 4.28 48.82 12.96 The --emit=metadata is a check time. The Opt build is the compilation time for a well optimized build. The binary size is stripped and in bytes. The times are all in seconds.
EDIT: told me about , so the range is .... EDIT2: at a quick glance, none of those changes should affect binary size or run time. How many times have you run each of these? How much do they vary?
They should be: rustc 1.24.0-nightly ( 2017-12-20) binary: rustc commit-hash: commit-date: 2017-12-20 host: x8664-pc-windows-gnu release: 1.24.0-nightly LLVM version: 4.0 rustc 1.24.0-nightly ( 2017-12-21) binary: rustc commit-hash: commit-date: 2017-12-21 host: x8664-pc-windows-gnu release: 1.24.0-nightly LLVM version: 4.0 Mixing up things seems quite easy here.
Ah, that's why I asked, so the range is .... Still not seeing anything clearly relevant, but maybe someone else from does?
The --emit=metadata times are computed as the minimum of four tries. Their variance is very small (on the order of +-0.05) so I think they are reliable. The binary run-time is the minimum of 5 runs, their variance is higher perhaps because they do some I/O, despite using a SSD, about +-0.12. The compilation is slow so there I've done only one time, so those values are the less reliable, but differences above 1.5 seconds should be reliable.
For the compilation time issue, maybe there was a bug in NLL that made it active without it being enabled. For the run-time issue, we need to actually investigate this.
As in, investigate the cause of the run-time fluctuations and how it unregressed?
This is my good old friend the torpedo. LLVM optimizes into this: This is basically equivalent to this pseudo-Rust code After the "non-constant-address" write is generated, LLVM is sunk - LLVM has no way of getting rid of the non constant address, and no way of optimizing accesses to the target with that non-constant address.
Upstream LLVM (that's the yet-to-be-released LLVM 6) has this patch, which avoids the SimplifyCfg sink problem by not running sinking before inlining I have confirmed that - e.g. this code is optimized correctly with the new Until then, I think representing small enums using a struct (rather than an array) should work around this problem.
With the 2017-12-22 Nightly all the problems are back: Rustc version --emit=metadata Opt build Binary size Run-time 1.24.0-nightly 2017-12-22 5.36 53.57 13.96
Coud you open a PR that turns small unions into LLVM structs (rather than arrays)? That should fix the problem.
The binaries generated by the last Nightly (1.24.0-nightly 2017-12-25) is further few percents slower (perhaps because of thinLTO?), the compilation times can't be compared now.
Is there more stable measure besides compile time / run time? They can be affected too easily by the environment especially when the run time is expected to take less than 1 second. The generated assembly size seems to be a good measure.
Please re-test next nightly and reopen if not fixed.
The run-time of the binary is now OK. The compilation time with --emit=metadata is still quite large.
Can you open a separate one for compilation times? Seems to be a separate issue.
, I've tried here:

Discussion:
discr, variants }, <del> // FIXME(eddyb): using `FieldPlacement::Arbitrary` here results // in lost optimizations, specifically around allocations, see // `test/codegen/{alloc-optimisation,vec-optimizes-away}.rs`. fields: FieldPlacement::Union(1), </del> <ins> fields: FieldPlacement::Arbitrary { offsets: vec![Size::from_bytes(0)], memory_index: vec![0] }, </ins> abi, align, size

A(i32), B(i32), } <del> // CHECK: %Enum4 = type { [2 x i32] } </del> <ins> // CHECK: %Enum4 = type { [0 x i32], i32, [1 x i32] } // CHECK: %"Enum4::A" = type { [1 x i32], i32, [0 x i32] } </ins> pub enum Enum64 { A(Align64), B(i32), } <del> // CHECK: %Enum64 = type { [16 x i64] } </del> <ins> // CHECK: %Enum64 = type { [0 x i32], i32, [31 x i32] } </ins> // CHECK: %"Enum64::A" = type { [8 x i64], %Align64, [0 x i64] } // CHECK-LABEL: @align64