Skip to content

Copy trait defeats generator optimization #62952

Open
@tmandry

Description

@tmandry

The following example (playground):

#![feature(generators, generator_trait)]

use std::ops::Generator;

#[derive(Clone)]
struct Foo([u8; 1024]);

fn overlap_foo() -> impl Generator<Yield = (), Return = ()>{
    static || {
        let x = Foo([0u8; 1024]);
        yield;
        drop(x);
        let y = Foo([0u8; 1024]);
        yield;
        drop(y);
    }
}

#[derive(Clone, Copy)]
struct Bar([u8; 1024]);

fn overlap_bar() -> impl Generator<Yield = (), Return = ()>{
    static || {
        let x = Bar([0u8; 1024]);
        yield;
        drop(x);
        let y = Bar([0u8; 1024]);
        yield;
        drop(y);
    }
}

fn main() {
    dbg!(std::mem::size_of_val(&overlap_foo()));
    dbg!(std::mem::size_of_val(&overlap_bar()));
}

Outputs:

[gen-explicit-drop.rs:34] std::mem::size_of_val(&overlap_foo()) = 1028                                                                                                                                                                                                                                                       
[gen-explicit-drop.rs:35] std::mem::size_of_val(&overlap_bar()) = 2052  

The only difference between Foo and Bar is that Foo is Copy. This defeats the generator optimization implemented in #61922 which considers any local that has been moved from as a candidate for overlap.

Technically, this is semantically consistent with the existing overlap behavior for generators. But making a type Copy and getting worse performance is a footgun that we should fix.

This can be fixed with a pass that turns unnecessary copies into moves in MIR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-coroutinesArea: CoroutinesC-enhancementCategory: An issue proposing an enhancement or a PR with one.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-heavyIssue: Problems and improvements with respect to binary size of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions