Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store const_eval_raw results to disk #62166

Closed
wants to merge 1 commit into from

Conversation

Zoxc
Copy link
Contributor

@Zoxc Zoxc commented Jun 27, 2019

Based on #59722.

r? @oli-obk

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 27, 2019
@Zoxc
Copy link
Contributor Author

Zoxc commented Jun 27, 2019

@oli-obk Do you know why we only store const eval results which does not result in an error?

@Zoxc
Copy link
Contributor Author

Zoxc commented Jun 27, 2019

@bors try

@oli-obk
Copy link
Contributor

oli-obk commented Jun 27, 2019

Do you know why we only store const eval results which does not result in an error?

I don't remember. I think I just kept the status quo alive and assumed there's a reason.

@oli-obk
Copy link
Contributor

oli-obk commented Jun 27, 2019

We do need this for statics, because const_eval will validate statics, and statics can be mutually recursive. So we call const_eval_raw to not run validation during const eval.

This will increase the amount of cached data, potentially by very large amounts. Every constant that has a trivial representation via ConstValue::Scalar will now require a full allocation to be cached to disk.

But I think I can design a perf test that shows that this PR is a perf improvement, but I'm not sure if its worth it to include it. Essentially it should be

// lib.rs of crate `foo`
static FOO: u32 = 42; // do some very complex static computation here
// main.rs of crate `foo`
static BAR: u32 = *&foo::FOO + 1;

Because reading from a static via an indirection will trigger

let raw_const = tcx.const_eval_raw(ty::ParamEnv::reveal_all().and(gid))

The only other uses are const evaluation of const fn with promoteds:

self.const_eval_raw(GlobalId {

Ok, I just found one use that is odd:

return Ok(OpTy::from(self.const_eval_raw(GlobalId {
introduced in ba82f54 @RalfJung since we only need an operand here, could we do the recursive thing again and use const_eval and call const_to_op instead of using const_eval_raw.

Then we could cache const_eval_raw only for promoteds and statics, although we could consider having promoteds go thorough the const_eval path, too.

@RalfJung
Copy link
Member

I did that because (a) converting a ConstValue back to an Operand is very messy, because ConstValue is really optimized for whatever the rest of the compiler needs, and I had hoped that we will eventually just kill the function in const_eval.rs that performs this conversion and the world will be a better place, and (b) I prefer to consistently use the same query for the constants/statics we encounter during evaluation.

@RalfJung
Copy link
Member

Ah, turns out that messy ConstValue-to-op code is in that same function eval_const_to_op. ;) So I guess we cannot avoid that mess. :/

The argument about consistency remains though, and also I'd expect a performance cost from doing validation there when it is not needed?

Why is this call not a problem? That one cannot be replaced. Right now all "recursive" const eval goes through InterpCtx::const_eval_raw and that's nice.

self.const_eval_raw(GlobalId {

@oli-obk
Copy link
Contributor

oli-obk commented Jun 27, 2019

I'd expect a performance cost from doing validation there when it is not needed?

That cost will be paid anyway once const_eval is called (which it is for all constants)

So I guess we cannot avoid that mess. :/

We could avoid it if we removed ConstValue::Scalar and ConstValue::Slice, but that has a performance regression (I tried it once)

The reason I want to remove it is so that we don't store the Allocation of a trivial constant in metadata when we start caching const_eval_raw

@RalfJung
Copy link
Member

RalfJung commented Jun 27, 2019

That cost will be paid anyway once const_eval is called (which it is for all constants)

Well, except for generic consts (once they exist). But I get what you are saying.

The reason I want to remove it is so that we don't store the Allocation of a trivial constant in metadata when we start caching const_eval_raw

Remove what? I don't understand how that is connected to replacing one of three places where the interpreter calls const_eval_raw, with const_eval -- why doing something else sometimes should be of any help.

@oli-obk
Copy link
Contributor

oli-obk commented Jun 27, 2019

why doing something else sometimes should be of any help.

If we only cache const_eval_raw calls for statics and promoteds, but we keep calling it for constants, then downstream crates will recompute those constants instead of fetching them from the cache. So if we use const_eval for constants, we only need to cache const_eval, which we already do.

@Zoxc
Copy link
Contributor Author

Zoxc commented Jun 27, 2019

@bors try

@Zoxc Zoxc closed this Jun 27, 2019
@Zoxc Zoxc reopened this Jun 27, 2019
@Zoxc
Copy link
Contributor Author

Zoxc commented Jun 27, 2019

@bors try

@bors
Copy link
Contributor

bors commented Jun 27, 2019

⌛ Trying commit 6a5afdd with merge c385f72...

bors added a commit that referenced this pull request Jun 27, 2019
 Store const_eval_raw results to disk

Based on #59722.

r? @oli-obk
@RalfJung
Copy link
Member

If we only cache const_eval_raw calls for statics and promoteds, but we keep calling it for constants, then downstream crates will recompute those constants instead of fetching them from the cache. So if we use const_eval for constants, we only need to cache const_eval, which we already do.

So you want to reliably use const_eval_raw for statics/promoteds, but const_eval for constants? I see. I don't like this lack of uniformity, but at least it's not entirely arbitrary -- and I guess there's always some price to pay for performance.

Do you think we can set things up in a way such that if we ever get it wrong, we get an ICE? That would put me more at ease with this scheme.

@bors
Copy link
Contributor

bors commented Jun 27, 2019

💥 Test timed out

@bors
Copy link
Contributor

bors commented Jun 30, 2019

☔ The latest upstream changes (presumably #59722) made this pull request unmergeable. Please resolve the merge conflicts.

@Zoxc
Copy link
Contributor Author

Zoxc commented Jul 1, 2019

@bors try

@bors
Copy link
Contributor

bors commented Jul 1, 2019

⌛ Trying commit 77c0af6 with merge 6ae40628b538d3adb52b1770f7eb908a19255148...

@bors
Copy link
Contributor

bors commented Jul 1, 2019

💔 Test failed - checks-azure

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 1, 2019
@Zoxc
Copy link
Contributor Author

Zoxc commented Jul 1, 2019

@bors try

@bors
Copy link
Contributor

bors commented Jul 1, 2019

⌛ Trying commit 77c0af6 with merge a60befa583852dee37603e3bd00fd04ff2870b54...

@Zoxc
Copy link
Contributor Author

Zoxc commented Jul 1, 2019

@rust-timer build a60befa583852dee37603e3bd00fd04ff2870b54

@rust-timer
Copy link
Collaborator

Success: Queued a60befa583852dee37603e3bd00fd04ff2870b54 with parent 765eebf, comparison URL.

@bors
Copy link
Contributor

bors commented Jul 1, 2019

💥 Test timed out

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 1, 2019
@rust-timer
Copy link
Collaborator

Finished benchmarking try commit a60befa583852dee37603e3bd00fd04ff2870b54, comparison URL.

@Zoxc Zoxc closed this Jul 2, 2019
Centril added a commit to Centril/rust that referenced this pull request Jul 4, 2019
Derive which queries to save using the proc macro

Based on rust-lang#62166.

r? @eddyb
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this pull request Jul 4, 2019
Derive which queries to save using the proc macro

Based on rust-lang#62166.

r? @eddyb
Centril added a commit to Centril/rust that referenced this pull request Jul 5, 2019
Derive which queries to save using the proc macro

Based on rust-lang#62166.

r? @eddyb
Centril added a commit to Centril/rust that referenced this pull request Jul 5, 2019
Derive which queries to save using the proc macro

Based on rust-lang#62166.

r? @eddyb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants