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 ADT information in an AdtDef structure in a unified way #27551

Merged
merged 14 commits into from Aug 7, 2015

Conversation

Projects
None yet
5 participants
@arielb1
Copy link
Contributor

arielb1 commented Aug 5, 2015

This ended up being a bigger refactoring than I thought, as I also cleaned a few ugly points in rustc. There are still a few areas that need improvements.

Performance numbers:

Before:
572.70user 5.52system 7:33.21elapsed 127%CPU (0avgtext+0avgdata 1173368maxresident)k
llvm-time: 385.858

After:
545.27user 5.49system 7:10.22elapsed 128%CPU (0avgtext+0avgdata 1145348maxresident)k
llvm-time: 387.119

A good 5% perf improvement. Note that after this patch >70% of the time is spent in LLVM - Amdahl's law is in full effect.

Passes make check locally.

r? @nikomatsakis

mk/main.mk Outdated
@@ -170,7 +170,6 @@ RUST_LIB_FLAGS_ST3 += -C prefer-dynamic

# Landing pads require a lot of codegen. We can get through bootstrapping faster
# by not emitting them.
RUSTFLAGS_STAGE0 += -Z no-landing-pads

This comment has been minimized.

@eefriedman

eefriedman Aug 6, 2015

Contributor

I assume this slipped in by accident?

This comment has been minimized.

@arielb1

arielb1 Aug 6, 2015

Author Contributor

yes

@arielb1 arielb1 force-pushed the arielb1:adt-def branch from cfd5878 to 5f0f53f Aug 6, 2015

@arielb1

This comment has been minimized.

Copy link
Contributor Author

arielb1 commented Aug 6, 2015

passes check locally

@arielb1 arielb1 force-pushed the arielb1:adt-def branch from 5f0f53f to 99c6bfd Aug 6, 2015

@arielb1 arielb1 force-pushed the arielb1:adt-def branch from 99c6bfd to c533f96 Aug 6, 2015

Ariel Ben-Yehuda
fix dropck overflow error message
Perf numbers:

Before this patchset:
572.70user 5.52system 7:33.21elapsed 127%CPU (0avgtext+0avgdata 1173368maxresident)k
llvm-time: 385.858

After this patch:
557.84user 5.73system 7:22.10elapsed 127%CPU (0avgtext+0avgdata 1142848maxresident)k
llvm-time: 385.834

nice 2.5% perf improvement

@arielb1 arielb1 force-pushed the arielb1:adt-def branch from b478196 to 1902973 Aug 6, 2015

Ariel Ben-Yehuda

@arielb1 arielb1 force-pushed the arielb1:adt-def branch from 1902973 to 0153001 Aug 6, 2015

@arielb1 arielb1 changed the title [WIP] store ADT information in an ADTDef structure in a unified way store ADT information in an ADTDef structure in a unified way Aug 6, 2015

@nikomatsakis

This comment has been minimized.

Why require that T: Copy? I guess because in a concurrency-oriented future, that would be handy?

This comment has been minimized.

Copy link

nikomatsakis replied Aug 6, 2015

If that is the case, we should add a comment justifying theT: Copy bound.

This comment has been minimized.

Copy link
Owner

arielb1 replied Aug 6, 2015

Because Cell requires T: Copy and I am too lazy to implement Cell myself.

@nikomatsakis

This comment has been minimized.

nit: move def.is_fundamental to the next line

@nikomatsakis

This comment has been minimized.

Copy link

nikomatsakis commented on src/librustc/middle/ty.rs in 764310e Aug 6, 2015

In general, these flags could use comments, but definitely is_dtorck and is_dtorck_valid

@nikomatsakis

This comment has been minimized.

Copy link

nikomatsakis commented on src/librustc/middle/ty.rs in 764310e Aug 6, 2015

Nit: I think Rust's precedent is to treat acronyms like other words. I'm sure we're inconsistent here and there, but Arc etc suggest so. Hence this should be AdtDef.

Less nit: Writing &'tcx AdtDef<'tcx> is tiresome and error-prone. We should at minimum follow the Ty precedent and make type AdtDef<'tcx> = &'tcx AdfDefData<'tcx>. I'd also personally be fine with a newtype (for both this and Ty).

@nikomatsakis

This comment has been minimized.

Copy link

nikomatsakis commented on src/librustc/middle/ty.rs in 764310e Aug 6, 2015

(a new type feels right to me because this constraint is more naturally enforced as part of the newtype, which signals "an interned AdtDefData")

This comment has been minimized.

Copy link
Owner

arielb1 replied Aug 6, 2015

it is not like there are any non-interned AdtDef-s anywhere.

This comment has been minimized.

Copy link
Owner

arielb1 replied Aug 6, 2015

The constructor is private, so you can't create them. It may be better to make the un-primed ADTDef (next commit) and friends newtypes.

This comment has been minimized.

Copy link

nikomatsakis replied Aug 6, 2015

The constructor is private, so you can't create them

right, seems fine. maybe just put that in the comment.

@arielb1

This comment has been minimized.

Copy link
Owner

arielb1 commented on src/librustc/middle/ty.rs in 4816e60 Aug 6, 2015

When reverse-variance goes away this should be split into an lookup_adt_def_mut (for collect, which needs this kind of access) and lookup_adt_def (for everyone else), hand-variancing.

This comment has been minimized.

Copy link

nikomatsakis replied Aug 6, 2015

Interesting. It might be worth retaining some sort of type that enables reverse-variance, but then again i'm not sure it carries its weight here. In particular we could also have an (unsafely implemented) method that downgrades from "write" to "read-only".

This comment has been minimized.

Copy link
Owner

arielb1 replied Aug 6, 2015

That's what I meant by "hand-variancing". I guess I will split the methods anyway.

@nikomatsakis

This comment has been minimized.

Copy link

nikomatsakis commented on src/librustc/middle/ty.rs in 213b6d7 Aug 6, 2015

is this sentence incomplete? it'd be nice to have some documentation of where it is important to have variance here

This comment has been minimized.

Copy link
Owner

arielb1 replied Aug 6, 2015

merge damage I imagine

@nikomatsakis

This comment has been minimized.

Copy link

nikomatsakis commented on src/librustc/middle/ty.rs in 213b6d7 Aug 6, 2015

If the major problem here is that we want Ty<'q> to be variant w/r/t 'q, perhaps it would be better to just have ty_struct continue to embed a DefId, rather than embedding a reference to the AdtDef?

OTOH, the trick you've worked out here is pretty clever. It does seem like it's nice to be able to have a "read-only" alias that is variant, and I guess that the lifetime games you are playing here make that possible.

/me ponders

This comment has been minimized.

Copy link

nikomatsakis replied Aug 6, 2015

OK, having reconsidered, I think this is a cool pattern you've got here, but we perhaps just need a clearer elucidation of what it's aiming to do, along with some nicer type aliases. For example:

/// A read-only reference to an ADT definition. References
/// of this type can query the state of an ivar, but not mutate it.
type AdtDef<'tcx> =  &'tcx AdtDefData<'tcx, 'static>;

/// A mutable reference to an ADT definition. This is what we
/// store in the tcx tables. In particular, this form
/// permits the IVars to be fulfilled. Note that, unlike with
/// `&mut` references, there may be extant read-only aliases
/// when the ivar is fulfilled.
type AdtDefMut<'tcx> = &'tcx AdtDefData<'tcx, 'tcx>;

This comment has been minimized.

Copy link
Owner

arielb1 replied Aug 6, 2015

Having AdtDef<'tcx> be &'tcx AdtDef<'tcx,'tcx> is certainly nice. AdtDef_ is used basically nowhere (once in the tcx, once in decoder, once in collect), I'm not sure it should be behind a type alias. Also, this isn't really Mut - you can still fulfill an AdtDef<'tcx> with a Ty<'static>.

@nikomatsakis

This comment has been minimized.

Copy link

nikomatsakis commented on src/librustc/middle/ty.rs in 213b6d7 Aug 6, 2015

I feel like we should find a more meaningful name than 'lt -- though it's tricky because it's sort of abstract. 'writer is sort of...ok, not a precise match with anything, but at least suggestive of the role of 'lt.

This comment has been minimized.

Copy link

nikomatsakis replied Aug 6, 2015

Also I'd prefer a name like AdtDefData to AdtDef_

This comment has been minimized.

Copy link
Owner

arielb1 replied Aug 6, 2015

ADTDef/ADTDef_ was the variance distinction. I guess I could go AdtDefData/AdtDef. Maybe call the lifetime `'owner' - this is essentially about preventing types from a child tcx from leaking into the parent tcx.

@nikomatsakis

This comment has been minimized.

Copy link

nikomatsakis commented on src/librustc/metadata/decoder.rs in 4816e60 Aug 6, 2015

nit: can you replace skip_binder with a call to no_late_bound_regions and unwrap? I believe that is correctly because the tuple signature should have no LBR.

This comment has been minimized.

Copy link
Owner

arielb1 replied Aug 6, 2015

I copied somewhere that did .0 (you can't believe how many places do this). I match on the binder in several places - maybe I'll add a tuple_ctor_to_type function.

@nikomatsakis

This comment has been minimized.

Copy link

nikomatsakis commented on src/librustc/middle/ty.rs in 4816e60 Aug 6, 2015

nice, I'm usually too lazy and just return a Vec :)

@nikomatsakis

This comment has been minimized.

Copy link

nikomatsakis commented on 612760b Aug 6, 2015

the commit message here suggests that changing how we issue this note causes a 2.5% perf improvement. How is that possible, given that this code only executes in error cases? What are you testing?

This comment has been minimized.

Copy link
Owner

arielb1 replied Aug 6, 2015

that's for the entire patchset up to this point (I wanted to separate it from Ty::is_simd).

@nikomatsakis

This comment has been minimized.

Copy link

nikomatsakis commented on src/librustc/middle/ty.rs in 764310e Aug 6, 2015

It'd be nice to move this code out of this file and (ideally) into dropck. Perhaps just have the code that uses the "is_dtorck" flag stuff elsewhere. Or maintain the flag a bit differently. Or use some external sets. I don't know. Not a huge thing, but I do feel like this kind of random code is best kept with the code that is consuming it (in general ty.rs has more stuff in it that I'd like).

This comment has been minimized.

Copy link

nikomatsakis replied Aug 6, 2015

I guess though that under RFC rust-lang/rfcs#1238 this just becomes an attribute check anyhow.

This comment has been minimized.

Copy link
Owner

arielb1 replied Aug 6, 2015

dropck was somewhat an hotspot on my profile. We really should split up ty someday, through.

@nikomatsakis

This comment has been minimized.

Copy link

nikomatsakis commented on src/librustc/middle/ty.rs in 764310e Aug 6, 2015

eventually, this "destructor_for_type" thing should go into AdtDef, right?

This comment has been minimized.

Copy link

nikomatsakis replied Aug 6, 2015

to clarify: not necessarily as part of this PR

This comment has been minimized.

Copy link
Owner

arielb1 replied Aug 6, 2015

Right. This PR is already somewhat too big to my taste.

@arielb1

This comment has been minimized.

Copy link
Owner

arielb1 commented on src/librustc_typeck/collect.rs in 4816e60 Aug 6, 2015

NOTE: this is commented to prevent duplicate error messages, and is uncommented in a later commit.

@Aatch

This comment has been minimized.

Copy link
Contributor

Aatch commented Aug 7, 2015

Awesome, I'm glad somebody did this. The performance increase is consistent with what I saw with my version of this change. Hopefully this should also make working with ADTs easier going forward, at the very least it's much more obvious.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 7, 2015

@arielb1

I copied somewhere that did .0 (you can't believe how many places do this). I match on the binder in several places - maybe I'll add a tuple_ctor_to_type function.

Oh, I can believe it, since I wrote them, but I've been migrating code to the following conventions:

  1. Either use a proper function (like no_late_bound_regions) or,
  2. If you call skip_binder, add a comment explaining why it makes sense in this particular case.
@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 7, 2015

@arielb1

Having AdtDef<'tcx> be &'tcx AdtDef<'tcx,'tcx> is certainly nice. AdtDef_ is used basically nowhere (once in the tcx, once in decoder, once in collect), I'm not sure it should be behind a type alias. Also, this isn't really Mut - you can still fulfill an AdtDef<'tcx> with a Ty<'static>.

While technically true, that's not particularly interesting, is it? The intention of these types is as I wrote them, no? I'm fine if you want to note that caveat in a comment, but I still favor names that lay clear the intent of "read-only" vs "mutable", as this is a subtle trick.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 7, 2015

@arielb1

dropck was somewhat an hotspot on my profile.

How is this relevant? I'm talking about what module the code is in, not what it does.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 7, 2015

@Aatch

that's for the entire patchset up to this point (I wanted to separate it from Ty::is_simd).

ah, ok, sounds good.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 7, 2015

cc @rust-lang/compiler <-- this PR is worth having more eyes on, incidentally

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 7, 2015

OK, I've finished reading through the PR. I am happy with it, this is nice work.

r+ modulo:

  • rename AdtDef_ to AdtDefData or AdtDefStruct or something similar with a word, not an underscore
  • readable type aliases for the (mostly) "read-only" &'tcx AdtDefData<'tcx,'static> and the mutable &'tcx AdtDefData<'tcx,'tcx>. Personally, I think it's worth giving both of them an alias because it makes the pattern clearer, even if the latter gets little use.
  • remove or at minimum document calls to skip_binder
  • explain where the T: Copy bound comes from (lets us use Cell; since we store &T it's fine; could be lifted in the future but would require more unsafe code). I was thinking that it mattered for concurrency but of course I was being silly: the whole POINT of an ivar is that it's write-once, and hence you can clone the contents without fear of them being overwritten, after all.
@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 7, 2015

ps, if you prefer, perhaps the name AdtDefTcx or something would be a compromise vs AdtDefMut ("fulfillable with a Ty<'tcx>")

@arielb1

This comment has been minimized.

Copy link
Contributor Author

arielb1 commented Aug 7, 2015

addressed

Ariel Ben-Yehuda

@arielb1 arielb1 force-pushed the arielb1:adt-def branch from 29970b6 to eedb1cc Aug 7, 2015

@nikomatsakis

This comment has been minimized.

Copy link

nikomatsakis commented on src/librustc/metadata/decoder.rs in 62cd3cc Aug 7, 2015

Note: this still skips the binder :) it just does so in the implicit way I would eventually like to remove altogether (by making the 0 field private). But there is a comment and assert so...good enough.

@arielb1 arielb1 changed the title store ADT information in an ADTDef structure in a unified way store ADT information in an AdtDef structure in a unified way Aug 7, 2015

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Aug 7, 2015

@bors r+

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Aug 7, 2015

📌 Commit eedb1cc has been approved by nikomatsakis

bors added a commit that referenced this pull request Aug 7, 2015

Auto merge of #27551 - arielb1:adt-def, r=nikomatsakis
This ended up being a bigger refactoring than I thought, as I also cleaned a few ugly points in rustc. There are still a few areas that need improvements.

Performance numbers:
```
Before:
572.70user 5.52system 7:33.21elapsed 127%CPU (0avgtext+0avgdata 1173368maxresident)k
llvm-time: 385.858

After:
545.27user 5.49system 7:10.22elapsed 128%CPU (0avgtext+0avgdata 1145348maxresident)k
llvm-time: 387.119
```

A good 5% perf improvement. Note that after this patch >70% of the time is spent in LLVM - Amdahl's law is in full effect.

Passes make check locally.

r? @nikomatsakis
@bors

This comment has been minimized.

Copy link
Contributor

bors commented Aug 7, 2015

⌛️ Testing commit eedb1cc with merge ab77c1d...

@bors bors merged commit eedb1cc into rust-lang:master Aug 7, 2015

2 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.