3 #endif /* HAVE_CONFIG_H */
16 #define SEND_BUF_SIZE 256
18 typedef struct _exchange_node_outs_assoc_t {
21 } exchange_node_outs_assoc_t;
23 enum _firm_ycomp_node_realizer_values {
29 NODE_REALIZER_STARTEND,
33 typedef struct _firm_ycomp_node_realizer_t {
35 const char *linecolor;
36 const char *fillcolor;
38 } firm_ycomp_node_realizer_t;
40 static firm_ycomp_node_realizer_t node_realizer[NODE_REALIZER_LAST] = {
41 { NODE_REALIZER_NORMAL, "black", "white", "box" },
42 { NODE_REALIZER_PROJ, "black", "yellow", "box" },
43 { NODE_REALIZER_BLOCK, "black", "yellow", "box" },
44 { NODE_REALIZER_MEM, "black", "blue", "box" },
45 { NODE_REALIZER_PHI, "black", "green", "box" },
46 { NODE_REALIZER_STARTEND, "black", "blue", "box" },
49 enum _firm_ycomp_edge_realizer_values {
57 typedef struct _firm_ycomp_edge_realizer_t {
59 const char *linecolor;
62 } firm_ycomp_edge_realizer_t;
64 static firm_ycomp_edge_realizer_t edge_realizer[EDGE_REALIZER_LAST] = {
65 { EDGE_REALIZER_DATA, "black", 1, "continuous" },
66 { EDGE_REALIZER_MEM, "blue", 1, "continuous" },
67 { EDGE_REALIZER_DEP, "green", 1, "continuous" },
68 { EDGE_REALIZER_CFG, "red", 1, "continuous" },
71 typedef struct _firm_ycomp_dbg_t {
74 pset *exchanged_nodes;
76 hook_entry_t hook_new_irg;
77 hook_entry_t hook_new_irn;
78 hook_entry_t hook_set_edge;
79 hook_entry_t hook_exchange;
82 static firm_ycomp_dbg_t yy_dbg;
84 static int cmp_nodes(const void *a, const void *b) {
85 exchange_node_outs_assoc_t *n1 = *(exchange_node_outs_assoc_t **)a;
86 exchange_node_outs_assoc_t *n2 = *(exchange_node_outs_assoc_t **)b;
88 return n1->irn != n2->irn;
91 static INLINE void send_cmd(const char *buf) {
94 fprintf(stderr, "'%s'\n", buf);
96 res = firmnet_send(yy_dbg.fd, (const void *)buf, len);
100 static void wait_for_sync(void) {
103 firmnet_recv(yy_dbg.fd, buf, 6, 5);
106 static void firm_ycomp_debug_init_realizer(void) {
108 char buf[SEND_BUF_SIZE];
110 for (i = 0; i < NODE_REALIZER_LAST; ++i) {
111 snprintf(buf, sizeof(buf), "addNodeRealizer \"%u\" \"%s\" \"%s\" \"%s\"\n",
113 node_realizer[i].linecolor,
114 node_realizer[i].fillcolor,
115 node_realizer[i].shape);
119 for (i = 0; i < EDGE_REALIZER_LAST; ++i) {
120 snprintf(buf, sizeof(buf), "addEdgeRealizer \"%u\" \"%s\" \"%u\" \"%s\"\n",
122 edge_realizer[i].linecolor,
123 edge_realizer[i].thickness,
124 edge_realizer[i].style);
129 static INLINE unsigned get_node_realizer(ir_node *node) {
131 opcode opc = get_irn_opcode(node);
135 realizer = NODE_REALIZER_BLOCK;
138 realizer = NODE_REALIZER_PHI;
141 if (get_irn_mode(node) == mode_M)
142 realizer = NODE_REALIZER_MEM;
144 realizer = NODE_REALIZER_PROJ;
148 realizer = NODE_REALIZER_STARTEND;
151 realizer = NODE_REALIZER_NORMAL;
157 static INLINE unsigned get_edge_realizer(ir_node *src, ir_node *tgt) {
161 assert(! is_Block(tgt));
163 mode = get_irn_mode(tgt);
166 realizer = EDGE_REALIZER_MEM;
167 else if (mode == mode_X)
168 realizer = EDGE_REALIZER_CFG;
170 realizer = EDGE_REALIZER_DATA;
175 static void firm_ycomp_debug_new_node(void *context, ir_graph *graph, ir_node *node) {
176 char buf[SEND_BUF_SIZE];
178 unsigned src_idx = get_irn_idx(node);
180 if (get_const_code_irg() == graph)
186 ir_snprintf(buf, sizeof(buf), "addNode \"%u\" \"%u\" \"%+F\"\n",
187 src_idx, /* node id */
188 get_node_realizer(node), /* realizerId */
193 for (i = get_irn_arity(node) - 1; i >= 0; --i) {
194 ir_node *pred = get_irn_n(node, i);
195 unsigned tgt_idx = get_irn_idx(pred);
197 ir_snprintf(buf, sizeof(buf), "addEdge \"n%un%up%d\" \"%u\" \"%u\" \"%u\" \"%d\"\n",
198 src_idx, tgt_idx, i, /* edge id */
199 src_idx, /* source node id */
200 tgt_idx, /* target node id */
201 get_edge_realizer(node, pred), /* realizer id */
211 static void firm_ycomp_debug_new_irg(void *context, ir_graph *irg, entity *ent) {
212 if (yy_dbg.has_data) {
213 send_cmd("deleteGraph\n");
221 static void firm_ycomp_debug_set_edge(void *context, ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt) {
222 firm_ycomp_dbg_t *dbg = context;
223 exchange_node_outs_assoc_t *entry, key;
224 char buf[SEND_BUF_SIZE];
225 unsigned src_idx, tgt_idx, old_tgt_idx;
227 /* ignore block edges for now */
232 entry = pset_find(dbg->exchanged_nodes, &key, HASH_PTR(old_tgt));
235 /* we are called from exchange() */
236 entry->n_out_edges--;
239 src_idx = get_irn_idx(src);
240 tgt_idx = get_irn_idx(tgt);
241 old_tgt_idx = get_irn_idx(old_tgt);
243 /* delete the old edge */
244 snprintf(buf, sizeof(buf), "deleteEdge \"n%un%up%d\"\n", src_idx, old_tgt_idx, pos);
247 /* add the new edge */
248 snprintf(buf, sizeof(buf), "addEdge \"n%un%up%d\" \"%u\" \"%u\" \"%u\" \"%d\"\n",
249 src_idx, tgt_idx, pos, /* edge id */
250 src_idx, /* source node id */
251 tgt_idx, /* target node id */
252 get_edge_realizer(src, tgt), /* realizer id */
256 /* show and sync if all edges are rerouted or if it's a normal set_irn_n */
257 if (! entry || entry->n_out_edges == 0) {
264 static void firm_ycomp_debug_exchange(void *context, ir_node *old_node, ir_node *new_node) {
265 firm_ycomp_dbg_t *dbg = context;
266 exchange_node_outs_assoc_t key, *entry;
269 entry = pset_find(dbg->exchanged_nodes, &key, HASH_PTR(old_node));
271 entry->n_out_edges = get_irn_n_edges(old_node);
274 entry = obstack_alloc(&dbg->obst, sizeof(*entry));
275 entry->irn = old_node;
276 entry->n_out_edges = get_irn_n_edges(old_node);
277 pset_insert(dbg->exchanged_nodes, entry, HASH_PTR(old_node));
281 void firm_init_ycomp_debugger(const char *host, uint16_t port) {
282 static int init_once = 0;
287 memset(&yy_dbg, 0, sizeof(yy_dbg));
293 yy_dbg.fd = firmnet_connect_tcp(host, port);
295 if (yy_dbg.fd > -1) {
296 /* We could establish a connection to ycomp -> register hooks */
297 firm_ycomp_debug_init_realizer();
298 yy_dbg.exchanged_nodes = new_pset(cmp_nodes, 20);
299 obstack_init(&yy_dbg.obst);
302 yy_dbg.hook_new_irn.context = &yy_dbg;
303 yy_dbg.hook_new_irn.hook._hook_new_node = firm_ycomp_debug_new_node;
304 register_hook(hook_new_node, &yy_dbg.hook_new_irn);
307 yy_dbg.hook_new_irg.context = &yy_dbg;
308 yy_dbg.hook_new_irg.hook._hook_new_graph = firm_ycomp_debug_new_irg;
309 register_hook(hook_new_graph, &yy_dbg.hook_new_irg);
312 yy_dbg.hook_set_edge.context = &yy_dbg;
313 yy_dbg.hook_set_edge.hook._hook_set_irn_n = firm_ycomp_debug_set_edge;
314 register_hook(hook_set_irn_n, &yy_dbg.hook_set_edge);
316 /* replace (exchange) hook */
317 yy_dbg.hook_exchange.context = &yy_dbg;
318 yy_dbg.hook_exchange.hook._hook_replace = firm_ycomp_debug_exchange;
319 register_hook(hook_replace, &yy_dbg.hook_exchange);
325 void firm_finish_ycomp_debugger(void) {
326 if (yy_dbg.fd > -1) {
327 firmnet_close_socket(yy_dbg.fd);
328 unregister_hook(hook_new_graph, &yy_dbg.hook_new_irg);
329 unregister_hook(hook_new_node, &yy_dbg.hook_new_irn);
330 unregister_hook(hook_set_irn_n, &yy_dbg.hook_set_edge);
331 unregister_hook(hook_replace, &yy_dbg.hook_exchange);
332 del_pset(yy_dbg.exchanged_nodes);
333 yy_dbg.exchanged_nodes = NULL;
334 obstack_free(&yy_dbg.obst, NULL);