## print-machcode-controlflow-graph-g.pkg -- print flowgraph of target machine instructions.
# Compiled by:
#
src/lib/compiler/back/low/lib/lowhalf.libstipulate
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.pkgherein
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.