FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

bpo-46528: Simplify the VM's stack manipulations by brandtbucher · Pull Request #30902 · python/cpython · GitHub

/ cpython Public

bpo-46528: Simplify the VM's stack manipulations - #30902

Merged
brandtbucher merged 10 commits into
python:mainfrom
brandtbucher:swap
Jan 26, 2022
Merged

bpo-46528: Simplify the VM's stack manipulations#30902
brandtbucher merged 10 commits into
python:mainfrom
brandtbucher:swap

Conversation

brandtbucher commented Jan 26, 2022
edited by bedevere-bot
Loading

Copy link
Copy Markdown
Member

...as discussed in faster-cpython/ideas#228:

  • Replace DUP_TOP with COPY(1).
  • Replace DUP_TOP_TWO with COPY(2), COPY(2).
  • Introduce a new SWAP instruction.
    • Replace ROT_TWO with SWAP(2).
    • Replace ROT_THREE with SWAP(3), SWAP(2).
    • Remove ROT_FOUR.
    • Replace ROT_N(n) with SWAP(n), SWAP(n - 1), ..., SWAP(2).
    • Optimize runs of SWAP instructions.

https://bugs.python.org/issue46528

Comment thread Python/compile.c Outdated
Comment thread Python/compile.c

Copy link
Copy Markdown
Member

I threw together a test for the basic swaptimize algorithm and it passes some test cases, so that's nice:

def permutation(swaps, N=None):
    if N is None:
        N = max(swaps)
    perm = list(range(N))
    for s in swaps:
        perm[0], perm[s-1] = perm[s-1], perm[0]
    return perm


def swaptimize(*old_swaps):
    assert old_swaps
    if len(old_swaps) == 1:
        return tuple(old_swaps)

    perm = permutation(old_swaps)

    swaps = []
    for i, x in enumerate(perm):
        # March forward, searching for an un-traversed cycle.
        if x is None or x == i:
            continue
        # Traverse this cycle.
        j = i
        while True:
            if j != 0:
                swaps.append(j + 1)
            if perm[j] is None:
                # Back to the start of the cycle.
                assert j == i
                break
            next_j = perm[j]
            perm[j] = None
            j = next_j

    swaps = tuple(reversed(swaps))

    assert permutation(old_swaps, len(perm)) == permutation(swaps, len(perm))
    assert len(swaps) <= len(old_swaps)

    return swaps

assert swaptimize(1) == (1,) # This should be ()?
assert swaptimize(2) == (2,)
assert swaptimize(3) == (3,)
assert swaptimize(10) == (10,)

assert swaptimize(2, 2, 5, 5) == ()
assert swaptimize(10, 20, 20, 10) == ()
assert swaptimize(2, 3, 4, 3) == (3, 4, 3, 2)

from random import randint

for i in range(100_000):
    for n in range(1, 20):
        swaptimize(*[randint(2, 20) for _ in range(n)])

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants


Back | FazBrowse Home | New Git URL