PreviousUpNext

15.4.329  src/lib/compiler/back/low/mcg/print-machcode-controlflow-graph-g.pkg

## print-machcode-controlflow-graph-g.pkg -- print flowgraph of target machine instructions. 

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


stipulate
    package fil =  file__premicrothread;                                                # file__premicrothread          is from   src/lib/std/src/posix/file--premicrothread.pkg
    package pp  =  standard_prettyprinter;                                              # standard_prettyprinter        is from   src/lib/prettyprint/big/src/standard-prettyprinter.pkg
herein

    api Print_Machcode_Controlflow_Graph {                                              # Used only within this file.
        #
        package ae: Machcode_Codebuffer_Pp;                                             # Machcode_Codebuffer_Pp        is from   src/lib/compiler/back/low/emit/machcode-codebuffer-pp.api


        package mcg: Machcode_Controlflow_Graph                                         # Machcode_Controlflow_Graph    is from   src/lib/compiler/back/low/mcg/machcode-controlflow-graph.api
                     where
                          mcf == ae::mcf                                                # "mcf" == "machcode_form" (abstract machine code).
                     also pop == ae::cst::pop;                                          # "pop" == "psuedo_op".


        maybe_prettyprint_machcode_controlflow_graph
            :
            Null_Or(pp::Prettyprinter)
            ->
            String
            ->
            mcg::Machcode_Controlflow_Graph
            ->
            Void;
    };
end;

stipulate
    package fil =  file__premicrothread;                                                # file__premicrothread                  is from   src/lib/std/src/posix/file--premicrothread.pkg
    package odg =  oop_digraph;                                                         # oop_digraph                           is from   src/lib/graph/oop-digraph.pkg
    package pp  =  standard_prettyprinter;                                              # standard_prettyprinter                is from   src/lib/prettyprint/big/src/standard-prettyprinter.pkg
    package ptf =  sfprintf;                                                            # sfprintf                              is from   src/lib/src/sfprintf.pkg
    package rkj =  registerkinds_junk;                                                  # registerkinds_junk                    is from   src/lib/compiler/back/low/code/registerkinds-junk.pkg

    Npp = pp::Npp;                                                                      # Null_Or(pp::Prettyprinter)
herein

    # This generic is invoked in:
    #
    #     src/lib/compiler/back/low/main/main/backend-lowhalf-g.pkg
    #     src/lib/compiler/back/low/intel32/regor/regor-intel32-g.pkg
    #
    generic package   print_machcode_controlflow_graph_g   (
        #             =================================
        #
        package ae:   Machcode_Codebuffer_Pp;                                           # Machcode_Codebuffer_Pp                is from   src/lib/compiler/back/low/emit/machcode-codebuffer-pp.api

        package mcg:  Machcode_Controlflow_Graph                                        # Machcode_Controlflow_Graph            is from   src/lib/compiler/back/low/mcg/machcode-controlflow-graph.api
                      where
                           mcf == ae::mcf                                               # "mcf" == "machcode_form" (abstract machine code).
                      also pop == ae::cst::pop;                                         # "pop" == "pseudo_op".
    )
    : (weak)  Print_Machcode_Controlflow_Graph                                          # Print_Machcode_Controlflow_Graph      is from   src/lib/compiler/back/low/mcg/print-machcode-controlflow-graph-g.pkg
    {
        # Export to client packages:
        #       
        package ae  = ae;
        package mcg = mcg;

        stipulate
            i2s = int::to_string;

            fun print_list stream list
                =
                iter list
                where
                    fun pr str
                        =
                        fil::write (stream, str);

                    fun iter []      => ();
                        iter [i]     => pr i;
                        iter (h ! t) => { pr (h + ", "); iter t;};
                    end;
                end;
        herein



            fun maybe_prettyprint_machcode_controlflow_graph  (npp:Npp)  title  (mcg' as odg::DIGRAPH mcg)
                = 
                case npp
                    #
                    NULL => ();

                    THE pp =>
                        {
                            fun pr txt
                                =
                                pp.txt txt;

                            fun pr_list list
                                =
                                iter list
                                where
                                    fun iter []      => ();
                                        iter [i]     => pr i;
                                        iter (h ! t) => { pr (h + ", "); iter t;};
                                    end;
                                end;


                            global_graph_notes = *(mcg::get_global_graph_notes mcg');

                            pp.flush ();

                            buf =  ae::make_codebuffer  pp  global_graph_notes;

                            fun show_freq (REF w)
                                =
                                sprintf "[%f]" w; 

                            fun show_edge (blknum, e)
                                = 
                                sprintf "%d:%s" blknum (mcg::show_edge_info e);

                            fun show_out_edge (_, x, e) =  show_edge (x, e);
                            fun show_in_edge  (x, _, e) =  show_edge (x, e); 

                            fun show_out_edges b
                                =
                                {   pr "\tout-edges:     "; 
                                    pr_list (map show_out_edge (mcg.out_edges b)); 
                                    pr "\n";
                                };

                            fun show_in_edges b
                                =
                                {   pr "\tin-edges:     "; 
                                    pr_list (map show_in_edge (mcg.in_edges b)); 
                                    pr "\n";
                                };

                            fun print_block (_, mcg::BBLOCK { kind=>mcg::START, id, execution_frequency, ... } )
                                    => 
                                    {   pr (sprintf "ENTRY %d %s\n" id (show_freq execution_frequency));
                                        show_out_edges id;
                                    };
                                print_block(_, mcg::BBLOCK { kind=>mcg::STOP, id, execution_frequency, ... } )
                                    => 
                                    {   pr (sprintf "EXIT %d %s\n" id (show_freq execution_frequency));
                                        show_in_edges id;
                                    };

                                print_block(_, mcg::BBLOCK { id, alignment_pseudo_op, execution_frequency, ops, notes, labels, ... } )
                                    => 
                                    {   pr (sprintf "BLOCK %d %s\n" id (show_freq execution_frequency));
                                        #
                                        case *alignment_pseudo_op
                                            #
                                            THE p =>  pr (mcg::pop::pseudo_op_to_string p + "\n");
                                            NULL  =>  ();
                                        esac;

                                        apply  buf.put_bblock_note    *notes;
                                        apply  buf.put_private_label  *labels;

                                        # pr ("\tlive in:  " + rkj::cls::register_to_string *live_in  + "\n");
                                        # pr ("\tlive out: " + rkj::cls::register_to_string *live_out + "\n");

                                        show_out_edges id;
                                        show_in_edges id;
                                        apply  buf.put_op  (reverse *ops);
                                    };
                            end;

                            fun print_data ()
                                =
                                {   mcg.graph_info ->   mcg::GRAPH_INFO { dataseg_pseudo_ops, ... };
                                    #
                                    list::apply
                                        (pr o mcg::pop::pseudo_op_to_string)
                                        (reverse *dataseg_pseudo_ops);
                                };

                            pr (sprintf "[ %s ]\n" title);

                            apply   buf.put_bblock_note   global_graph_notes;

#                           print_block entry; 

                            mcg.forall_nodes print_block;

#                           print_block exit; 

                            print_data ();

                            pp.flush ();
                        };                                      # fun maybe_prettyprint_machcode_controlflow_graph
                esac;
        end;
    };
end;


## Copyright (c) 1997 Bell Laboratories.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext