• Dmitry Vyukov's avatar
    cmd/gc: transform closure calls to function calls · c4ee44b7
    Dmitry Vyukov authored
    Currently we always create context objects for closures that capture variables.
    However, it is completely unnecessary for direct calls of closures
    (whether it is func()(), defer func()() or go func()()).
    This change transforms any OCALLFUNC(OCLOSURE) to normal function call.
    Closed variables become function arguments.
    This transformation is especially beneficial for go func(),
    because we do not need to allocate context object on heap.
    But it makes direct closure calls a bit faster as well (see BenchmarkClosureCall).
    
    On implementation level it required to introduce yet another compiler pass.
    However, the pass iterates only over xtop, so it should not be an issue.
    Transformation consists of two parts: closure transformation and call site
    transformation. We can't run these parts on different sides of escape analysis,
    because tree state is inconsistent. We can do both parts during typecheck,
    we don't know how to capture variables and don't have call site.
    We can't do both parts during walk of OCALLFUNC, because we can walk
    OCLOSURE body earlier.
    So now capturevars pass only decides how to capture variables
    (this info is required for escape analysis). New transformclosure
    pass, that runs just before order/walk, does all transformations
    of a closure. And later walk of OCALLFUNC(OCLOSURE) transforms call site.
    
    benchmark                            old ns/op     new ns/op     delta
    BenchmarkClosureCall                 4.89          3.09          -36.81%
    BenchmarkCreateGoroutinesCapture     1634          1294          -20.81%
    
    benchmark                            old allocs     new allocs     delta
    BenchmarkCreateGoroutinesCapture     6              2              -66.67%
    
    benchmark                            old bytes     new bytes     delta
    BenchmarkCreateGoroutinesCapture     176           48            -72.73%
    
    Change-Id: Ic85e1706e18c3235cc45b3c0c031a9c1cdb7a40e
    Reviewed-on: https://go-review.googlesource.com/4050Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
    c4ee44b7
bug346.go 743 Bytes