mincaml icon indicating copy to clipboard operation
mincaml copied to clipboard

Generate graphviz for lowered program

Open osa1 opened this issue 5 years ago • 3 comments

Here's an example .dot generated by rustc:

cfg.dot
digraph __crate__ {
subgraph cluster_Mir_0_4 {
    graph [fontname="monospace"];
    node [fontname="monospace"];
    edge [fontname="monospace"];
    label=<fn foo::{{closure}}#0(_1: &amp;[[email protected]:2:15: 2:22], _2: u64) -&gt; ()<br align="left"/>>;
    bb0__0_4 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">_0 = const ()<br/></td></tr><tr><td align="left">return</td></tr></table>>];
}
subgraph cluster_Mir_0_5 {
    graph [fontname="monospace"];
    node [fontname="monospace"];
    edge [fontname="monospace"];
    label=<fn main() -&gt; ()<br align="left"/>let mut _1: u64;<br align="left"/>let mut _2: std::ops::Range&lt;i32&gt;;<br align="left"/>let mut _3: std::ops::Range&lt;i32&gt;;<br align="left"/>let mut _4: std::ops::Range&lt;i32&gt;;<br align="left"/>let mut _5: i32;<br align="left"/>let mut _6: std::option::Option&lt;i32&gt;;<br align="left"/>let mut _7: &amp;mut std::ops::Range&lt;i32&gt;;<br align="left"/>let mut _8: &amp;mut std::ops::Range&lt;i32&gt;;<br align="left"/>let mut _9: isize;<br align="left"/>let _10: i32;<br align="left"/>let mut _11: i32;<br align="left"/>let _12: i32;<br align="left"/>let mut _13: u64;<br align="left"/>let mut _14: i32;<br align="left"/>let mut _15: (u64, bool);<br align="left"/>let _16: ();<br align="left"/>let mut _17: u64;<br align="left"/>debug x =&gt; _1;<br align="left"/>debug iter =&gt; _4;<br align="left"/>debug __next =&gt; _5;<br align="left"/>debug val =&gt; _10;<br align="left"/>debug i =&gt; _12;<br align="left"/>>;
    bb0__0_5 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">StorageLive(_1)<br/>_1 = const 0u64<br/>StorageLive(_2)<br/>StorageLive(_3)<br/>(_3.0: i32) = const 0i32<br/>(_3.1: i32) = const 100i32<br/></td></tr><tr><td align="left">_2 = const &lt;std::ops::Range&lt;i32&gt; as std::iter::IntoIterator&gt;::into_iter(move _3)</td></tr></table>>];
    bb1__0_5 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">1</td></tr><tr><td align="left" balign="left">StorageDead(_3)<br/>StorageLive(_4)<br/>_4 = move _2<br/></td></tr><tr><td align="left">goto</td></tr></table>>];
    bb2__0_5 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">2</td></tr><tr><td align="left" balign="left">StorageLive(_5)<br/>StorageLive(_6)<br/>StorageLive(_7)<br/>StorageLive(_8)<br/>_8 = &amp;mut _4<br/>_7 = move _8<br/></td></tr><tr><td align="left">_6 = const &lt;std::ops::Range&lt;i32&gt; as std::iter::Iterator&gt;::next(move _7)</td></tr></table>>];
    bb3__0_5 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">3</td></tr><tr><td align="left" balign="left">StorageDead(_7)<br/>_9 = discriminant(_6)<br/></td></tr><tr><td align="left">switchInt(move _9)</td></tr></table>>];
    bb4__0_5 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">4</td></tr><tr><td align="left" balign="left">_0 = const ()<br/>StorageDead(_8)<br/>StorageDead(_6)<br/>StorageDead(_5)<br/>StorageDead(_4)<br/>StorageDead(_2)<br/>StorageDead(_1)<br/></td></tr><tr><td align="left">return</td></tr></table>>];
    bb5__0_5 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">5</td></tr><tr><td align="left">unreachable</td></tr></table>>];
    bb6__0_5 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">6</td></tr><tr><td align="left" balign="left">StorageLive(_10)<br/>_10 = ((_6 as Some).0: i32)<br/>StorageLive(_11)<br/>_11 = _10<br/>_5 = move _11<br/>StorageDead(_11)<br/>StorageDead(_10)<br/>StorageDead(_8)<br/>StorageDead(_6)<br/>StorageLive(_12)<br/>_12 = _5<br/>StorageLive(_13)<br/>StorageLive(_14)<br/>_14 = _12<br/>_13 = move _14 as u64 (Misc)<br/>StorageDead(_14)<br/>_15 = CheckedAdd(_1, move _13)<br/></td></tr><tr><td align="left">assert(!move (_15.1: bool), &quot;attempt to add with overflow&quot;)</td></tr></table>>];
    bb7__0_5 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">7</td></tr><tr><td align="left" balign="left">_1 = move (_15.0: u64)<br/>StorageDead(_13)<br/>StorageLive(_16)<br/>StorageLive(_17)<br/>_17 = _1<br/></td></tr><tr><td align="left">_16 = const foo(move _17)</td></tr></table>>];
    bb8__0_5 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">8</td></tr><tr><td align="left" balign="left">StorageDead(_17)<br/>StorageDead(_16)<br/>StorageDead(_12)<br/>StorageDead(_5)<br/></td></tr><tr><td align="left">goto</td></tr></table>>];
    bb0__0_5 -> bb1__0_5 [label="return"];
    bb1__0_5 -> bb2__0_5 [label=""];
    bb2__0_5 -> bb3__0_5 [label="return"];
    bb3__0_5 -> bb4__0_5 [label="0isize"];
    bb3__0_5 -> bb6__0_5 [label="1isize"];
    bb3__0_5 -> bb5__0_5 [label="otherwise"];
    bb6__0_5 -> bb7__0_5 [label=""];
    bb7__0_5 -> bb8__0_5 [label="return"];
    bb8__0_5 -> bb2__0_5 [label=""];
}
subgraph cluster_Mir_0_3 {
    graph [fontname="monospace"];
    node [fontname="monospace"];
    edge [fontname="monospace"];
    label=<fn foo(_1: u64) -&gt; ()<br align="left"/>let _2: [[email protected]:2:15: 2:22];<br align="left"/>let mut _3: ();<br align="left"/>let mut _4: &amp;[[email protected]:2:15: 2:22];<br align="left"/>let mut _5: (u64,);<br align="left"/>let mut _6: u64;<br align="left"/>debug x =&gt; _1;<br align="left"/>debug bar =&gt; _2;<br align="left"/>>;
    bb0__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">StorageLive(_2)<br/>StorageLive(_3)<br/>StorageLive(_4)<br/>_4 = &amp;_2<br/>StorageLive(_5)<br/>StorageLive(_6)<br/>_6 = _1<br/>(_5.0: u64) = move _6<br/></td></tr><tr><td align="left">_3 = const &lt;[[email protected]:2:15: 2:22] as std::ops::Fn&lt;(u64,)&gt;&gt;::call(move _4, move _5)</td></tr></table>>];
    bb1__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">1</td></tr><tr><td align="left" balign="left">StorageDead(_6)<br/>StorageDead(_5)<br/>StorageDead(_4)<br/>StorageDead(_3)<br/>_0 = const ()<br/>StorageDead(_2)<br/></td></tr><tr><td align="left">return</td></tr></table>>];
    bb0__0_3 -> bb1__0_3 [label="return"];
}
}

Rendered:

cfg

osa1 avatar Jun 03 '20 08:06 osa1

What does "lowered program" mean here?

shubhamkumar13 avatar Feb 22 '21 15:02 shubhamkumar13

It's been a while since I worked on this project so I don't remember all the details, but I think this refers to the IR before final code (assembly) generation in one of the branches (not in master branch, we use cranelift for code gen in master).

osa1 avatar Feb 23 '21 07:02 osa1

Oh ok, I was looking for any issues to get my hands dirty

shubhamkumar13 avatar Feb 23 '21 09:02 shubhamkumar13