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

Only break critical edges where actually needed #33544

Merged
merged 1 commit into from
May 14, 2016

Commits on May 11, 2016

  1. Only break critical edges where actually needed

    Currently, to prepare for MIR trans, we break _all_ critical edges,
    although we only actually need to do this for edges originating from a
    call that gets translated to an invoke instruction in LLVM.
    
    This has the unfortunate effect of undoing a bunch of the things that
    SimplifyCfg has done. A particularly bad case arises when you have a
    C-like enum with N variants and a derived PartialEq implementation.
    
    In that case, the match on the (&lhs, &rhs) tuple gets translated into
    nested matches with N arms each and a basic block each, resulting in N²
    basic blocks. SimplifyCfg reduces that to roughly 2*N basic blocks, but
    breaking the critical edges means that we go back to N².
    
    In nickel.rs, there is such an enum with roughly N=800. So we get about
    640K basic blocks or 2.5M lines of LLVM IR. LLVM takes a while to
    reduce that to the final "disr_a == disr_b".
    
    So before this patch, we had 2.5M lines of IR with 640K basic blocks,
    which took about about 3.6s in LLVM to get optimized and translated.
    After this patch, we get about 650K lines with about 1.6K basic blocks
    and spent a little less than 0.2s in LLVM.
    
    cc rust-lang#33111
    dotdash committed May 11, 2016
    Configuration menu
    Copy the full SHA
    00f6513 View commit details
    Browse the repository at this point in the history