Stream: t-compiler/const-eval

Topic: const_eval is slow with locals without liveness markers


Björn Steinbrink (Jan 03 2019 at 16:05, on Zulip):

While working on https://github.com/rust-lang/rust/issues/36673 I noticed that const_eval gets a lot slower when the storage liveness markers get removed. I suspect it's because without the liveness markers the push_stack_frame function has to eagerly "initialize" the local right away, instead of doing it lazily when (and if) it hits the StorageLive marker.

RalfJ (Jan 03 2019 at 16:08, on Zulip):

that might be, though this should only make a difference when there are lots of unused local variables

Björn Steinbrink (Jan 03 2019 at 16:10, on Zulip):

with the example code from that issue, I'm seeing millions of extra queries to erase_regions_ty and layout_of. I'm pretty clueless about how const_eval works, so I'm not sure whether that's to be expected

Björn Steinbrink (Jan 03 2019 at 16:11, on Zulip):

comparing the -Zself-profile output for a run that doesn't remove the markers and one that just removes the markers, but doesn't actually do any copy propagation

RalfJ (Jan 03 2019 at 16:11, on Zulip):

allocating memory for a local calls layout_of to determine the size of the type of the local

RalfJ (Jan 03 2019 at 16:12, on Zulip):

it probably also calls erase_regions_ty because const eval does that all the time

Björn Steinbrink (Jan 03 2019 at 16:12, on Zulip):

erase_regions_ty seems to come via monomorphize()

Björn Steinbrink (Jan 03 2019 at 16:13, on Zulip):

also called in layout_of_local

RalfJ (Jan 03 2019 at 16:14, on Zulip):

yeah that makes sense

RalfJ (Jan 03 2019 at 16:14, on Zulip):

not sure why there are so many unused locals though

RalfJ (Jan 03 2019 at 16:14, on Zulip):

Cc @Oli

Björn Steinbrink (Jan 03 2019 at 16:53, on Zulip):

looks like this is via validate_and_turn_into_const which, AFAICT, creates an eval context from the function's mir for every promoted mir, which probably(?) explains why the locals are unused

RalfJ (Jan 03 2019 at 16:57, on Zulip):

oh yeah, we do funny things for promoteds

RalfJ (Jan 03 2019 at 16:57, on Zulip):

I dont know which funny things though^^ but @Oli does

oli (Jan 03 2019 at 17:42, on Zulip):

I tried a while back to create a dummy mir that we can use in mk_eval_cx to work around doing any operations during the push_stack_frame

oli (Jan 03 2019 at 17:47, on Zulip):

Should be fairly easy to do if you don't attempt to create a constant like I did :P

Björn Steinbrink (Jan 03 2019 at 18:05, on Zulip):

@oli could we add an Undef variant in addition to the Dead variant? Seems that all code path ultimately simply ignore accesses to undef values atm anyway

oli (Jan 03 2019 at 18:14, on Zulip):

There's an Undef inside the initialized variant. But I'd rather use a dummy mir. If you want I can cook up a quick PR

Björn Steinbrink (Jan 03 2019 at 18:15, on Zulip):

@Oli yeah, but that requires the layout computations which make things expensive, thus I was thinking of moving it to a higher level. PR sounds good to me

oli (Jan 03 2019 at 18:20, on Zulip):

@Björn Steinbrink your pings aren't highlighting me, I think you need to tab complete

Björn Steinbrink (Jan 03 2019 at 18:21, on Zulip):

@Oli better?

RalfJ (Jan 04 2019 at 10:55, on Zulip):

initialized with Undef and uninitialized are not the same state

RalfJ (Jan 04 2019 at 10:55, on Zulip):

in the former case we do have backing memroy allocated but not initialized yet, in the latter case there is no memory yet

RalfJ (Jan 04 2019 at 10:55, on Zulip):

so it makes sense for these to be distinct states

RalfJ (Jan 04 2019 at 10:55, on Zulip):

and we may need that for unsized locals where we cannot pre-allocate because we don't know the size

RalfJ (Jan 04 2019 at 10:56, on Zulip):

one thing I am wondering about: for unsized locals, when exactly do we emit the alloca for LLVM? When is the size determined? That should be the place where miri allocates the backing memory. (CC @eddyb @Oli )

Björn Steinbrink (Jan 04 2019 at 15:39, on Zulip):

@RalfJ what kind of unsized local are you referring to? Do we support C99 style variable length arrays now or something like that?

RalfJ (Jan 04 2019 at 16:39, on Zulip):

much better than that: https://doc.rust-lang.org/unstable-book/language-features/unsized-locals.html

Jake Goulding (Jan 05 2019 at 03:09, on Zulip):

Huh. I missed that had been implemented at all

oli (Jan 05 2019 at 12:07, on Zulip):

@Björn Steinbrink one thing that I think we should probably do is to not run optimizations like inlining and copy propagation on constants and statics (associated constants might still make sense to get optimized though)

oli (Jan 05 2019 at 12:07, on Zulip):

also not on promoteds

Last update: Nov 15 2019 at 21:25UTC