Skip to content

Inline generators before state machine conversion in order to reduce branching #83101

Open
@pcwalton

Description

@pcwalton

As of 6c51ec9, which is the fix for #76181, generators no longer inline in MIR. This results in missing the following optimization opportunity:

pub async fn f() {
    foo().await;
    g().await;
}

async fn g() {
    bar().await;
    h().await;
}

async fn h() {
    baz();
}

should become:

async fn f() {
    foo().await;
    bar().await;
    baz().await;
}

I checked a simple example and LLVM didn't seem to do the inlining, which doesn't surprise me as after the state machine transformation it's going to be quite hard to perform it.

This could be an important optimization because recreating the nested call stack when a generator is resumed can be O(n) in bad cases like this one. (This was brought up as a potential problem when comparing C++ coroutines with Rust generators.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-coroutinesArea: CoroutinesA-mir-optArea: MIR optimizationsC-enhancementCategory: An issue proposing an enhancement or a PR with one.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-slowIssue: Problems and improvements with respect to performance of generated code.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions