• Leszek Swirski's avatar
    [maglev] Fix lifetime extension of generator values · dd6fa2d1
    Leszek Swirski authored
    Loop used value lifetimes extension extends the lifetime of anything
    used inside of a loop but defined outside of it, to make sure that it is
    considered 'live' for the entire body of the loop (this is so that we
    don't e.g. clobber their stack slots with stack slot reuse).
    
    The implementation works on the principle that a) basic blocks are
    topologically sorted by forward control flow, and b) loops are
    irreducible. This means that basic blocks between a loop header and the
    jump to that loop header are inside the loop, and nodes whose id
    preceeds the loop header's id must be before the loop.
    
    Generator resumes break this irreducibility by jumping into the middle
    of loops. This is principally not a problem for the above lifetime
    extension, it just means that the loop's used nodes will overapproximate
    and include these generator nodes. However, there was an implicit
    additional assumption that the node must be loadable by the loop end, to
    extend its lifetime. This fails for the generator resume case, because
    it's possible that the node didn't make it into any loop merge state,
    e.g. because the resume would immediately deopt or return, e.g.
    
                     Start
                     /   \
                    /   GeneratorResume
                    |         |
                    v         |
               .>Loop header  |
              |     |         |
              |   Branch      |
              |   |    |      |
              |   |  Suspend  |
              |   |           |
              |   |  Resume <-'
              |   |    |
              |   |  Return
              |   v
              `--JumpLoop
    
    Here the Resume will get the accumulator from the generator and the
    Return will use it, which will be seen as an out-of-loop use of the
    generator, but the generator was never reachable from the "real" loop
    body.
    
    At the end of the day, since there are no actual uses of the generator
    value in the loop body, the lifetime extension does no harm; all that
    fails is a DCHECK that the values loop lifetime extension extends are
    actually loadable. So, we can relax this DCHECK for this specific
    generator edge case, by checking for whether the JumpLoop is reachable
    from the generator resume.
    
    Bug: v8:7700
    Change-Id: Iec4db2aee5b8812de61c3afb9004c8be3982baa2
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3890975
    Auto-Submit: Leszek Swirski <leszeks@chromium.org>
    Reviewed-by: 's avatarJakob Linke <jgruber@chromium.org>
    Commit-Queue: Jakob Linke <jgruber@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#83144}
    dd6fa2d1
Name
Last commit
Last update
..
DEPS Loading commit data...
DIR_METADATA Loading commit data...
OWNERS Loading commit data...
maglev-assembler-inl.h Loading commit data...
maglev-assembler.h Loading commit data...
maglev-basic-block.h Loading commit data...
maglev-code-gen-state.h Loading commit data...
maglev-code-generator.cc Loading commit data...
maglev-code-generator.h Loading commit data...
maglev-compilation-info.cc Loading commit data...
maglev-compilation-info.h Loading commit data...
maglev-compilation-unit.cc Loading commit data...
maglev-compilation-unit.h Loading commit data...
maglev-compiler.cc Loading commit data...
maglev-compiler.h Loading commit data...
maglev-concurrent-dispatcher.cc Loading commit data...
maglev-concurrent-dispatcher.h Loading commit data...
maglev-graph-builder.cc Loading commit data...
maglev-graph-builder.h Loading commit data...
maglev-graph-labeller.h Loading commit data...
maglev-graph-printer.cc Loading commit data...
maglev-graph-printer.h Loading commit data...
maglev-graph-processor.h Loading commit data...
maglev-graph-verifier.h Loading commit data...
maglev-graph.h Loading commit data...
maglev-interpreter-frame-state.h Loading commit data...
maglev-ir-inl.h Loading commit data...
maglev-ir.cc Loading commit data...
maglev-ir.h Loading commit data...
maglev-regalloc-data.h Loading commit data...
maglev-regalloc.cc Loading commit data...
maglev-regalloc.h Loading commit data...
maglev-register-frame-array.h Loading commit data...
maglev-vreg-allocator.h Loading commit data...
maglev.cc Loading commit data...
maglev.h Loading commit data...