2 * This file is part of libFirm.
3 * Copyright (C) 2012 University of Karlsruhe.
8 * @brief Code for dumping backend datastructures (i.e. interference graphs)
9 * @author Matthias Braun
18 #include "becopyopt_t.h"
21 static void dump_ifg_nodes(FILE *F, const be_ifg_t *ifg)
23 nodes_iter_t ifg_iter;
24 be_ifg_foreach_node(ifg, &ifg_iter, node) {
29 static void dump_ifg_edges(FILE *F, const be_ifg_t *ifg)
31 nodes_iter_t ifg_iter;
33 be_ifg_foreach_node(ifg, &ifg_iter, node) {
34 neighbours_iter_t neigh_iter;
36 be_ifg_foreach_neighbour(ifg, &neigh_iter, node, neighbour) {
37 /* interference is bidirectional, but it's enough to dump 1
39 if (get_irn_node_nr(node) >= get_irn_node_nr(neighbour))
42 fprintf(F, "edge: {sourcename: ");
43 print_nodeid(F, node);
44 fprintf(F, " targetname: ");
45 print_nodeid(F, neighbour);
46 fprintf(F, " arrowstyle:none class:1}\n");
51 void be_dump_ifg(FILE *F, ir_graph *irg, const be_ifg_t *ifg)
54 "graph: { title: \"interference graph of %+F\"\n"
55 "layoutalgorithm: mindepth //$ \"circular\"\n"
56 "classname 1: \"interference\"\n"
58 dump_vcg_infonames(F);
59 dump_vcg_header_colors(F);
61 dump_ifg_nodes(F, ifg);
62 dump_ifg_edges(F, ifg);
67 static void dump_affinity_edges(FILE *F, const copy_opt_t *co,
68 bool dump_costs, bool dump_colors)
70 co_gs_foreach_aff_node(co, a) {
71 co_gs_foreach_neighb(a, n) {
72 /* edges are bidirection, dumping one direction is enough */
73 if (get_irn_node_nr(a->irn) >= get_irn_node_nr(n->irn))
76 fprintf(F, "edge: {sourcename: ");
77 print_nodeid(F, a->irn);
78 fprintf(F, " targetname: ");
79 print_nodeid(F, n->irn);
80 fprintf(F, " arrowstyle:none");
83 fprintf(F, " label:\"%d\"", n->costs);
85 const arch_register_t *ar = arch_get_irn_register(a->irn);
86 const arch_register_t *nr = arch_get_irn_register(n->irn);
87 const char *color = nr == ar ? "blue" : "red";
88 fprintf(F, " color:%s", color);
90 fprintf(F, " linestyle:dashed class:2");
96 void be_dump_ifg_co(FILE *F, const copy_opt_t *co, bool dump_costs,
99 ir_graph *irg = co->irg;
100 be_ifg_t *ifg = co->cenv->ifg;
103 "graph: { title: \"interference graph of %+F\"\n"
104 "layoutalgorithm: mindepth //$ \"circular\"\n"
105 "classname 1: \"interference\"\n"
106 "classname 2: \"affinity\"\n"
108 dump_vcg_infonames(F);
109 dump_vcg_header_colors(F);
111 dump_ifg_nodes(F, ifg);
112 dump_ifg_edges(F, ifg);
113 dump_affinity_edges(F, co, dump_costs, dump_colors);
118 static const char *lv_flags_to_str(unsigned flags)
120 static const char *states[] = {
131 return states[flags & 7];
134 void be_dump_liveness_block(be_lv_t *lv, FILE *F, const ir_node *bl)
136 be_lv_info_t *info = ir_nodehashmap_get(be_lv_info_t, &lv->map, bl);
138 fprintf(F, "liveness:\n");
140 unsigned n = info[0].head.n_members;
143 for (i = 0; i < n; ++i) {
144 be_lv_info_node_t *n = &info[i+1].node;
145 ir_fprintf(F, "%s %+F\n", lv_flags_to_str(n->flags), n->node);
150 typedef struct lv_walker_t {
155 static void lv_dump_block_walker(ir_node *irn, void *data)
157 lv_walker_t *w = (lv_walker_t*)data;
160 be_dump_liveness_block(w->lv, w->out, irn);
163 void be_liveness_dump(FILE *F, const be_lv_t *lv)
167 w.lv = (be_lv_t *) lv;
169 irg_block_walk_graph(lv->irg, lv_dump_block_walker, NULL, &w);