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

Add forever unstable attribute to allow specifying arbitrary scalar ranges #54032

Merged
merged 15 commits into from
Sep 14, 2018

Conversation

oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Sep 7, 2018

r? @eddyb for the first commit and @nikomatsakis for the second one

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 7, 2018
@@ -161,8 +161,7 @@ pub struct BlockRemainder {

newtype_index!(FirstStatementIndex
{
pub idx
MAX = SCOPE_DATA_REMAINDER_MAX
MAX = 0xFFFF_FFFB // the remainder of the scope data
Copy link
Member

Choose a reason for hiding this comment

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

Can we do something less magic-value like than this? 0xFFFF_FFFB is two steps away from the values in SCOPE_DATA_*. Changing the definition of SCOPE_DATA_* to be 0xFFFF_FFFE, ... 0xFFFF_FFFD would help somewhat, if it is not possible to use arithmetic in the attribute.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SCOPE_DATA_DESTRUCTION is 0xFFFF_FFFC, so this is exactly next to it.

Attributes currently only allow literals, no expressions. Though referring to constants might work via queries, there's currently no support for that.

@rust-highfive

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@bors

This comment has been minimized.

const SCOPE_DATA_CALLSITE: u32 = 0xFFFF_FFFE;
const SCOPE_DATA_ARGUMENTS: u32 = 0xFFFF_FFFD;
const SCOPE_DATA_DESTRUCTION: u32 = 0xFFFF_FFFC;
// be sure to add the MAX of FirstStatementIndex if you add more constants here
Copy link
Member

@eddyb eddyb Sep 8, 2018

Choose a reason for hiding this comment

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

Why isn't this done by having an enum with 4 unit variants and a tuple variant around FirstStatementIndex?

@@ -1083,6 +1083,29 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
interned
}

/// Returns a range of the start/end indices specified with the `rustc_layout_scalar_range`
/// attribute. Missing range ends may be denoted by `None` and will just use the max/min of
/// the type.
Copy link
Member

Choose a reason for hiding this comment

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

You can use the RangeBound enum from libstd instead of Option here.

@eddyb
Copy link
Member

eddyb commented Sep 8, 2018

@oli-obk I think the name should have valid_range in it, "scalar" is not enough IMO.

@oli-obk oli-obk force-pushed the layout_scalar_ranges branch from 7e185fc to 95987d0 Compare September 10, 2018 12:40
@oli-obk oli-obk force-pushed the layout_scalar_ranges branch from 2285e76 to 8053f63 Compare September 11, 2018 10:07
#[allow(dead_code)]
// only works on stage 1 when the rustc_layout_scalar_valid_range attribute actually exists
#[cfg(not(stage0))]
static ASSERT: () = [()][(mem::size_of::<ScopeData>() != 4) as usize];
Copy link
Member

Choose a reason for hiding this comment

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

I would put ! around the expression and use == instead of !=. That way, it reads more like an assert.

@@ -82,7 +83,8 @@ macro_rules! newtype_index {
newtype_index!(
// Leave out derives marker so we can use its absence to ensure it comes first
@type [$name]
@max [::std::u32::MAX - 1]
// shave off 256 indices at the end to allow space for packing these indices into enums
@max [0xFFFF_FF00]
Copy link
Member

Choose a reason for hiding this comment

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

Ohhhh, this is clever!

@@ -0,0 +1,5 @@
// compile-pass

static ASSERT: () = [()][(std::mem::size_of::<u32>() != 4) as usize];
Copy link
Member

Choose a reason for hiding this comment

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

I'd make the same change here (! around ==).

@rust-highfive

This comment has been minimized.

@eddyb

This comment has been minimized.

@oli-obk
Copy link
Contributor Author

oli-obk commented Sep 11, 2018

Ups forgot to push. Stage 2 tests are passing locally now.

@oli-obk
Copy link
Contributor Author

oli-obk commented Sep 11, 2018

I'm presuming

@bors r=eddyb

since all review comments have been addressed

@bors
Copy link
Contributor

bors commented Sep 11, 2018

📌 Commit 79f2cc0 has been approved by eddyb

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 11, 2018
@rust-highfive

This comment has been minimized.

ScopeData::Destruction => write!(fmt, "Destruction({:?})", self.id),
ScopeData::Remainder(fsi) => write!(
fmt,
"Remainder {{ block: {:?}, first_statement_index: {}}}",
Copy link
Member

Choose a reason for hiding this comment

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

You probably want to use the fmt.debug_struct wrapper, to automate this.

@eddyb
Copy link
Member

eddyb commented Sep 11, 2018

@bors r+

@bors
Copy link
Contributor

bors commented Sep 11, 2018

📌 Commit a94c166 has been approved by eddyb

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

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

OK, I was wrong. This is awesome! Nice work @oli-obk! 🎉

@bors
Copy link
Contributor

bors commented Sep 14, 2018

⌛ Testing commit a94c166 with merge dfabe4b...

bors added a commit that referenced this pull request Sep 14, 2018
Add forever unstable attribute to allow specifying arbitrary scalar ranges

r? @eddyb for the first commit and @nikomatsakis for the second one
@bors
Copy link
Contributor

bors commented Sep 14, 2018

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

@bors bors merged commit a94c166 into rust-lang:master Sep 14, 2018
bors added a commit that referenced this pull request Sep 17, 2018
Make rustc::middle::region::Scope's fields public

This PR makes the following changes to `rustc::middle::region::Scope`:

- [x] Makes `region::Scope`'s fields public
- [x] Removes the `impl Scope` block with constructors (as per [this comment](#54032 (comment)))
- [x] Updates call sites throughout the compiler

Closes #54122.
@nnethercote
Copy link
Contributor

@oli-obk
Copy link
Contributor Author

oli-obk commented Sep 22, 2018

Previously the unpacking was done manually. Now ruatc generates the relevant enum matching code. Maybe it's not as optimizeable?

@nnethercote
Copy link
Contributor

@oli-obk: Here is a Cachegrind diff comparing instruction counts before vs. after. Positive numbers means the instruction counts went up, negative numbers mean they went down.

 9,254,752  /home/njn/moz/rustN/src/librustc/hir/def_id.rs:<rustc::ty::Predicate<'tcx> as core::cmp::PartialEq>::eq
 9,105,881  /home/njn/moz/rustN/src/libcore/cell.rs:rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
 6,810,037  /home/njn/moz/rustN/src/librustc/ty/mod.rs:<rustc::ty::Predicate<'tcx> as core::hash::Hash>::hash
 5,633,067  /home/njn/moz/rustN/src/librustc/hir/def_id.rs:rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
 5,153,016  /home/njn/moz/rustN/src/librustc/hir/def_id.rs:rustc::traits::select::SelectionContext::assemble_candidates
 4,295,696  /home/njn/moz/rustN/src/librustc/hir/def_id.rs:<rustc::ty::Predicate<'tcx> as core::hash::Hash>::hash
 4,130,136  /home/njn/moz/rustN/src/librustc/hir/def_id.rs:<rustc::ty::sty::TyKind<'tcx> as core::cmp::PartialEq>::eq
 3,785,310  /home/njn/moz/rustN/src/libcore/num/mod.rs:<rustc_data_structures::snapshot_map::SnapshotMap<K, V>>::get
-3,703,491  /home/njn/moz/rustN/src/librustc/ty/query/plumbing.rs:rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
 2,583,451  /home/njn/moz/rustN/src/libcore/num/mod.rs:<rustc::ty::Predicate<'tcx> as core::hash::Hash>::hash
 2,396,730  /home/njn/moz/rustN/src/librustc_data_structures/snapshot_map/mod.rs:<rustc_data_structures::snapshot_map::SnapshotMap<K, V>>::get
-2,392,645  /home/njn/moz/rustN/src/libcore/num/mod.rs:rustc::traits::project::opt_normalize_projection_type
 2,151,640  /home/njn/moz/rustN/src/librustc/hir/def_id.rs:<rustc_data_structures::snapshot_map::SnapshotMap<K, V>>::get
 2,056,569  /home/njn/moz/rustN/src/librustc/hir/def_id.rs:rustc::infer::higher_ranked::<impl rustc::infer::combine::CombineFields<'a, 'gcx, 'tcx>>::higher_ranked_sub::{{closure}}
 2,056,161  /home/njn/moz/rustN/src/libstd/collections/hash/table.rs:<rustc_data_structures::snapshot_map::SnapshotMap<K, V>>::get
-2,041,430  /home/njn/moz/rustN/src/libcore/hash/mod.rs:<rustc::ty::Predicate<'tcx> as core::hash::Hash>::hash
-1,794,496  /home/njn/moz/rustN/src/libstd/collections/hash/table.rs:rustc::traits::project::opt_normalize_projection_type
 1,677,995  /home/njn/moz/rustN/src/libcore/ptr.rs:<rustc_data_structures::snapshot_map::SnapshotMap<K, V>>::get
-1,630,473  /home/njn/moz/rustN/src/libstd/collections/hash/map.rs:rustc::traits::project::opt_normalize_projection_type
 1,597,264  /home/njn/moz/rustN/src/libstd/collections/hash/map.rs:<rustc_data_structures::snapshot_map::SnapshotMap<K, V>>::get
 1,564,224  /home/njn/moz/rustN/src/librustc/middle/region.rs:rustc::middle::region::ScopeTree::temporary_scope
 1,544,676  /home/njn/moz/rustN/src/libstd/collections/hash/table.rs:rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
 1,528,640  /home/njn/moz/rustN/src/libstd/collections/hash/map.rs:rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
 1,381,946  /home/njn/moz/rustN/src/librustc/hir/def_id.rs:rustc::middle::lang_items::LanguageItems::fn_trait_kind
 1,278,687  /home/njn/moz/rustN/src/librustc/middle/region.rs:rustc::middle::region::ScopeTree::opt_encl_scope
 1,228,759  /home/njn/moz/rustN/src/librustc/traits/project.rs:rustc::traits::project::opt_normalize_projection_type
 1,173,536  /home/njn/moz/rustN/src/librustc/hir/mod.rs:<rustc::ty::sty::TyKind<'tcx> as core::hash::Hash>::hash
 1,136,358  /home/njn/.cargo/registry/src/suiyiyu.us.kg-1ecc6299db9ec823/rustc-hash-1.0.1/src/lib.rs:<rustc::ty::Predicate<'tcx> as core::hash::Hash>::hash
 1,022,004  /home/njn/moz/rustN/src/libstd/collections/hash/table.rs:rustc::middle::region::ScopeTree::opt_encl_scope

Any more thoughts about how to fix the regression?

@oli-obk oli-obk deleted the layout_scalar_ranges branch October 1, 2018 11:56
@oli-obk
Copy link
Contributor Author

oli-obk commented Oct 1, 2018

I'll create some artificial benchmarks to try to repro the issue in isolation. Without knowing which case exactly is slow/verbose and we'd be poking in the dark.

@oli-obk
Copy link
Contributor Author

oli-obk commented Oct 13, 2018

I think I know the reason for this now. I changed e.g.

const FOO_A: u32 = 0xFFFF_FFFF;
const FOO_B: u32 = 0xFFFF_FFFE;
struct Foo { u: u32 }

https://play.rust-lang.org/?gist=639deede27237c3913e57ac4181f42bf&version=nightly&mode=debug&edition=2015

to

#[rustc_layout_scalar_range_end(0xFFFF_FF00)]
struct Bar(u32);
enum Foo {
    A,
    B,
    Other(Bar),
}

https://play.rust-lang.org/?gist=639deede27237c3913e57ac4181f42bf&version=nightly&mode=debug&edition=2015

While this will result in pretty much the same layout as before, any derived code on Foo will now generate less optimal code. Apparently llvm can't manage to clean that up.

The llvm IR for the second playground link is ca 150 LOC, the first link has 50 LOC

I'm opening an issue for this problem, since I can also create an example on stable code (without the unstable attribute) that will result in the same lack of optimitations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants