PreviousUpNext

15.4.238  src/lib/compiler/back/low/display/machcode-controlflow-graph-viewer-g.pkg

## machcode-controlflow-graph-viewer-g.pkg

# Compiled by:
#     src/lib/compiler/back/low/lib/visual.lib

# This generic is invoked (only) from:
#
#     src/lib/compiler/back/low/main/main/backend-lowhalf-g.pkg

stipulate
    package f8b =  eight_byte_float;                                                    # eight_byte_float              is from   src/lib/std/eight-byte-float.pkg
    package glo =  graph_layout;                                                        # graph_layout                  is from   src/lib/compiler/back/low/display/graph-layout.pkg
    package lbl =  codelabel;                                                           # codelabel                     is from   src/lib/compiler/back/low/code/codelabel.pkg
    package odg =  oop_digraph;                                                         # oop_digraph                   is from   src/lib/graph/oop-digraph.pkg
    package rwv =  rw_vector;                                                           # rw_vector                     is from   src/lib/std/src/rw-vector.pkg
herein

    # This generic is invoked (only) in:
    #
    #     src/lib/compiler/back/low/main/main/backend-lowhalf-g.pkg
    #
    generic package   machcode_controlflow_graph_viewer_g   (
        #             ==================================
        #
        package mcg: Machcode_Controlflow_Graph;                                        # Machcode_Controlflow_Graph    is from   src/lib/compiler/back/low/mcg/machcode-controlflow-graph.api

        package gv:  Graph_Viewer;                                                      # Graph_Viewer                  is from   src/lib/compiler/back/low/display/graph-viewer.api

        package ae:  Machcode_Codebuffer_Pp                                             # Machcode_Codebuffer_Pp        is from   src/lib/compiler/back/low/emit/machcode-codebuffer-pp.api
                     where                                                              # "ae"  == "asmcode_emitter".
                         mcf == mcg::mcf;                                               # "mcf" == "machcode_form" (abstract machine code).
    )
    : (weak)  api {
                      view_machcode_controlflow_graph:   mcg::Machcode_Controlflow_Graph -> Void;
                  }
    {
        stipulate
            package fmt =  format_instruction_g( ae );
        herein

            view_outline
                =
                lowhalf_control::get_bool
                    "view_outline";

            fun view_machcode_controlflow_graph (machcode_controlflow_graph as odg::DIGRAPH g)
                =
                {   g.graph_info ->   mcg::GRAPH_INFO { notes, ... };
                    #
                    to_string =   fmt::to_string *notes;

                    fun info_fn _ =   [];

                    color_scale
                        = 
                        rwv::from_list
                          ["#ccffff", "#99ffff", "#66ccff", "#54a9ff", "#ccff99", 
                           "#ffff99", "#ffcc66", "#ff9966", "#cc6666", "#d14949",
                           "#d14949"];

                    fun weight_range ([], min, max)
                            =>
                            (min, max-min);

                        weight_range((_, _, mcg::EDGE_INFO { execution_frequency, ... } ) ! rest, min, max)
                            =>
                            {   wt = *execution_frequency;

                                if   (wt > max)  weight_range (rest, min, wt);
                                elif (wt < min)  weight_range (rest, wt, max);
                                else             weight_range (rest, min, max);
                                fi;
                            };
                    end;

                    my (lo_wt, range)
                        =
                        weight_range( g.edges (), -1.0, -1.0);

                    fun color w
                        =
                        {   pos = if (range < 100.0)   floor(((w-lo_wt)             * 10.0) / range);
                                  else                 floor (math::log10 (w-lo_wt) * 10.0  / math::log10 range);
                                  fi;

                            rwv::get (color_scale, pos);
                        };

                    entry = head (g.entries ());
                    exit  = head (g.exits   ());

                    red    = glo::COLOR "#ff0000"; 
                    yellow = glo::COLOR "yellow";
                    green  = glo::COLOR "green";

                    fun edge_fn (i, j, mcg::EDGE_INFO { execution_frequency, ... } )
                        = 
                        {   label =  glo::LABEL (f8b::to_string  *execution_frequency);
                            #
                            [ label, glo::COLOR (color *execution_frequency) ]; 
                        };

                    fun title (blknum, REF freq)
                        = 
                        " " + int::to_string blknum + " freq=" + f8b::to_string freq;

                    fun ann  notes
                        = 
                        list::fold_forward (\\ (a, l) = "/* " + note::to_string a + " */\n" + l)
                                        ""
                                        *notes;

                    fun node_fn (_, mcg::BBLOCK { kind, labels, id, execution_frequency, ops, notes, ... } )
                        = 
                        case kind
                            #
                            mcg::START
                                => 
                                [glo::LABEL("entry" + title (id, execution_frequency) + "\n" + ann  notes)];

                            mcg::STOP
                                => 
                                [glo::LABEL("exit" + title (id, execution_frequency))];

                            _ => 
                                [ glo::LABEL
                                    (   "BLK"
                                    +   title (id, execution_frequency)
                                    +   "\n"

                                    +   case *labels
                                            #
                                            [] =>  "";
                                            #
                                            codelabels
                                                =>
                                                string::join
                                                    ":\n"
                                                    (map  lbl::codelabel_to_string  codelabels)   +   ":\n";
                                        esac

                                    +   ann notes

                                    +   if *view_outline
                                            "";
                                        else
                                            list::fold_forward 
                                               (\\ (i, t) =  {   text = to_string i;

                                                                 text == ""   ??                t
                                                                              ::  text + "\n" + t;
                                                             }
                                               ) 
                                               "" 
                                               *ops;
                                        fi
                                    )
                                ];
                        esac;



                   gv::view
                        (glo::make_layout { info_fn, edge_fn, node_fn } machcode_controlflow_graph);
                };
        end;
    };
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext