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

Proposal: split AllFacts into contexts dedicated to each component of the pipeline #134

Merged
merged 8 commits into from
Nov 5, 2019

Conversation

lqd
Copy link
Member

@lqd lqd commented Oct 12, 2019

This introduce contexts to store data between the pipeline's steps, to solve some of the problems described in #112.

These contexts are used to store:

  • initialization data, used by liveness
  • liveness data, used by the borrow checking variants
  • some static input data, or partial results, which is shared between variants (and more could be shared)

This also makes more use of Relations between initialization and liveness to avoid creating and cloning the same data (so a slight optimization here).

This separation should also drop the initialization input relations after var_maybe_initialized_on_exit is computed, and the liveness input relations after region_live_at is computed, instead of storing them all throughout the pipeline (although I haven't made sure of how much memory it "saves").

While this PR avoids some Relation cloning (but not all, as it'd require changes in concert with rustc, and which will be done in the future), it mostly avoids computing initialization and liveness twice as happens today, when using the Hybrid variant and the LocationInsensitive pre-pass returns a potential error in the code. (These first 2 steps dominate runtime on bigger benchmarks when that happens)

The Hybrid variant also stores the potential errors found by the LocationInsensitive pre-pass, so that the following variant can heavily prune the data it traverses to find errors on only those specific "interesting" loans. (This is an optimization I've done elsewhere and has very good results on our small number of benchmarks, but can't upstream in a PR yet as this filtering could interfere with the ongoing work on illegal subset relations errors).

While sharing Relations is easy when used as join inputs, it may also be interesting to share the static data inserted in the Variables themselves, when appropriate (which is not that often right now) to avoid mapping and cloning some of this initial input data.

This also re-enables logging from within the polonius bin, which I had forgotten to push to the dependencies cleanup PR.

lqd added 7 commits October 12, 2019 15:17
- Introduce a context to store data common to all variants: initialization, liveness, some of the facts as Relations, so that the Hybrid variant doesn't have to perform the same steps twice
- inline the hybrid variant
- make variants return a Relation of errors so we can reuse them more easily in the future
- store partial results in the context: the locinsensitive potential errors will be used to filter loans in the optimized variant which follows it
- make liveness and initialization use and produce Relations instead of cloning them via Vecs
…instead of leapjoins

that's 1% of free benchmark real estate
@lqd lqd force-pushed the its_all_contextual branch from 112e5fb to 61d763e Compare October 13, 2019 10:24
@amandasystems
Copy link
Contributor

amandasystems commented Oct 14, 2019

I think this looks great, but I'm not 100% comfy with the mem::replace thing. Specifically, I don't like the fact that those inputs are technically invalid after they have been consumed by the earlier stages, but that their access is no longer enforced by the compiler like it would have been if they were moved out. However, the only way to fix that (I guess?) would have been to do the decomposition of all_facts on entry, which I guess has its own drawbacks?

@lqd
Copy link
Member Author

lqd commented Oct 14, 2019

We can split it up more for sure because of the initial clone, while I was trying not to move away too much from AllFacts but there's no specific reason we couldn't do that. We also need to remove the clone and that will require changes in rustc as well, so I think we can use this to iterate on the kind of interface we'd need (after the clone), and then fix that upstream.

@amandasystems
Copy link
Contributor

Sounds reasonable. I also have a few changes of the same kind I'd like to make to rustc (for example, I plan on having child be the actual child relation and not be transitive, instead computing that at the start of the initialisation step).

@lqd lqd changed the title Proposal: share a context between the components of the pipeline Proposal: split AllFacts into contexts dedicated to each component of the pipeline Oct 14, 2019
@lqd
Copy link
Member Author

lqd commented Oct 14, 2019

(updated this to completely separate each step's data)

Comment on lines +169 to +175
let liveness_ctx = LivenessContext {
var_used: all_facts.var_used.clone(),
var_defined: all_facts.var_defined.clone(),
var_drop_used: all_facts.var_drop_used.clone(),
var_uses_region: all_facts.var_uses_region.clone(),
var_drops_region: all_facts.var_drops_region.clone(),
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need these clones? I thought they were only used here?

Copy link
Member Author

@lqd lqd Oct 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the same reason as the previous mem::replaces: we can't move these out of all_facts: &AllFacts<T>

@nikomatsakis nikomatsakis merged commit 46b7c63 into rust-lang:master Nov 5, 2019
@lqd lqd deleted the its_all_contextual branch November 5, 2019 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants