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

remove interior mutability of type-flags #42015

Merged
merged 14 commits into from
May 23, 2017

Conversation

nikomatsakis
Copy link
Contributor

@nikomatsakis nikomatsakis commented May 15, 2017

We were previously using the flags on Ty<'tcx> instances to do some ad-hoc caching schemes around things like is_sized(), is_freeze(), and moves_by_default(). This PR replaces those schemes with a proper query; the query key is based on the pair of a (ParameterEnvironment<'tcx>, Ty<'tcx>) pair. This is also intended to be a preliminary template for what trait-selection and projection will eventually look like.

I did some performance measurements. In the past, I observed a noticeable speedup (6%) for building rustc, but since I've rebased, the numbers appear to be more of a wash:

Crate Before After Percentage
syntax 167s 166s 0.6% faster
rustc 376s 382s 1.5% slower

Some advantages of this new scheme:

  • is_sized etc are proper queries
  • we get caching across generic fns, so long as trait environment is identical
  • dependency tracking is correct

@rust-highfive
Copy link
Collaborator

r? @eddyb

(rust_highfive has picked a reviewer for you, use r? to override)

@nikomatsakis
Copy link
Contributor Author

cc @arielb1

@@ -507,8 +507,6 @@ bitflags! {
// Caches for type_is_sized, type_moves_by_default
const SIZEDNESS_CACHED = 1 << 16,
const IS_SIZED = 1 << 17,
const MOVENESS_CACHED = 1 << 18,
const MOVES_BY_DEFAULT = 1 << 19,
Copy link
Member

Choose a reason for hiding this comment

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

Only two flags removed?

Copy link
Member

@Mark-Simulacrum Mark-Simulacrum left a comment

Choose a reason for hiding this comment

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

Just some minor nits, no need to bother if you don't want to.

let param_env = param_env.take().unwrap_or_else(|| {
global_tcx.empty_parameter_environment()
});
let param_env = param_env.take().unwrap_or_else(|| ParameterEnvironment::empty());
Copy link
Member

Choose a reason for hiding this comment

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

We could just use ty::ParameterEnvironment here and avoid adding the import.

Copy link
Member

Choose a reason for hiding this comment

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

Speaking of which, renaming it to ParamEnv might be a good idea?

Copy link
Contributor Author

@nikomatsakis nikomatsakis May 15, 2017

Choose a reason for hiding this comment

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

I always go back and forth on the importing question. I tend to prefer the import, so as to avoid having to write modules everywhere, and comply more closely with the Rust style guidelines (which suggest importing types, but not fns) -- but it does mean more merge conflicts around use declarations, which is annoying.

const FREEZENESS_CACHED = 1 << 20,
const IS_FREEZE = 1 << 21,
const NEEDS_DROP_CACHED = 1 << 22,
const NEEDS_DROP = 1 << 23,
}
Copy link
Member

Choose a reason for hiding this comment

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

I think this is now small enough to be a u16 instead of a u32 bitflags!

Copy link
Member

Choose a reason for hiding this comment

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

It was always wasteful, heh. And I think due to padding it ends up using a lot anyway.

}

pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
ty.is_freeze(self.tcx, &self.empty_param_env, DUMMY_SP)
ty.is_freeze(self.tcx, ParameterEnvironment::empty(), DUMMY_SP)
Copy link
Member

Choose a reason for hiding this comment

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

Minor, but we could avoid the additional import with ty::ParamEnv. I think this occurs elsewhere, too.

}
}

pub struct TyS<'tcx> {
pub sty: TypeVariants<'tcx>,
pub flags: Cell<TypeFlags>,
pub flags: TypeFlags,
Copy link
Member

Choose a reason for hiding this comment

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

😻

.enter(|infcx| traits::type_known_to_meet_bound(&infcx, ty, trait_def_id, DUMMY_SP))
}

fn is_sized_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Copy link
Member

Choose a reason for hiding this comment

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

I see you killed some of the shortcutting?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I figured it'd fall out from the caching anyway.

Copy link
Member

@eddyb eddyb left a comment

Choose a reason for hiding this comment

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

LGTM, modulo nits.

@nikomatsakis
Copy link
Contributor Author

ok, I made some style changes (s/ParameterEnvironment/ParamEnv/, removed imports) -- I haven't finished building this locally yet though :)

@@ -418,7 +418,7 @@ before, and hence the cache lookup would succeed, yielding
One subtle interaction is that the results of trait lookup will vary
depending on what where clauses are in scope. Therefore, we actually
have *two* caches, a local and a global cache. The local cache is
attached to the `ParameterEnvironment` and the global cache attached
attached to ParamEnv` and the global cache attached
Copy link
Member

Choose a reason for hiding this comment

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

This looks wrong, but is minor. Should ideally be "to the ParamEnv".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

@@ -16,7 +16,7 @@ use infer::InferCtxt;
use ich::{StableHashingContext, NodeIdHashingMode};
use traits::{self, Reveal};
use ty::{self, Ty, TyCtxt, TypeFoldable};
use ty::ParameterEnvironment;
use ty::ParamEnv;
Copy link
Member

Choose a reason for hiding this comment

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

This is again somewhat painful to me since we use both ty::ParamEnv and ParamEnv in this file. Don't bother fixing if you don't want to though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed.

@arielb1 arielb1 added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 16, 2017
@bors
Copy link
Contributor

bors commented May 18, 2017

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

@carols10cents carols10cents 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 May 22, 2017
@carols10cents
Copy link
Member

@nikomatsakis looks like this is back in your court now, friendly ping!

Ideally, we'd have the `Ty` inserted directly in the dep-node, but since
we can't do that yet, we extract the characteristic def-id of the type
in question.
@nikomatsakis
Copy link
Contributor Author

@bors r=eddyb

@bors
Copy link
Contributor

bors commented May 22, 2017

📌 Commit 83641a9 has been approved by eddyb

@bors
Copy link
Contributor

bors commented May 23, 2017

⌛ Testing commit 83641a9 with merge 9fa25a7...

bors added a commit that referenced this pull request May 23, 2017
remove interior mutability of type-flags

We were previously using the flags on `Ty<'tcx>` instances to do some ad-hoc caching schemes around things like `is_sized()`, `is_freeze()`, and `moves_by_default()`. This PR replaces those schemes with a proper query; the query key is based on the pair of a `(ParameterEnvironment<'tcx>, Ty<'tcx>)` pair. This is also intended to be a preliminary template for what trait-selection and projection will eventually look like.

I did some performance measurements. In the past, I observed a noticeable speedup (6%) for building rustc, but since I've rebased, the numbers appear to be more of a wash:

| Crate | Before | After | Percentage |
| --- | --- | --- | -- |
| syntax | 167s | 166s | 0.6% faster |
| rustc | 376s | 382s | 1.5% slower |

Some advantages of this new scheme:

- `is_sized` etc are proper queries
- we get caching across generic fns, so long as trait environment is identical
- dependency tracking is correct
@bors
Copy link
Contributor

bors commented May 23, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: eddyb
Pushing 9fa25a7 to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants