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

[MIR] Deaggregate structs to enable further optimizations #35168

Merged
merged 6 commits into from
Aug 4, 2016

Conversation

scottcarr
Copy link
Contributor

Currently, we generate MIR like:

tmp0 = ...;
tmp1 = ...;
tmp3 = Foo { a: ..., b: ... };

This PR implements "deaggregation," i.e.:

tmp3.0 = ...
tmp3.1 = ...

Currently, the code only deaggregates structs, not enums. My understanding is that we do not have MIR to set the discriminant of an enum.

@rust-highfive
Copy link
Collaborator

r? @nrc

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

@scottcarr
Copy link
Contributor Author

r? @nikomatsakis

let node_path = tcx.item_path_str(tcx.map.local_def_id(node_id));
debug!("running on: {:?}", node_path);
// we only run when mir_opt_level > 1
match tcx.sess.opts.debugging_opts.mir_opt_level {
Copy link
Member

@nagisa nagisa Aug 1, 2016

Choose a reason for hiding this comment

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

I’d suggest adding a Pass::should_run(stuff) -> bool. We previously had no use-case for such a method, which is why it does not exist currently, but somebody (…ehem, me…) foresaw such use case and left a useful comment.

@scottcarr scottcarr force-pushed the deaggregation branch 2 times, most recently from 392ce66 to 62cdbea Compare August 1, 2016 22:57
@scottcarr
Copy link
Contributor Author

Thanks @nagisa. I took out the O(n^2) cases. For should_run I didn't implement it, but it probably does make some sense for passes to not enable/disable themselves.

None => { return; },
_ => {}
};
if let MirSource::Fn(_) = source {} else { return; }
Copy link
Contributor

Choose a reason for hiding this comment

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

can you leave a comment as to why we do this if -- iirc, otherwise this triggers in constants. Seems like this may be just a temporary limitation, if we improve our constant handling a la miri.

@nikomatsakis
Copy link
Contributor

OK, so I left some nits, but it seems good other than those. r=me when the nits are addressed.

One other question: can you test this using your MIR optimization testing code?

@scottcarr
Copy link
Contributor Author

scottcarr commented Aug 2, 2016

I think I'd prefer to open a FIXME issue

I created issue #35186

// } else {
// lhs_cast
// };
// FIXME we cannot deaggregate enums issue: 35186
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: "#35186" makes for easier searching, I think

@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Aug 2, 2016

📌 Commit d918c99 has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented Aug 2, 2016

⌛ Testing commit d918c99 with merge 9478922...

@bors
Copy link
Contributor

bors commented Aug 2, 2016

💔 Test failed - auto-win-msvc-64-opt-no-mir

@alexcrichton
Copy link
Member

@arielb1
Copy link
Contributor

arielb1 commented Aug 3, 2016

I am worried that this may be a pessimization for newtype structs, because it forces them to memory.

@eddyb
Copy link
Member

eddyb commented Aug 3, 2016

@arielb1 Pair is probably more affected by this atm (as it gets non-memory field access).
However, I think the solution here will involve a combination of newtype unpacking and MIR SROA.

@arielb1
Copy link
Contributor

arielb1 commented Aug 3, 2016

The problem is that an SSA-value pair/newtype constructor is a no-op at the LLVM level, while a inner-field write, like tmp0.0 = Foo; call Bar(tmp0); is more complicated to handle.

However, that looks like a complication that can be handled at the MIR trans level.

@scottcarr
Copy link
Contributor Author

It seems to me that we could imagine cases where we don't want to deaggregate, but its not completely clear what those are or if they would be handled by the deaggregator or MIR trans. I opened an issue #35259 to discuss this.

@nikomatsakis
Copy link
Contributor

Given that this won't even be enabled anyway, seems like we can continu to hack on the "when to trigger it" heuristics, so I won't have that block landing!

@bors r+

@bors
Copy link
Contributor

bors commented Aug 3, 2016

📌 Commit 06acf16 has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented Aug 4, 2016

⌛ Testing commit 06acf16 with merge e804a3c...

bors added a commit that referenced this pull request Aug 4, 2016
[MIR] Deaggregate structs to enable further optimizations

Currently, we generate MIR like:

```
tmp0 = ...;
tmp1 = ...;
tmp3 = Foo { a: ..., b: ... };
```

This PR implements "deaggregation," i.e.:

```
tmp3.0 = ...
tmp3.1 = ...
```

Currently, the code only deaggregates structs, not enums.  My understanding is that we do not have MIR to set the discriminant of an enum.
@bors bors merged commit 06acf16 into rust-lang:master Aug 4, 2016
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.

9 participants