Skip to content

Convert Python source code to SSA form #2

@pfalcon

Description

@pfalcon

Intro: https://en.wikipedia.org/wiki/Static_single_assignment_form

Convert Python to SSA form. Baseline example:

a = 0

if a:
    x = 1
else:
    x = 2
print(x)

Schematic transformation to SSA would be:

a0 = 0

if a0:
    x0 = 1
else:
    x1 = 2
x2 = __phi__(x0, x1)
print(x2)

However, that's not executable form. Can actually make it executable with more syntactic noise:

from ssa_interp import *


# All vars should be initialized
x0 = x1 = None

a0 = 0

__label__("bb0")
if a0:
    __label__("bb1")
    x0 = 1
else:
    __label__("bb2")
    x1 = 2
# Crucial point - __phi__'s really should be first "instructions" of
# the basic block, even before a label.
x2 = __phi__({"bb1": x0, "bb2": x1})
__label__("bb3")
print(x2)

Where ssa_interp.py is:

__all__ = ("__label__", "__phi__")

_last_bblock = None

def __label__(lab):
    global _last_bblock
    _last_bblock = lab


def __phi__(choices):
    global _last_bblock
    return choices[_last_bblock]

The challenge is to convert arbitrary Python source code to such an SSA form. See how far we can go without explicit __goto__. The first suspects would be break/continue. But Aycock/Hosrpool aren't put down by them. Indeed, break/continue are static control flow, so we just add CFG edge, and it's not important what we have in the surface form.

The real suspect is of course exception handling. But while it's conceptually dynamic control flow, we can over-approximate it statically. That would lead to ugly multi-var phi's, but such is exception handling. That's why many languages afraid of it. Us shouldn't ;-).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions