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

enable mir inlining across trait methods #44389

Closed
nikomatsakis opened this issue Sep 7, 2017 · 2 comments
Closed

enable mir inlining across trait methods #44389

nikomatsakis opened this issue Sep 7, 2017 · 2 comments
Labels
A-codegen Area: Code generation A-mir Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Sep 7, 2017

As the fix to #40473, @qmx disabled MIR inlining of trait calls altogether. This issue tracks the task of re-enabling the inlining, where possible! This is a slightly more involved task.

Here is the example text:

pub trait Foo {
    fn bar(&self) {}
}

impl Foo for () {
    fn bar(&self) { println!("Hello, World!"); }
}

pub fn main() {
    ().bar();
}

The goal would be to have the call to bar() inlined. But we should draw up some more interesting tasks showing edge-cases: for example, generic functions and so forth (we should be able to use RevealMode::All to "see through" specialization, since inlining executes quite late).

I think roughly speaking the steps to solve this issue "properly" are to:

  • Refactor Instance and InstanceDef out of librustc_trans and (probably) into librustc
  • Rework inlining to use those mechanisms to resolve method calls (including trait ones)
@nikomatsakis nikomatsakis added A-codegen Area: Code generation A-mir Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 7, 2017
@nikomatsakis
Copy link
Contributor Author

nikomatsakis commented Sep 7, 2017

Some notes:

First, this code in the lints does more or less what is needed already (in particular, this match arm is the case where we are able to find a particular impl).

Second, the code in trans is reasonable, but assumes that things are monomorphized (otherwise it has to return an Option, to start). The heart of that code, in any case, is the call to the helper function trans_fulfill_obligation(), which actually lives in librustc already.

To be quite honest i'm not entirely sure what the "right abstraction" looks like here. It's not clear to me that using Instance in this particular case would add a lot of value at this point in time -- but I suppose that, longer term, it might be a stepping stone to letting us generalize the inlining code even further, so that it can (e.g.) inline bits of drop glue or other things that are not user-defined functions.

I also know that we've talked for some time about migrating some of the "trans" logic out of librustc_trans, since things like miri etc -- not to mention other potential optimizations and backends -- will want to make use of it. I know that @eddyb had some thoughts -- perhaps he can leave some notes as to what he would like to see!

@eddyb
Copy link
Member

eddyb commented Sep 7, 2017

This is the true entrypoint:

pub fn resolve<'a, 'tcx>(

This should be in librustc and everyone should use it. That's pretty much it.
There's enough functionality in there to work without monomorphization, including taking specialization into account to not resolve more aggressively than it's sound to, it just has to return Option/Result like @nikomatsakis mentioned, instead of panicking.

@TimNN TimNN added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Sep 17, 2017
bors added a commit that referenced this issue Oct 3, 2017
Move monomorphize::resolve() to librustc

this moves `monomorphize::resolve(..)` to librustc, and re-enables inlining for some trait methods, fixing #44389

@nikomatsakis I've kept the calls to the new `ty::Instance::resolve(....)` always `.unwrap()`-ing for the moment, how/do you want to add more debugging info via `.unwrap_or()` or something like this?

we still have some related `resolve_*` functions on monomorphize, but I wasn't sure moving them was into the scope for this PR too.

@eddyb mind to take a look too?
@bors bors closed this as completed in 3bd09de Oct 3, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation A-mir Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants