diff --git a/numba_rvsdg-demo.ipynb b/numba_rvsdg-demo.ipynb index daf3ca6..a00d86c 100644 --- a/numba_rvsdg-demo.ipynb +++ b/numba_rvsdg-demo.ipynb @@ -18,6 +18,18 @@ "The code in this demo is a faithful implementation of the Algorithms described in `Bahmann2015` -- https://dl.acm.org/doi/pdf/10.1145/2693261" ] }, + { + "cell_type": "markdown", + "id": "a3ea9c10-af0c-472e-8efd-ff5b4db60b14", + "metadata": {}, + "source": [ + "## Motiviation\n", + "\n", + "* Abstract away control flow\n", + "* Make it easier for compilers to optimize\n", + "* Beginning of a source frontend for Numba" + ] + }, { "cell_type": "markdown", "id": "dbcd23bd-917c-4778-85d3-4d0aca647a86", @@ -112,8 +124,9 @@ "def compile_ast(ast_):\n", " \"\"\"Custom `compile` function via `exec`. \"\"\"\n", " exec_locals = {}\n", + " name = ast_.name\n", " exec(ast.unparse(ast_), {}, exec_locals)\n", - " transformed = exec_locals[\"transformed_function\"]\n", + " transformed = exec_locals[name]\n", " return transformed\n", "\n", "# https://github.com/ipython/ipython/issues/11747#issuecomment-528694702\n", @@ -151,7 +164,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "ad7ed127-8784-4eaf-a9c2-f66a6701e996", "metadata": { "editable": true, @@ -162,7 +175,7 @@ }, "outputs": [], "source": [ - "def branch(b: int):\n", + "def branch(b: int) -> int:\n", " if b:\n", " r = 1\n", " else:\n", @@ -172,7 +185,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "id": "77aacace-1738-491e-be24-3266bfc077d5", "metadata": { "editable": true, @@ -188,7 +201,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "50495ec4-38c5-424e-ac0d-426069c28758", "metadata": { "editable": true, @@ -302,7 +315,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "3db30dd3-d79c-4ff3-aad7-4026466267ce", "metadata": { "editable": true, @@ -318,7 +331,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "a81b68d8-70c8-4e97-a304-921eb28644c3", "metadata": { "editable": true, @@ -457,7 +470,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "00dd7c03-f84f-424c-9a5d-3f8ab9a656da", "metadata": {}, "outputs": [ @@ -611,7 +624,7 @@ ".jp-RenderedHTML .vg { color: #19177C } /* Name.Variable.Global */\n", ".jp-RenderedHTML .vi { color: #19177C } /* Name.Variable.Instance */\n", ".jp-RenderedHTML .vm { color: #19177C } /* Name.Variable.Magic */\n", - ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */
def transformed_function(b: int):\n",
+       ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */
def transformed_branch(b: int) -> int:\n",
        "    if b:\n",
        "        r = 1\n",
        "    else:\n",
@@ -621,7 +634,7 @@
       ],
       "text/latex": [
        "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
-       "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}function}\\PY{p}{(}\\PY{n}{b}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)}\\PY{p}{:}\n",
+       "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}branch}\\PY{p}{(}\\PY{n}{b}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)} \\PY{o}{\\PYZhy{}}\\PY{o}{\\PYZgt{}} \\PY{n+nb}{int}\\PY{p}{:}\n",
        "    \\PY{k}{if} \\PY{n}{b}\\PY{p}{:}\n",
        "        \\PY{n}{r} \\PY{o}{=} \\PY{l+m+mi}{1}\n",
        "    \\PY{k}{else}\\PY{p}{:}\n",
@@ -630,7 +643,7 @@
        "\\end{Verbatim}\n"
       ],
       "text/plain": [
-       "def transformed_function(b: int):\n",
+       "def transformed_branch(b: int) -> int:\n",
        "    if b:\n",
        "        r = 1\n",
        "    else:\n",
@@ -638,7 +651,7 @@
        "    return r"
       ]
      },
-     "execution_count": 8,
+     "execution_count": 7,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -651,7 +664,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 8,
    "id": "153d97ed-1588-4b84-9087-293ce749cd1b",
    "metadata": {},
    "outputs": [
@@ -661,7 +674,7 @@
        "(2, 1)"
       ]
      },
-     "execution_count": 9,
+     "execution_count": 8,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -689,12 +702,12 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": 9,
    "id": "c180fa36-d6fc-4b55-8534-384cbbb2ceee",
    "metadata": {},
    "outputs": [],
    "source": [
-    "def multi_return(b: int):\n",
+    "def multi_return(b: int) -> int:\n",
     "    if b:\n",
     "        return 1\n",
     "    else:\n",
@@ -703,7 +716,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 10,
    "id": "263882ae-4929-4619-99d1-6e5af8081f77",
    "metadata": {},
    "outputs": [],
@@ -713,7 +726,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": 11,
    "id": "a7e1aa87-d0cd-4ca7-90c7-311d4d9065b9",
    "metadata": {},
    "outputs": [
@@ -797,12 +810,12 @@
    "id": "ce5c9a8b-5285-476b-82d5-6e5b7ac76988",
    "metadata": {},
    "source": [
-    "## Close CFG: restructure"
+    "## Close CFG: Restructure"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 12,
    "id": "4206ca5e-263b-4bfe-946f-658e8fea917c",
    "metadata": {},
    "outputs": [],
@@ -812,7 +825,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 13,
    "id": "0a132a5d-988c-4def-a21a-05380d90d9b8",
    "metadata": {},
    "outputs": [
@@ -944,7 +957,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
+   "execution_count": 14,
    "id": "57b3ec44-f98c-4c13-9c86-29bd574afa25",
    "metadata": {},
    "outputs": [
@@ -1098,7 +1111,7 @@
        ".jp-RenderedHTML .vg { color: #19177C } /* Name.Variable.Global */\n",
        ".jp-RenderedHTML .vi { color: #19177C } /* Name.Variable.Instance */\n",
        ".jp-RenderedHTML .vm { color: #19177C } /* Name.Variable.Magic */\n",
-       ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */
def transformed_function(b: int):\n",
+       ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */
def transformed_multi_return(b: int) -> int:\n",
        "    if b:\n",
        "        __scfg_return_value__ = 1\n",
        "    else:\n",
@@ -1108,7 +1121,7 @@
       ],
       "text/latex": [
        "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
-       "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}function}\\PY{p}{(}\\PY{n}{b}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)}\\PY{p}{:}\n",
+       "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}multi\\PYZus{}return}\\PY{p}{(}\\PY{n}{b}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)} \\PY{o}{\\PYZhy{}}\\PY{o}{\\PYZgt{}} \\PY{n+nb}{int}\\PY{p}{:}\n",
        "    \\PY{k}{if} \\PY{n}{b}\\PY{p}{:}\n",
        "        \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}return\\PYZus{}value\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{1}\n",
        "    \\PY{k}{else}\\PY{p}{:}\n",
@@ -1117,7 +1130,7 @@
        "\\end{Verbatim}\n"
       ],
       "text/plain": [
-       "def transformed_function(b: int):\n",
+       "def transformed_multi_return(b: int) -> int:\n",
        "    if b:\n",
        "        __scfg_return_value__ = 1\n",
        "    else:\n",
@@ -1125,7 +1138,7 @@
        "    return __scfg_return_value__"
       ]
      },
-     "execution_count": 15,
+     "execution_count": 14,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -1138,7 +1151,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 16,
+   "execution_count": 15,
    "id": "34b97f2e-8131-4e65-b66f-5ae540ce38cc",
    "metadata": {},
    "outputs": [
@@ -1148,7 +1161,7 @@
        "(2, 1)"
       ]
      },
-     "execution_count": 16,
+     "execution_count": 15,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -1184,7 +1197,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
+   "execution_count": 16,
    "id": "1ddb14d9-56f1-4f6c-b1e2-6fdde2942b3b",
    "metadata": {},
    "outputs": [],
@@ -1198,7 +1211,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 17,
    "id": "af9bbca7-03bb-4fb1-aecf-393e9bb62846",
    "metadata": {},
    "outputs": [],
@@ -1208,7 +1221,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": 18,
    "id": "e72cc9eb-819e-4741-9e36-179692886c44",
    "metadata": {},
    "outputs": [
@@ -1305,12 +1318,12 @@
    "id": "7293cab2-1722-4666-a898-fc8e4e264a18",
    "metadata": {},
    "source": [
-    "## Loop Restructure: restructure"
+    "## Loop Restructure: Restructure"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 19,
    "id": "973e662a-1462-4c87-ac7e-cdebe2c60b41",
    "metadata": {},
    "outputs": [],
@@ -1320,7 +1333,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": 20,
    "id": "1c6cc6b2-84a9-4b85-90ec-fb79af75bad3",
    "metadata": {},
    "outputs": [
@@ -1511,7 +1524,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 21,
    "id": "c5c4375a-541f-4c3b-9368-38210c10cdd5",
    "metadata": {},
    "outputs": [
@@ -1665,7 +1678,7 @@
        ".jp-RenderedHTML .vg { color: #19177C } /* Name.Variable.Global */\n",
        ".jp-RenderedHTML .vi { color: #19177C } /* Name.Variable.Instance */\n",
        ".jp-RenderedHTML .vm { color: #19177C } /* Name.Variable.Magic */\n",
-       ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */
def transformed_function():\n",
+       ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */
def transformed_while_loop():\n",
        "    c = 0\n",
        "    __scfg_loop_cont__ = True\n",
        "    while __scfg_loop_cont__:\n",
@@ -1680,7 +1693,7 @@
       ],
       "text/latex": [
        "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
-       "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}function}\\PY{p}{(}\\PY{p}{)}\\PY{p}{:}\n",
+       "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}while\\PYZus{}loop}\\PY{p}{(}\\PY{p}{)}\\PY{p}{:}\n",
        "    \\PY{n}{c} \\PY{o}{=} \\PY{l+m+mi}{0}\n",
        "    \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{k+kc}{True}\n",
        "    \\PY{k}{while} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}}\\PY{p}{:}\n",
@@ -1694,7 +1707,7 @@
        "\\end{Verbatim}\n"
       ],
       "text/plain": [
-       "def transformed_function():\n",
+       "def transformed_while_loop():\n",
        "    c = 0\n",
        "    __scfg_loop_cont__ = True\n",
        "    while __scfg_loop_cont__:\n",
@@ -1707,7 +1720,7 @@
        "    return c"
       ]
      },
-     "execution_count": 22,
+     "execution_count": 21,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -1731,14 +1744,14 @@
    "id": "249d5667-db9a-4dc3-86a4-5a5ce9189fcf",
    "metadata": {},
    "source": [
-    "## Early Exit: example and CFG\n",
+    "## Early Exit: Example and CFG\n",
     "\n",
     "Things become more interesting, when the loop contains early exits:"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": 22,
    "id": "93f8e8d3-839a-4fbb-b209-da6425fcb5cf",
    "metadata": {},
    "outputs": [],
@@ -1754,7 +1767,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 24,
+   "execution_count": 23,
    "id": "4dbf537f-b67d-4203-947f-9ba669eb8edb",
    "metadata": {},
    "outputs": [],
@@ -1764,7 +1777,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": 24,
    "id": "8e3bd9f6-0b15-402f-b7d2-7233bcf881dc",
    "metadata": {},
    "outputs": [
@@ -1875,12 +1888,12 @@
    "id": "4dd81694-0b0e-4434-baaf-62a7d037851b",
    "metadata": {},
    "source": [
-    "## Early Exit: restructure"
+    "## Early Exit: Restructure"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 26,
+   "execution_count": 25,
    "id": "1fce9b69-084c-4b52-94fc-699cb28f3549",
    "metadata": {},
    "outputs": [],
@@ -1890,7 +1903,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 27,
+   "execution_count": 26,
    "id": "0446d173-eafd-448e-a163-ec6ba7c55784",
    "metadata": {
     "editable": true,
@@ -2212,7 +2225,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 28,
+   "execution_count": 27,
    "id": "9a122ad2-1eec-41c8-8fa2-ab0500ba9dfb",
    "metadata": {},
    "outputs": [
@@ -2366,7 +2379,7 @@
        ".jp-RenderedHTML .vg { color: #19177C } /* Name.Variable.Global */\n",
        ".jp-RenderedHTML .vi { color: #19177C } /* Name.Variable.Instance */\n",
        ".jp-RenderedHTML .vm { color: #19177C } /* Name.Variable.Magic */\n",
-       ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */
def transformed_function(a: int):\n",
+       ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */
def transformed_while_loop_with_exit(a: int):\n",
        "    c = 0\n",
        "    __scfg_loop_cont__ = True\n",
        "    while __scfg_loop_cont__:\n",
@@ -2391,7 +2404,7 @@
       ],
       "text/latex": [
        "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
-       "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}function}\\PY{p}{(}\\PY{n}{a}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)}\\PY{p}{:}\n",
+       "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}while\\PYZus{}loop\\PYZus{}with\\PYZus{}exit}\\PY{p}{(}\\PY{n}{a}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)}\\PY{p}{:}\n",
        "    \\PY{n}{c} \\PY{o}{=} \\PY{l+m+mi}{0}\n",
        "    \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{k+kc}{True}\n",
        "    \\PY{k}{while} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}}\\PY{p}{:}\n",
@@ -2415,7 +2428,7 @@
        "\\end{Verbatim}\n"
       ],
       "text/plain": [
-       "def transformed_function(a: int):\n",
+       "def transformed_while_loop_with_exit(a: int):\n",
        "    c = 0\n",
        "    __scfg_loop_cont__ = True\n",
        "    while __scfg_loop_cont__:\n",
@@ -2438,7 +2451,7 @@
        "    return __scfg_return_value__"
       ]
      },
-     "execution_count": 28,
+     "execution_count": 27,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -2454,7 +2467,7 @@
    "id": "5aa6893a-c5d5-48c9-a159-4120faf9532b",
    "metadata": {},
    "source": [
-    "## For Loop: Example and CFG"
+    "## For-Loop: Example and CFG"
    ]
   },
   {
@@ -2472,21 +2485,21 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 29,
+   "execution_count": 28,
    "id": "87867a02-0b9d-46e2-85de-55de473f3c64",
    "metadata": {},
    "outputs": [],
    "source": [
-    "def for_loop():\n",
-    "    c = 0\n",
-    "    for i in range(10):\n",
-    "        c += i\n",
-    "    return c"
+    "    def for_loop():\n",
+    "        c = 0\n",
+    "        for i in range(10):\n",
+    "            c += i\n",
+    "        return c"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 30,
+   "execution_count": 29,
    "id": "5384e244-bdbc-4214-8a6e-aa2b47315bce",
    "metadata": {},
    "outputs": [],
@@ -2496,7 +2509,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 31,
+   "execution_count": 30,
    "id": "f59b20e0-5f6e-4161-a202-60e3c8e9d3ae",
    "metadata": {
     "scrolled": true
@@ -2613,12 +2626,12 @@
    "id": "6facab03-2901-4bb8-b3a2-c130a4892206",
    "metadata": {},
    "source": [
-    "## For-loop: restructure"
+    "## For-Loop: Restructure"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": 31,
    "id": "4a7c99b6-6bbd-43b4-9a0f-d123839c6222",
    "metadata": {},
    "outputs": [],
@@ -2627,194 +2640,9 @@
    ]
   },
   {
-   "cell_type": "code",
-   "execution_count": 33,
-   "id": "6f9a2e02-1f70-4f97-8c98-12d1c574deb6",
+   "cell_type": "markdown",
+   "id": "26e4e14f-242a-48bd-9142-1e74c2008bfb",
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "\n",
-       "    
\n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "cluster_loop_region_0\n", - "\n", - "loop_region_0\n", - "jump targets: ('3',)\n", - "\n", - "\n", - "cluster_head_region_0\n", - "\n", - "head_region_0\n", - "jump targets: ('branch_region_0', 'branch_region_1')\n", - "\n", - "\n", - "cluster_branch_region_0\n", - "\n", - "branch_region_0\n", - "jump targets: ('tail_region_0',)\n", - "\n", - "\n", - "cluster_branch_region_1\n", - "\n", - "branch_region_1\n", - "jump targets: ('tail_region_0',)\n", - "\n", - "\n", - "cluster_tail_region_0\n", - "\n", - "tail_region_0\n", - "jump targets: ('3',)\n", - "\n", - "\n", - "\n", - "3\n", - "\n", - "3\n", - "i = __scfg_iter_last_1__\n", - "jump targets: ('4',)\n", - "\n", - "\n", - "\n", - "4\n", - "\n", - "4\n", - "return c\n", - "\n", - "\n", - "\n", - "3->4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "0\n", - "\n", - "0\n", - "c = 0\n", - "__scfg_iterator_1__ = iter(range(10))\n", - "i = None\n", - "jump targets: ('loop_region_0',)\n", - "\n", - "\n", - "\n", - "1\n", - "\n", - "1\n", - "__scfg_iter_last_1__ = i\n", - "i = next(__scfg_iterator_1__, '__scfg_sentinel__')\n", - "i != '__scfg_sentinel__'\n", - "jump targets: ('branch_region_0', 'branch_region_1')\n", - "\n", - "\n", - "\n", - "0->1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "2\n", - "\n", - "2\n", - "c += i\n", - "jump targets: ('synth_asign_block_1',)\n", - "\n", - "\n", - "\n", - "1->2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "synth_asign_block_0\n", - "\n", - "synth_asign_block_0\n", - "__scfg_backedge_var_0__ = 1\n", - "jump targets: ('tail_region_0',)\n", - "\n", - "\n", - "\n", - "1->synth_asign_block_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "synth_asign_block_1\n", - "\n", - "synth_asign_block_1\n", - "__scfg_backedge_var_0__ = 0\n", - "jump targets: ('tail_region_0',)\n", - "\n", - "\n", - "\n", - "2->synth_asign_block_1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "synth_exit_latch_block_0\n", - "\n", - "synth_exit_latch_block_0\n", - "variable: __scfg_backedge_var_0__\n", - "1 → 3\n", - "0 → head_region_0\n", - "jump targets: ('3',)\n", - "back edges: ('head_region_0',)\n", - "\n", - "\n", - "\n", - "synth_asign_block_1->synth_exit_latch_block_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "synth_asign_block_0->synth_exit_latch_block_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "synth_exit_latch_block_0->3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "synth_exit_latch_block_0->1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], "source": [ "render_scfg_info_notebook_center(scfg)" ] @@ -2824,12 +2652,12 @@ "id": "6ae72138-16cd-496a-b52a-c46a41f7b3bb", "metadata": {}, "source": [ - "## For-loop: Python synthesis" + "## For-loop: Python Synthesis" ] }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 32, "id": "2bdd6e26-d4af-4630-b6b0-e8f324e14733", "metadata": {}, "outputs": [ @@ -2983,7 +2811,7 @@ ".jp-RenderedHTML .vg { color: #19177C } /* Name.Variable.Global */\n", ".jp-RenderedHTML .vi { color: #19177C } /* Name.Variable.Instance */\n", ".jp-RenderedHTML .vm { color: #19177C } /* Name.Variable.Magic */\n", - ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */
def transformed_function():\n",
+       ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */
def transformed_for_loop():\n",
        "    c = 0\n",
        "    __scfg_iterator_1__ = iter(range(10))\n",
        "    i = None\n",
@@ -3003,7 +2831,7 @@
       ],
       "text/latex": [
        "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
-       "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}function}\\PY{p}{(}\\PY{p}{)}\\PY{p}{:}\n",
+       "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}for\\PYZus{}loop}\\PY{p}{(}\\PY{p}{)}\\PY{p}{:}\n",
        "    \\PY{n}{c} \\PY{o}{=} \\PY{l+m+mi}{0}\n",
        "    \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}iterator\\PYZus{}1\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{n+nb}{iter}\\PY{p}{(}\\PY{n+nb}{range}\\PY{p}{(}\\PY{l+m+mi}{10}\\PY{p}{)}\\PY{p}{)}\n",
        "    \\PY{n}{i} \\PY{o}{=} \\PY{k+kc}{None}\n",
@@ -3022,7 +2850,7 @@
        "\\end{Verbatim}\n"
       ],
       "text/plain": [
-       "def transformed_function():\n",
+       "def transformed_for_loop():\n",
        "    c = 0\n",
        "    __scfg_iterator_1__ = iter(range(10))\n",
        "    i = None\n",
@@ -3040,7 +2868,7 @@
        "    return c"
       ]
      },
-     "execution_count": 34,
+     "execution_count": 32,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -3053,12 +2881,1035 @@
   },
   {
    "cell_type": "markdown",
-   "id": "9cec4807-fc8d-4b82-b96d-cce226f968bc",
+   "id": "7712e672-6556-4ee8-a019-8ef300bc527b",
    "metadata": {},
    "source": [
-    "TODO\n",
-    "* break and continue elimination\n",
-    "* if-cascade\n",
+    "## Break and Continue: Example and CFG"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "id": "e241526b-b064-487f-abdc-0672c30686da",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def break_and_continue(x: int, y: int) -> int:\n",
+    "    for i in range(2):\n",
+    "        if i == x:\n",
+    "            i = 3\n",
+    "            return i + 100\n",
+    "        elif i == y:\n",
+    "            i = 4\n",
+    "            break\n",
+    "        else:\n",
+    "            continue\n",
+    "    return i"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "id": "18aae927-21d8-4dc0-a753-39c8c23b8f7d",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "scfg = AST2SCFGTransformer(break_and_continue).transform_to_SCFG()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "id": "553a0fd2-3e39-4bc7-b837-f99cdd7bf3ed",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "\n",
+       "    
\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "0\n", + "__scfg_iterator_1__ = iter(range(2))\n", + "i = None\n", + "jump targets: ('1',)\n", + "\n", + "\n", + "\n", + "1\n", + "\n", + "1\n", + "__scfg_iter_last_1__ = i\n", + "i = next(__scfg_iterator_1__, '__scfg_sentinel__')\n", + "i != '__scfg_sentinel__'\n", + "jump targets: ('2', '3')\n", + "\n", + "\n", + "\n", + "0->1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "2\n", + "\n", + "2\n", + "i == x\n", + "jump targets: ('5', '6')\n", + "\n", + "\n", + "\n", + "1->2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "3\n", + "\n", + "3\n", + "i = __scfg_iter_last_1__\n", + "jump targets: ('4',)\n", + "\n", + "\n", + "\n", + "1->3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "5\n", + "\n", + "5\n", + "i = 3\n", + "return i + 100\n", + "\n", + "\n", + "\n", + "2->5\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "6\n", + "\n", + "6\n", + "i == y\n", + "jump targets: ('8', '1')\n", + "\n", + "\n", + "\n", + "2->6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "6->1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "8\n", + "\n", + "8\n", + "i = 4\n", + "jump targets: ('4',)\n", + "\n", + "\n", + "\n", + "6->8\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "4\n", + "\n", + "4\n", + "return i\n", + "\n", + "\n", + "\n", + "8->4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "3->4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "render_scfg_info_notebook_center(scfg)" + ] + }, + { + "cell_type": "markdown", + "id": "e54b25c2-265a-48d8-b140-d67c30e8e6dd", + "metadata": {}, + "source": [ + "## Break and Continue: restructure" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "0c892380-af7d-4948-b9fd-3443130ee723", + "metadata": {}, + "outputs": [], + "source": [ + "scfg.restructure()" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "e5d114c0-5964-4e68-82f9-cfd541ee2445", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "cluster_head_region_0\n", + "\n", + "head_region_0\n", + "jump targets: ('branch_region_0', 'branch_region_1', 'branch_region_2')\n", + "\n", + "\n", + "cluster_loop_region_0\n", + "\n", + "loop_region_0\n", + "jump targets: ('synth_exit_block_0',)\n", + "\n", + "\n", + "cluster_head_region_1\n", + "\n", + "head_region_1\n", + "jump targets: ('branch_region_3', 'branch_region_4')\n", + "\n", + "\n", + "cluster_branch_region_3\n", + "\n", + "branch_region_3\n", + "jump targets: ('tail_region_1',)\n", + "\n", + "\n", + "cluster_head_region_2\n", + "\n", + "head_region_2\n", + "jump targets: ('branch_region_5', 'branch_region_6')\n", + "\n", + "\n", + "cluster_branch_region_5\n", + "\n", + "branch_region_5\n", + "jump targets: ('tail_region_2',)\n", + "\n", + "\n", + "cluster_branch_region_6\n", + "\n", + "branch_region_6\n", + "jump targets: ('tail_region_2',)\n", + "\n", + "\n", + "cluster_head_region_3\n", + "\n", + "head_region_3\n", + "jump targets: ('branch_region_7', 'branch_region_8')\n", + "\n", + "\n", + "cluster_branch_region_7\n", + "\n", + "branch_region_7\n", + "jump targets: ('tail_region_3',)\n", + "\n", + "\n", + "cluster_branch_region_8\n", + "\n", + "branch_region_8\n", + "jump targets: ('tail_region_3',)\n", + "\n", + "\n", + "cluster_tail_region_3\n", + "\n", + "tail_region_3\n", + "jump targets: ('tail_region_2',)\n", + "\n", + "\n", + "cluster_tail_region_2\n", + "\n", + "tail_region_2\n", + "jump targets: ('tail_region_1',)\n", + "\n", + "\n", + "cluster_branch_region_4\n", + "\n", + "branch_region_4\n", + "jump targets: ('tail_region_1',)\n", + "\n", + "\n", + "cluster_tail_region_1\n", + "\n", + "tail_region_1\n", + "jump targets: ('synth_exit_block_0',)\n", + "\n", + "\n", + "cluster_branch_region_0\n", + "\n", + "branch_region_0\n", + "jump targets: ('tail_region_0',)\n", + "\n", + "\n", + "cluster_branch_region_1\n", + "\n", + "branch_region_1\n", + "jump targets: ('tail_region_0',)\n", + "\n", + "\n", + "cluster_branch_region_2\n", + "\n", + "branch_region_2\n", + "jump targets: ('tail_region_0',)\n", + "\n", + "\n", + "cluster_tail_region_0\n", + "\n", + "tail_region_0\n", + "\n", + "\n", + "cluster_head_region_4\n", + "\n", + "head_region_4\n", + "jump targets: ('branch_region_9', 'branch_region_10')\n", + "\n", + "\n", + "cluster_branch_region_10\n", + "\n", + "branch_region_10\n", + "jump targets: ('tail_region_4',)\n", + "\n", + "\n", + "cluster_branch_region_9\n", + "\n", + "branch_region_9\n", + "jump targets: ('tail_region_4',)\n", + "\n", + "\n", + "cluster_tail_region_4\n", + "\n", + "tail_region_4\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "0\n", + "__scfg_iterator_1__ = iter(range(2))\n", + "i = None\n", + "jump targets: ('loop_region_0',)\n", + "\n", + "\n", + "\n", + "1\n", + "\n", + "1\n", + "__scfg_iter_last_1__ = i\n", + "i = next(__scfg_iterator_1__, '__scfg_sentinel__')\n", + "i != '__scfg_sentinel__'\n", + "jump targets: ('branch_region_3', 'branch_region_4')\n", + "\n", + "\n", + "\n", + "0->1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "2\n", + "\n", + "2\n", + "i == x\n", + "jump targets: ('branch_region_5', 'branch_region_6')\n", + "\n", + "\n", + "\n", + "1->2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_asign_block_0\n", + "\n", + "synth_asign_block_0\n", + "__scfg_backedge_var_0__ = 1\n", + "__scfg_exit_var_0__ = 0\n", + "jump targets: ('tail_region_1',)\n", + "\n", + "\n", + "\n", + "1->synth_asign_block_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_asign_block_1\n", + "\n", + "synth_asign_block_1\n", + "__scfg_backedge_var_0__ = 1\n", + "__scfg_exit_var_0__ = 1\n", + "jump targets: ('tail_region_2',)\n", + "\n", + "\n", + "\n", + "2->synth_asign_block_1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "6\n", + "\n", + "6\n", + "i == y\n", + "jump targets: ('branch_region_7', 'branch_region_8')\n", + "\n", + "\n", + "\n", + "2->6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_tail_block_0\n", + "\n", + "synth_tail_block_0\n", + "jump targets: ('tail_region_1',)\n", + "\n", + "\n", + "\n", + "synth_asign_block_1->synth_tail_block_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_asign_block_2\n", + "\n", + "synth_asign_block_2\n", + "__scfg_backedge_var_0__ = 1\n", + "__scfg_exit_var_0__ = 2\n", + "jump targets: ('tail_region_3',)\n", + "\n", + "\n", + "\n", + "6->synth_asign_block_2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_asign_block_3\n", + "\n", + "synth_asign_block_3\n", + "__scfg_backedge_var_0__ = 0\n", + "__scfg_exit_var_0__ = -1\n", + "jump targets: ('tail_region_3',)\n", + "\n", + "\n", + "\n", + "6->synth_asign_block_3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_tail_block_1\n", + "\n", + "synth_tail_block_1\n", + "jump targets: ('tail_region_2',)\n", + "\n", + "\n", + "\n", + "synth_asign_block_2->synth_tail_block_1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_asign_block_3->synth_tail_block_1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_tail_block_1->synth_tail_block_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_exit_latch_block_0\n", + "\n", + "synth_exit_latch_block_0\n", + "variable: __scfg_backedge_var_0__\n", + "1 → synth_exit_block_0\n", + "0 → head_region_1\n", + "jump targets: ('synth_exit_block_0',)\n", + "back edges: ('head_region_1',)\n", + "\n", + "\n", + "\n", + "synth_tail_block_0->synth_exit_latch_block_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_asign_block_0->synth_exit_latch_block_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_exit_latch_block_0->1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_exit_block_0\n", + "\n", + "synth_exit_block_0\n", + "variable: __scfg_exit_var_0__\n", + "0 → branch_region_0\n", + "1 → branch_region_1\n", + "2 → branch_region_2\n", + "jump targets: ('branch_region_0', 'branch_region_1', 'branch_region_2')\n", + "\n", + "\n", + "\n", + "synth_exit_latch_block_0->synth_exit_block_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "3\n", + "\n", + "3\n", + "i = __scfg_iter_last_1__\n", + "jump targets: ('synth_asign_block_4',)\n", + "\n", + "\n", + "\n", + "synth_exit_block_0->3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "5\n", + "\n", + "5\n", + "i = 3\n", + "return i + 100\n", + "jump targets: ('synth_asign_block_5',)\n", + "\n", + "\n", + "\n", + "synth_exit_block_0->5\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "8\n", + "\n", + "8\n", + "i = 4\n", + "jump targets: ('synth_asign_block_6',)\n", + "\n", + "\n", + "\n", + "synth_exit_block_0->8\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_asign_block_4\n", + "\n", + "synth_asign_block_4\n", + "__scfg_control_var_0__ = 0\n", + "jump targets: ('tail_region_0',)\n", + "\n", + "\n", + "\n", + "3->synth_asign_block_4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_head_block_0\n", + "\n", + "synth_head_block_0\n", + "variable: __scfg_control_var_0__\n", + "0 → branch_region_9\n", + "2 → branch_region_9\n", + "1 → branch_region_10\n", + "jump targets: ('branch_region_9', 'branch_region_10')\n", + "\n", + "\n", + "\n", + "synth_asign_block_4->synth_head_block_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_asign_block_5\n", + "\n", + "synth_asign_block_5\n", + "__scfg_control_var_0__ = 1\n", + "jump targets: ('tail_region_0',)\n", + "\n", + "\n", + "\n", + "5->synth_asign_block_5\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_asign_block_5->synth_head_block_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_asign_block_6\n", + "\n", + "synth_asign_block_6\n", + "__scfg_control_var_0__ = 2\n", + "jump targets: ('tail_region_0',)\n", + "\n", + "\n", + "\n", + "8->synth_asign_block_6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_asign_block_6->synth_head_block_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_fill_block_0\n", + "\n", + "synth_fill_block_0\n", + "jump targets: ('tail_region_4',)\n", + "\n", + "\n", + "\n", + "synth_head_block_0->synth_fill_block_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "4\n", + "\n", + "4\n", + "return i\n", + "jump targets: ('tail_region_4',)\n", + "\n", + "\n", + "\n", + "synth_head_block_0->4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "synth_return_block_0\n", + "\n", + "synth_return_block_0\n", + "\n", + "\n", + "\n", + "synth_fill_block_0->synth_return_block_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "4->synth_return_block_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "render_scfg_info_notebook_center(scfg)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "a191a2ca-bc9a-4382-9242-12215de3840c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
def transformed_break_and_continue(x: int, y: int) -> int:\n",
+       "    __scfg_iterator_1__ = iter(range(2))\n",
+       "    i = None\n",
+       "    __scfg_loop_cont__ = True\n",
+       "    while __scfg_loop_cont__:\n",
+       "        __scfg_iter_last_1__ = i\n",
+       "        i = next(__scfg_iterator_1__, '__scfg_sentinel__')\n",
+       "        if i != '__scfg_sentinel__':\n",
+       "            if i == x:\n",
+       "                __scfg_exit_var_0__ = 1\n",
+       "                __scfg_backedge_var_0__ = 1\n",
+       "            elif i == y:\n",
+       "                __scfg_exit_var_0__ = 2\n",
+       "                __scfg_backedge_var_0__ = 1\n",
+       "            else:\n",
+       "                __scfg_backedge_var_0__ = 0\n",
+       "                __scfg_exit_var_0__ = -1\n",
+       "        else:\n",
+       "            __scfg_exit_var_0__ = 0\n",
+       "            __scfg_backedge_var_0__ = 1\n",
+       "        __scfg_loop_cont__ = not __scfg_backedge_var_0__\n",
+       "    if __scfg_exit_var_0__ in (0,):\n",
+       "        i = __scfg_iter_last_1__\n",
+       "        __scfg_control_var_0__ = 0\n",
+       "    elif __scfg_exit_var_0__ in (1,):\n",
+       "        i = 3\n",
+       "        __scfg_return_value__ = i + 100\n",
+       "        __scfg_control_var_0__ = 1\n",
+       "    else:\n",
+       "        i = 4\n",
+       "        __scfg_control_var_0__ = 2\n",
+       "    if __scfg_control_var_0__ in (0, 2):\n",
+       "        __scfg_return_value__ = i\n",
+       "    else:\n",
+       "        pass\n",
+       "    return __scfg_return_value__\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}break\\PYZus{}and\\PYZus{}continue}\\PY{p}{(}\\PY{n}{x}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{,} \\PY{n}{y}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)} \\PY{o}{\\PYZhy{}}\\PY{o}{\\PYZgt{}} \\PY{n+nb}{int}\\PY{p}{:}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}iterator\\PYZus{}1\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{n+nb}{iter}\\PY{p}{(}\\PY{n+nb}{range}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{)}\n", + " \\PY{n}{i} \\PY{o}{=} \\PY{k+kc}{None}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{k+kc}{True}\n", + " \\PY{k}{while} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}}\\PY{p}{:}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}iter\\PYZus{}last\\PYZus{}1\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{n}{i}\n", + " \\PY{n}{i} \\PY{o}{=} \\PY{n+nb}{next}\\PY{p}{(}\\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}iterator\\PYZus{}1\\PYZus{}\\PYZus{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{\\PYZus{}\\PYZus{}scfg\\PYZus{}sentinel\\PYZus{}\\PYZus{}}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n", + " \\PY{k}{if} \\PY{n}{i} \\PY{o}{!=} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{\\PYZus{}\\PYZus{}scfg\\PYZus{}sentinel\\PYZus{}\\PYZus{}}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{:}\n", + " \\PY{k}{if} \\PY{n}{i} \\PY{o}{==} \\PY{n}{x}\\PY{p}{:}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}exit\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{1}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}backedge\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{1}\n", + " \\PY{k}{elif} \\PY{n}{i} \\PY{o}{==} \\PY{n}{y}\\PY{p}{:}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}exit\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{2}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}backedge\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{1}\n", + " \\PY{k}{else}\\PY{p}{:}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}backedge\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{0}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}exit\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{1}\n", + " \\PY{k}{else}\\PY{p}{:}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}exit\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{0}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}backedge\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{1}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{o+ow}{not} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}backedge\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}}\n", + " \\PY{k}{if} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}exit\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o+ow}{in} \\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{,}\\PY{p}{)}\\PY{p}{:}\n", + " \\PY{n}{i} \\PY{o}{=} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}iter\\PYZus{}last\\PYZus{}1\\PYZus{}\\PYZus{}}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}control\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{0}\n", + " \\PY{k}{elif} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}exit\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o+ow}{in} \\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{,}\\PY{p}{)}\\PY{p}{:}\n", + " \\PY{n}{i} \\PY{o}{=} \\PY{l+m+mi}{3}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}return\\PYZus{}value\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{n}{i} \\PY{o}{+} \\PY{l+m+mi}{100}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}control\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{1}\n", + " \\PY{k}{else}\\PY{p}{:}\n", + " \\PY{n}{i} \\PY{o}{=} \\PY{l+m+mi}{4}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}control\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{2}\n", + " \\PY{k}{if} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}control\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o+ow}{in} \\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{,} \\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{:}\n", + " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}return\\PYZus{}value\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{n}{i}\n", + " \\PY{k}{else}\\PY{p}{:}\n", + " \\PY{k}{pass}\n", + " \\PY{k}{return} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}return\\PYZus{}value\\PYZus{}\\PYZus{}}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "def transformed_break_and_continue(x: int, y: int) -> int:\n", + " __scfg_iterator_1__ = iter(range(2))\n", + " i = None\n", + " __scfg_loop_cont__ = True\n", + " while __scfg_loop_cont__:\n", + " __scfg_iter_last_1__ = i\n", + " i = next(__scfg_iterator_1__, '__scfg_sentinel__')\n", + " if i != '__scfg_sentinel__':\n", + " if i == x:\n", + " __scfg_exit_var_0__ = 1\n", + " __scfg_backedge_var_0__ = 1\n", + " elif i == y:\n", + " __scfg_exit_var_0__ = 2\n", + " __scfg_backedge_var_0__ = 1\n", + " else:\n", + " __scfg_backedge_var_0__ = 0\n", + " __scfg_exit_var_0__ = -1\n", + " else:\n", + " __scfg_exit_var_0__ = 0\n", + " __scfg_backedge_var_0__ = 1\n", + " __scfg_loop_cont__ = not __scfg_backedge_var_0__\n", + " if __scfg_exit_var_0__ in (0,):\n", + " i = __scfg_iter_last_1__\n", + " __scfg_control_var_0__ = 0\n", + " elif __scfg_exit_var_0__ in (1,):\n", + " i = 3\n", + " __scfg_return_value__ = i + 100\n", + " __scfg_control_var_0__ = 1\n", + " else:\n", + " i = 4\n", + " __scfg_control_var_0__ = 2\n", + " if __scfg_control_var_0__ in (0, 2):\n", + " __scfg_return_value__ = i\n", + " else:\n", + " pass\n", + " return __scfg_return_value__" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "original_ast = unparse_code(break_and_continue)[0]\n", + "transformed_ast = SCFG2ASTTransformer().transform(original=original_ast, scfg=scfg)\n", + "display_source(ast.unparse(transformed_ast))" + ] + }, + { + "cell_type": "markdown", + "id": "9cec4807-fc8d-4b82-b96d-cce226f968bc", + "metadata": {}, + "source": [ + "TODO\n", + "\n", "* nested loops" ] } @@ -3079,7 +3930,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.3" + "version": "3.12.4" } }, "nbformat": 4,