@@ -2228,22 +2228,6 @@ impl<'a> FunctionPrinter<'a> {
22282228 }
22292229}
22302230
2231- /// Pretty printer for [`Function`].
2232- pub struct FunctionGraphvizPrinter < ' a > {
2233- fun : & ' a Function ,
2234- ptr_map : PtrPrintMap ,
2235- }
2236-
2237- impl < ' a > FunctionGraphvizPrinter < ' a > {
2238- pub fn new ( fun : & ' a Function ) -> Self {
2239- let mut ptr_map = PtrPrintMap :: identity ( ) ;
2240- if cfg ! ( test) {
2241- ptr_map. map_ptrs = true ;
2242- }
2243- Self { fun, ptr_map }
2244- }
2245- }
2246-
22472231/// Union-Find (Disjoint-Set) is a data structure for managing disjoint sets that has an interface
22482232/// of two operations:
22492233///
@@ -5929,13 +5913,6 @@ impl Function {
59295913 Some ( DumpHIR :: Debug ) => println ! ( "Optimized HIR:\n {:#?}" , & self ) ,
59305914 None => { } ,
59315915 }
5932-
5933- if let Some ( filename) = & get_option ! ( dump_hir_graphviz) {
5934- use std:: fs:: OpenOptions ;
5935- use std:: io:: Write ;
5936- let mut file = OpenOptions :: new ( ) . append ( true ) . open ( filename) . unwrap ( ) ;
5937- writeln ! ( file, "{}" , FunctionGraphvizPrinter :: new( self ) ) . unwrap ( ) ;
5938- }
59395916 }
59405917
59415918 pub fn dump_iongraph ( & self , function_name : & str , passes : Vec < Json > ) {
@@ -6477,87 +6454,6 @@ impl<'a> std::fmt::Display for FunctionPrinter<'a> {
64776454 }
64786455}
64796456
6480- struct HtmlEncoder < ' a , ' b > {
6481- formatter : & ' a mut std:: fmt:: Formatter < ' b > ,
6482- }
6483-
6484- impl < ' a , ' b > std:: fmt:: Write for HtmlEncoder < ' a , ' b > {
6485- fn write_str ( & mut self , s : & str ) -> std:: fmt:: Result {
6486- for ch in s. chars ( ) {
6487- match ch {
6488- '<' => self . formatter . write_str ( "<" ) ?,
6489- '>' => self . formatter . write_str ( ">" ) ?,
6490- '&' => self . formatter . write_str ( "&" ) ?,
6491- '"' => self . formatter . write_str ( """ ) ?,
6492- '\'' => self . formatter . write_str ( "'" ) ?,
6493- _ => self . formatter . write_char ( ch) ?,
6494- }
6495- }
6496- Ok ( ( ) )
6497- }
6498- }
6499-
6500- impl < ' a > std:: fmt:: Display for FunctionGraphvizPrinter < ' a > {
6501- fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
6502- macro_rules! write_encoded {
6503- ( $f: ident, $( $arg: tt) * ) => {
6504- HtmlEncoder { formatter: $f } . write_fmt( format_args!( $( $arg) * ) )
6505- } ;
6506- }
6507- use std:: fmt:: Write ;
6508- let fun = & self . fun ;
6509- let iseq_name = iseq_get_location ( fun. iseq , 0 ) ;
6510- write ! ( f, "digraph G {{ # " ) ?;
6511- write_encoded ! ( f, "{iseq_name}" ) ?;
6512- writeln ! ( f) ?;
6513- writeln ! ( f, "node [shape=plaintext];" ) ?;
6514- writeln ! ( f, "mode=hier; overlap=false; splines=true;" ) ?;
6515- for block_id in fun. rpo ( ) {
6516- writeln ! ( f, r#" {block_id} [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">"# ) ?;
6517- write ! ( f, r#"<TR><TD ALIGN="LEFT" PORT="params" BGCOLOR="gray">{block_id}("# ) ?;
6518- if !fun. blocks [ block_id. 0 ] . params . is_empty ( ) {
6519- let mut sep = "" ;
6520- for param in & fun. blocks [ block_id. 0 ] . params {
6521- write_encoded ! ( f, "{sep}{param}" ) ?;
6522- let insn_type = fun. type_of ( * param) ;
6523- if !insn_type. is_subtype ( types:: Empty ) {
6524- write_encoded ! ( f, ":{}" , insn_type. print( & self . ptr_map) ) ?;
6525- }
6526- sep = ", " ;
6527- }
6528- }
6529- let mut edges = vec ! [ ] ;
6530- writeln ! ( f, ") </TD></TR>" ) ?;
6531- for insn_id in & fun. blocks [ block_id. 0 ] . insns {
6532- let insn_id = fun. union_find . borrow ( ) . find_const ( * insn_id) ;
6533- let insn = fun. find ( insn_id) ;
6534- if matches ! ( insn, Insn :: Snapshot { ..} ) {
6535- continue ;
6536- }
6537- write ! ( f, r#"<TR><TD ALIGN="left" PORT="{insn_id}">"# ) ?;
6538- if insn. has_output ( ) {
6539- let insn_type = fun. type_of ( insn_id) ;
6540- if insn_type. is_subtype ( types:: Empty ) {
6541- write_encoded ! ( f, "{insn_id} = " ) ?;
6542- } else {
6543- write_encoded ! ( f, "{insn_id}:{} = " , insn_type. print( & self . ptr_map) ) ?;
6544- }
6545- }
6546- if let Insn :: Jump ( ref target) | Insn :: IfTrue { ref target, .. } | Insn :: IfFalse { ref target, .. } = insn {
6547- edges. push ( ( insn_id, target. target ) ) ;
6548- }
6549- write_encoded ! ( f, "{}" , insn. print( & self . ptr_map, Some ( fun. iseq) ) ) ?;
6550- writeln ! ( f, " </TD></TR>" ) ?;
6551- }
6552- writeln ! ( f, "</TABLE>>];" ) ?;
6553- for ( src, dst) in edges {
6554- writeln ! ( f, " {block_id}:{src} -> {dst}:params:n;" ) ?;
6555- }
6556- }
6557- writeln ! ( f, "}}" )
6558- }
6559- }
6560-
65616457#[ derive( Debug , Clone , PartialEq ) ]
65626458pub struct FrameState {
65636459 pub iseq : IseqPtr ,
@@ -9291,131 +9187,3 @@ mod infer_tests {
92919187 } ) ;
92929188 }
92939189}
9294-
9295- #[ cfg( test) ]
9296- mod graphviz_tests {
9297- use super :: * ;
9298- use insta:: assert_snapshot;
9299-
9300- #[ track_caller]
9301- fn hir_string ( method : & str ) -> String {
9302- let iseq = crate :: cruby:: with_rubyvm ( || get_method_iseq ( "self" , method) ) ;
9303- unsafe { crate :: cruby:: rb_zjit_profile_disable ( iseq) } ;
9304- let mut function = iseq_to_hir ( iseq) . unwrap ( ) ;
9305- function. optimize ( ) ;
9306- function. validate ( ) . unwrap ( ) ;
9307- format ! ( "{}" , FunctionGraphvizPrinter :: new( & function) )
9308- }
9309-
9310- #[ test]
9311- fn test_guard_fixnum_or_fixnum ( ) {
9312- eval ( r#"
9313- def test(x, y) = x | y
9314-
9315- test(1, 2)
9316- "# ) ;
9317- assert_snapshot ! ( hir_string( "test" ) , @r#"
9318- digraph G { # test@<compiled>:2
9319- node [shape=plaintext];
9320- mode=hier; overlap=false; splines=true;
9321- bb0 [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
9322- <TR><TD ALIGN="LEFT" PORT="params" BGCOLOR="gray">bb0() </TD></TR>
9323- <TR><TD ALIGN="left" PORT="v25">Entries bb1, bb2 </TD></TR>
9324- </TABLE>>];
9325- bb1 [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
9326- <TR><TD ALIGN="LEFT" PORT="params" BGCOLOR="gray">bb1() </TD></TR>
9327- <TR><TD ALIGN="left" PORT="v0">EntryPoint interpreter </TD></TR>
9328- <TR><TD ALIGN="left" PORT="v1">v1:BasicObject = LoadSelf </TD></TR>
9329- <TR><TD ALIGN="left" PORT="v2">v2:CPtr = LoadSP </TD></TR>
9330- <TR><TD ALIGN="left" PORT="v3">v3:BasicObject = LoadField v2, :x@0x1000 </TD></TR>
9331- <TR><TD ALIGN="left" PORT="v4">v4:BasicObject = LoadField v2, :y@0x1001 </TD></TR>
9332- <TR><TD ALIGN="left" PORT="v5">Jump bb3(v1, v3, v4) </TD></TR>
9333- </TABLE>>];
9334- bb1:v5 -> bb3:params:n;
9335- bb2 [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
9336- <TR><TD ALIGN="LEFT" PORT="params" BGCOLOR="gray">bb2() </TD></TR>
9337- <TR><TD ALIGN="left" PORT="v6">EntryPoint JIT(0) </TD></TR>
9338- <TR><TD ALIGN="left" PORT="v7">v7:BasicObject = LoadArg :self@0 </TD></TR>
9339- <TR><TD ALIGN="left" PORT="v8">v8:BasicObject = LoadArg :x@1 </TD></TR>
9340- <TR><TD ALIGN="left" PORT="v9">v9:BasicObject = LoadArg :y@2 </TD></TR>
9341- <TR><TD ALIGN="left" PORT="v10">Jump bb3(v7, v8, v9) </TD></TR>
9342- </TABLE>>];
9343- bb2:v10 -> bb3:params:n;
9344- bb3 [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
9345- <TR><TD ALIGN="LEFT" PORT="params" BGCOLOR="gray">bb3(v11:BasicObject, v12:BasicObject, v13:BasicObject) </TD></TR>
9346- <TR><TD ALIGN="left" PORT="v16">PatchPoint NoTracePoint </TD></TR>
9347- <TR><TD ALIGN="left" PORT="v27">PatchPoint MethodRedefined(Integer@0x1008, |@0x1010, cme:0x1018) </TD></TR>
9348- <TR><TD ALIGN="left" PORT="v28">v28:Fixnum = GuardType v12, Fixnum </TD></TR>
9349- <TR><TD ALIGN="left" PORT="v29">v29:Fixnum = GuardType v13, Fixnum </TD></TR>
9350- <TR><TD ALIGN="left" PORT="v30">v30:Fixnum = FixnumOr v28, v29 </TD></TR>
9351- <TR><TD ALIGN="left" PORT="v23">CheckInterrupts </TD></TR>
9352- <TR><TD ALIGN="left" PORT="v24">Return v30 </TD></TR>
9353- </TABLE>>];
9354- }
9355- "# ) ;
9356- }
9357-
9358- #[ test]
9359- fn test_multiple_blocks ( ) {
9360- eval ( r#"
9361- def test(c)
9362- if c
9363- 3
9364- else
9365- 4
9366- end
9367- end
9368-
9369- test(1)
9370- test("x")
9371- "# ) ;
9372- assert_snapshot ! ( hir_string( "test" ) , @r#"
9373- digraph G { # test@<compiled>:3
9374- node [shape=plaintext];
9375- mode=hier; overlap=false; splines=true;
9376- bb0 [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
9377- <TR><TD ALIGN="LEFT" PORT="params" BGCOLOR="gray">bb0() </TD></TR>
9378- <TR><TD ALIGN="left" PORT="v37">Entries bb1, bb2 </TD></TR>
9379- </TABLE>>];
9380- bb1 [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
9381- <TR><TD ALIGN="LEFT" PORT="params" BGCOLOR="gray">bb1() </TD></TR>
9382- <TR><TD ALIGN="left" PORT="v0">EntryPoint interpreter </TD></TR>
9383- <TR><TD ALIGN="left" PORT="v1">v1:BasicObject = LoadSelf </TD></TR>
9384- <TR><TD ALIGN="left" PORT="v2">v2:CPtr = LoadSP </TD></TR>
9385- <TR><TD ALIGN="left" PORT="v3">v3:BasicObject = LoadField v2, :c@0x1000 </TD></TR>
9386- <TR><TD ALIGN="left" PORT="v4">Jump bb3(v1, v3) </TD></TR>
9387- </TABLE>>];
9388- bb1:v4 -> bb3:params:n;
9389- bb2 [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
9390- <TR><TD ALIGN="LEFT" PORT="params" BGCOLOR="gray">bb2() </TD></TR>
9391- <TR><TD ALIGN="left" PORT="v5">EntryPoint JIT(0) </TD></TR>
9392- <TR><TD ALIGN="left" PORT="v6">v6:BasicObject = LoadArg :self@0 </TD></TR>
9393- <TR><TD ALIGN="left" PORT="v7">v7:BasicObject = LoadArg :c@1 </TD></TR>
9394- <TR><TD ALIGN="left" PORT="v8">Jump bb3(v6, v7) </TD></TR>
9395- </TABLE>>];
9396- bb2:v8 -> bb3:params:n;
9397- bb3 [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
9398- <TR><TD ALIGN="LEFT" PORT="params" BGCOLOR="gray">bb3(v9:BasicObject, v10:BasicObject) </TD></TR>
9399- <TR><TD ALIGN="left" PORT="v13">PatchPoint NoTracePoint </TD></TR>
9400- <TR><TD ALIGN="left" PORT="v15">CheckInterrupts </TD></TR>
9401- <TR><TD ALIGN="left" PORT="v16">v16:CBool = Test v10 </TD></TR>
9402- <TR><TD ALIGN="left" PORT="v17">v17:Falsy = RefineType v10, Falsy </TD></TR>
9403- <TR><TD ALIGN="left" PORT="v18">IfFalse v16, bb4(v9, v17) </TD></TR>
9404- <TR><TD ALIGN="left" PORT="v19">v19:Truthy = RefineType v10, Truthy </TD></TR>
9405- <TR><TD ALIGN="left" PORT="v21">PatchPoint NoTracePoint </TD></TR>
9406- <TR><TD ALIGN="left" PORT="v22">v22:Fixnum[3] = Const Value(3) </TD></TR>
9407- <TR><TD ALIGN="left" PORT="v25">CheckInterrupts </TD></TR>
9408- <TR><TD ALIGN="left" PORT="v26">Return v22 </TD></TR>
9409- </TABLE>>];
9410- bb3:v18 -> bb4:params:n;
9411- bb4 [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
9412- <TR><TD ALIGN="LEFT" PORT="params" BGCOLOR="gray">bb4(v27:BasicObject, v28:Falsy) </TD></TR>
9413- <TR><TD ALIGN="left" PORT="v31">PatchPoint NoTracePoint </TD></TR>
9414- <TR><TD ALIGN="left" PORT="v32">v32:Fixnum[4] = Const Value(4) </TD></TR>
9415- <TR><TD ALIGN="left" PORT="v35">CheckInterrupts </TD></TR>
9416- <TR><TD ALIGN="left" PORT="v36">Return v32 </TD></TR>
9417- </TABLE>>];
9418- }
9419- "# ) ;
9420- }
9421- }
0 commit comments