GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — `n_popped`, `n_pushed` is the wrong abstraction for stack effect · Issue #105034 · python/cpython

n_popped, n_pushed is the wrong abstraction for stack effect #105034

New issue
Copy link
New issue
Copy link
Closed as not planned
Closed as not planned
n_popped, n_pushed is the wrong abstraction for stack effect#105034
Copy link
Assignees
gvanrossum
Labels
type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@gvanrossum
gvanrossum
opened on May 28, 2023
Issue body actions

The code generator produces metadata for use by the compiler that tells it how many stack entries were pushed and popped by an opcode. These two quantities are subtracted to compute the net stack effect. (The metadata is in the form of functions _PyOpcode_num_popped and _PyOpcode_num_pushed in opcode_metadata.h.)

But what we really need to know, if we want accurate information about what an opcode (or micro-op) does to the stack, is three numbers: how low it goes, how high it goes, and where it ends. For example, if we have a micro-op that pops two entries and then pushes one, and another that pushes two and then pops one, and we combine them into a macro, the macro's net effect is zero, but the lowest point is two below the initial stack level, and the highest point is one above it.

There are various ways to express this, but there is no way to express all this information with just two numbers.

Note that the relevant calculation is already present in the generator, as part of analyze_macro().

Reacted by Irit Katriel
Reacted by Donghee Na and Raymond Hettinger

Activity

  1. gvanrossum
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on May 28, 2023
  2. gvanrossum
    self-assigned this
    on May 28, 2023
  3. gvanrossum commented on May 30, 2023

    @gvanrossum
    gvanrossum
    on May 30, 2023
    MemberAuthor
    More actions

    There are various ways to express this, but there is no way to express all this information with just two numbers.

    I might be wrong here. I'm ending up doing the equivalent of

    low = -popped
    net = pushed - popped
    high = max(0, net)

    So two numbers (low an net) would seem to be enough...

  4. markshannon commented on May 30, 2023

    @markshannon
    markshannon
    on May 30, 2023
    Member
    More actions

    Abstractly, each instruction, or op, pops some number of values, then either fails or pushes some other number of values.
    Two numbers are sufficient.

    For example, instruction I is composed of op A and op B. Op A pops 2 values, and pushes 1. Op B pops 2 values and pushes 2, the net effect is that I pops 3 values and pushes 2.

    You need to model the stack, rather than just adding up values.

    Operation Stack depth
    Start 0
    A pops -2
    A pushes -1
    B pops -3
    B pushes -1
    Reacted by Guido van Rossum
  5. gvanrossum commented on May 30, 2023

    @gvanrossum
    gvanrossum
    on May 30, 2023
    MemberAuthor
    More actions

    The tricky bits happen when the stack effect depends on oparg (e.g. BUILD_SET). The stack effect must then be represented symbolically. I don't know if there are any of those that need to be split up though -- will do an audit later.

  6. gvanrossum commented on May 30, 2023

    @gvanrossum
    gvanrossum
    on May 30, 2023
    MemberAuthor
    More actions

    Fortunately there are (as yet) no ops with variable-size stack effects. So in #104909 we can use Mark's algorithm.

    There is a hypothetical case where the tuple (popped, pushed) isn't enough for the computation of maximum stack level needed: consider I composed of A+B+C, where A pushes 1, B pops 2, and C pushes 1. The net effect is 0, but we need to know that this requires at least one item on the stack at the beginning, and we also need to know that it requires room for an extra item. However, this case doesn't occur in practice.

  7. carljm commented on May 30, 2023

    @carljm
    carljm
    on May 30, 2023
    Member
    More actions

    we also need to know that it requires room for an extra item

    Does it? Doesn't the cases generator convert temporaries pushed to the stack by one op and popped by the next into temporary variables, meaning the A+B+C example would not actually use any additional stack (though it would temporarily consume one item from the stack.)

    Reacted by Guido van Rossum
  8. gvanrossum commented on Jun 13, 2023

    @gvanrossum
    gvanrossum
    on Jun 13, 2023
    MemberAuthor
    More actions

    Let's close this since we don't need it.

  9. gvanrossum
    closed this as not plannedon Jun 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @gvanrossum
    gvanrossum

Labels

type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402520 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.