5 * File name: ir/ana/ecg.c
6 * Purpose: Extended Call Graph
11 * Copyright: (c) 1999-2004 Universität Karlsruhe
12 * Licence: This file is protected by the GPL - GNU GENERAL PUBLIC LICENSE.
20 Erweiterter Aufrufgraph.
25 /* #include "eset.h" */
35 # endif /* not defined TRUE */
37 # define BUF_SIZE 1024
40 # include "typalise.h"
46 /* static int verbose = 0; */
47 static int do_typalise = 0;
53 /* Ids for the ctxs */
54 static int ctx_id = 0;
55 ctx_info_t *main_ctx = NULL;
57 /* mapping from method graphs (callR) to method graphs (lset_ts of callEds) */
58 /* static pmap *calls; */
59 static pmap *graph_infos;
61 /* linked list of all graph_infos: */
62 static graph_info_t *graph_infos_list = NULL;
64 /* Counters for ecg_ecg and friends */
65 static long _graphs = 0;
66 static long _calls = 0;
67 static long _allocs = 0;
69 static int _depth = 0;
70 static int _max_depth = 0;
72 static int _max_callEds = 0;
73 static entity* _max_callEds_callR = NULL;
76 void set_main_ctx (ctx_info_t*);
78 /* ====================
80 ==================== */
81 static void append_alloc (graph_info_t *ginfo, ir_node *alloc, type *tp)
83 alloc_info_t *ainfo = (alloc_info_t*) xmalloc (sizeof (alloc_info_t));
85 ainfo->graph = ginfo->graph;
89 ainfo->prev = ginfo->allocs;
90 ginfo->allocs = ainfo;
94 /* ====================
96 ==================== */
98 Append the given callEd to the given callEd info.
100 static callEd_info_t *append_callEd_info (callEd_info_t *ced, ir_graph *callEd)
102 callEd_info_t *nced = (callEd_info_t*) xmalloc (sizeof (sizeof (callEd_info_t)));
104 nced->callEd = callEd;
111 Append all callEd methods of the given (call) node to the given graph_info.
113 static void append_calls (graph_info_t *info, ir_node *call, lset_t *callEds)
115 call_info_t *cinfo = (call_info_t*) xmalloc (sizeof (call_info_t));
119 cinfo->prev = info->calls;
121 cinfo->callEds = NULL;
124 ir_graph *callEd = lset_first (callEds);
126 cinfo->callEds = append_callEd_info (cinfo->callEds, callEd);
128 callEd = lset_next (callEds);
133 Append the (single) callEd to the given (call) node of the given graph_info.
135 static void append_call (graph_info_t *info, ir_node *call, ir_graph *callEd)
137 call_info_t *cinfo = (call_info_t*) xmalloc (sizeof (call_info_t));
140 cinfo->prev = info->calls;
143 cinfo->callEds = append_callEd_info (cinfo->callEds, callEd);
147 Given a method, find the firm graph that implements that method.
148 Return NULL for abstract and native methods.
150 static ir_graph *_get_implementing_graph (entity *method)
152 ir_graph *graph = NULL;
154 /* What's up with the fenced out stuff in rta? */
155 if (peculiarity_existent == get_entity_peculiarity (method)) {
156 if (visibility_external_allocated == get_entity_visibility (method)) {
157 /* Todo: native implementation */
161 graph = get_entity_irg (get_SymConst_entity (get_atomic_ent_value (method)));
162 assert (graph && "no graph");
166 } else if (0 && (peculiarity_description == get_entity_peculiarity (method))) {
167 /* abstract --- can't find an implementation */
168 graph = get_entity_irg (method);
169 assert (!graph && "graph in abstract method");
172 } else if ((peculiarity_description == get_entity_peculiarity (method)) ||
173 (peculiarity_inherited == get_entity_peculiarity (method))) {
176 int n_over = get_entity_n_overwrites (method);
180 for (i = 0; (NULL == graph) && (i < n_over); i ++) {
181 entity *over = get_entity_overwrites (method, i);
183 graph = _get_implementing_graph (over);
186 assert (0 && "invalid peculiarity");
194 Collect all graphs of 'method' in the given set.
196 static void _collect_implementing_graphs (entity *method, lset_t *set)
198 /* search DOWN-wards in clazz hierarchy */
200 int n_over = get_entity_n_overwrittenby (method);
201 ir_graph *graph = get_entity_irg (method);
204 graph = _get_implementing_graph (method);
208 lset_insert (set, graph);
211 for (i = 0; i < n_over; i ++) {
212 entity *over = get_entity_overwrittenby (method, i);
214 _collect_implementing_graphs (over, set);
220 Collect all graphs that could possibly be executed when 'method' is called.
222 static lset_t *get_implementing_graphs (entity *method, ir_node *select)
224 lset_t *set = lset_create ();
226 ir_graph *impl = _get_implementing_graph (method);
229 lset_insert (set, impl);
231 /* actually, abstract OR native */
235 _collect_implementing_graphs (method, set);
237 if (lset_empty (set)) {
238 /* then it's a method which is only implemented natively, and we
239 don' bother to analyse anything */
243 /* void *tmp = lset_first (set); */
244 int n_graphs = lset_n_entries (set);
246 /* typalise select_in */
248 ir_node *select_in = get_Sel_ptr (select);
249 typalise_t *ta = typalise (select_in);
250 assert (ta && "typalise failed (go figure)");
252 /* const char *res = ta_name (ta); */
254 /* fprintf (stdout, "typalyse res = %s\n", res); */
257 set = filter_for_ta (set, ta);
259 int n_filtered_graphs = lset_n_entries (set);
262 fprintf (stdout, "%s: %02d %02d\n",
266 n_graphs - n_filtered_graphs);
268 n_graphs = n_filtered_graphs;
272 if (n_graphs > _max_callEds) {
273 _max_callEds = n_graphs;
274 _max_callEds_callR = method;
278 if (visibility_external_allocated != get_entity_visibility (method)) {
280 /* fprintf (stdout, "no graphs for method %s\n", get_entity_name (method)); */
281 assert (n_graphs && "no graphs for method");
289 Action for the graph.
291 static void ecg_calls_act (ir_node *node, void *env)
293 opcode op = get_irn_opcode (node);
294 graph_info_t *graph_info = (graph_info_t*) env;
296 if (iro_Call == op) { /* CALL */
298 ir_node *ptr = get_Call_ptr (node);
301 if (iro_Sel == get_irn_opcode (ptr)) {
302 ent = get_Sel_entity (ptr);
303 lset_t *graphs = get_implementing_graphs (ent, ptr);
305 append_calls (graph_info, node, graphs);
306 } else if (iro_SymConst == get_irn_opcode (ptr)) {
307 if (get_SymConst_kind (ptr) == symconst_addr_ent) {
308 ent = get_SymConst_entity (ptr);
309 ir_graph *graph = get_entity_irg (ent);
312 append_call (graph_info, node, graph);
314 /* it's an externally allocated thingy */
316 } else if (get_SymConst_kind (ptr) == symconst_addr_name) {
317 /* If this SymConst refers to a method the method is external_visible
318 and therefore must be considered live anyways. */
319 if (get_SymConst_name (ptr) != new_id_from_str ("iro_Catch")) {
320 assert (ent && "couldn't determine entity of call to symConst");
323 /* other symconst. */
324 assert (0 && "This SymConst can not be an address for a method call.");
327 /* STRANGE, no less ... */
330 assert (0 && "Unexpected address expression");
332 } else if (iro_Alloc == op) {
333 type *tp = get_Alloc_type (node);
334 /* const char *name = get_type_name (tp); */
336 append_alloc (graph_info, node, tp);
338 /* fprintf (stdout, "NEW \"%s\"\n", name); */
343 Collect called graphs for the given graph.
345 static void ecg_fill_graph_calls (ir_graph *graph)
347 graph_info_t *graph_info = (graph_info_t*) xmalloc (sizeof (graph_info_t));
349 graph_info->graph = graph;
350 graph_info->calls = NULL;
351 graph_info->ecg_seen = 0;
352 graph_info->ctxs = NULL;
353 graph_info->n_ctxs = 0;
355 /* link up into global list */
356 graph_info->prev = graph_infos_list;
357 graph_infos_list = graph_info;
359 irg_walk_graph (graph, ecg_calls_act, NULL, graph_info);
361 pmap_insert (graph_infos, graph, graph_info);
365 For each graph, collect called graphs, and enter them into calls.
367 static void ecg_fill_calls (void)
371 for (i = 0; i < get_irp_n_irgs (); i++) {
372 ir_graph *graph = get_irp_irg (i);
374 ecg_fill_graph_calls (graph);
379 Allocate a new ctx for the given graph and the given enclosing ctx.
381 static ctx_info_t *new_ctx (ir_graph *graph, ir_node *call, ctx_info_t *enc)
383 ctx_info_t *res = xmalloc (sizeof (ctx_info_t));
395 Fill in the ctxs parts of the graph_infos
397 static void ecg_fill_ctxs_count (ir_graph *graph)
399 graph_info_t *ginfo = ecg_get_info (graph);
401 /* count how many ctxs we have per graph */
402 if (0 == ginfo->ecg_seen) {
405 call_info_t *cinfo = ginfo->calls;
407 while (NULL != cinfo) {
408 callEd_info_t *ced = cinfo->callEds;
410 while (NULL != ced) {
411 ir_graph *callEd_graph = ced->callEd;
413 /* first step: we have a new ctx */
414 graph_info_t *callEd_info = ecg_get_info (callEd_graph);
415 callEd_info->n_ctxs ++;
417 /* Calling graph -> callEd_graph */
418 ecg_fill_ctxs_count (callEd_graph);
421 } /* end forall callEds (call) */
424 } /* end forall (calls(graph)) */
430 static void ecg_fill_ctxs_alloc (void)
432 /* allocate the memory needed for the ctxts: */
433 graph_info_t *ginfo = graph_infos_list;
435 while (NULL != ginfo) {
436 ginfo->ctxs = (ctx_info_t **) xmalloc (ginfo->n_ctxs * sizeof (ctx_info_t*));
439 fprintf (stdout, "graph of \"%s\": n_ctxs = %i\n",
440 get_entity_name (get_irg_entity (ginfo->graph)), ginfo->n_ctxs);
449 Fill in the ctxs parts of the graph_infos
451 static void ecg_fill_ctxs_write (ir_graph *graph, ctx_info_t *enc_ctx)
453 graph_info_t *ginfo = ecg_get_info (graph);
455 /* enter a new ctx for all callEds along the call edges of this graph */
456 if (0 == ginfo->ecg_seen) {
458 call_info_t *cinfo = ginfo->calls;
460 while (NULL != cinfo) {
461 callEd_info_t *ced = cinfo->callEds;
463 while (NULL != ced) {
464 ctx_info_t *ctx = new_ctx (graph, cinfo->call, enc_ctx);
466 ir_graph *callEd_graph = ced->callEd;
468 /* write the ctx of this call into the callEd graph */
469 graph_info_t *callEd_info = ecg_get_info (callEd_graph);
471 callEd_info->ctxs [callEd_info->n_ctxs] = ctx;
472 callEd_info->n_ctxs ++;
474 /* Calling graph -> callEd_graph */
475 ecg_fill_ctxs_write (callEd_graph, ctx);
478 } /* end forall callEds (call) */
481 } /* end forall (calls(graph)) */
488 Fill in the ctxs parts of the graph_infos
490 static void ecg_fill_ctxs (void)
492 ecg_fill_ctxs_count (get_irp_main_irg ());
493 ecg_fill_ctxs_alloc ();
495 ctx_info_t *main_ctx = new_ctx (get_irp_main_irg (), NULL, NULL);
496 ir_graph *main_irg = get_irp_main_irg ();
498 set_main_ctx (main_ctx);
500 /* Grrr, have to add this ctx manually to main.ginfo ... */
501 graph_info_t *ginfo = ecg_get_info (main_irg);
503 ginfo->ctxs = (ctx_info_t **) xmalloc (1 * sizeof (ctx_info_t*));
504 ginfo->ctxs [0] = main_ctx;
506 ecg_fill_ctxs_write (main_irg, main_ctx);
509 /* ====================
511 ==================== */
513 Nicely print a ctx_info_t to the given output stream
515 void ecg_print_ctx (ctx_info_t *ctx, FILE *stream)
517 entity *ent = get_irg_ent (ctx->graph);
518 ir_node *call = ctx->call;
519 const char *ent_name = (char*) get_entity_name (ent);
520 const char *own_name = (char*) get_type_name (get_entity_owner (ent));
522 fprintf (stream, "CTX[%i](%s.%s->%s[%li])",
523 ctx->id, own_name, ent_name,
524 get_op_name (get_irn_op (call)),
525 get_irn_node_nr (call));
527 if (NULL != ctx->enc) {
528 fprintf (stream, "->%i", ctx->enc->id);
531 fprintf (stream, "\n");
535 Get a ctx of the given graph info
537 ctx_info_t *get_ctx (graph_info_t *ginfo, int ctx_idx)
539 assert (ginfo->n_ctxs > ctx_idx);
541 return (ginfo->ctxs [ctx_idx]);
545 Get the pseudo-ctx of 'main'
547 ctx_info_t *get_main_ctx ()
553 Set the pseudo-ctx of 'main'
555 void set_main_ctx (ctx_info_t *ctx)
561 /* ====================
563 ==================== */
565 /* ====================
567 ==================== */
569 Iterate over all graphs
571 void ecg_iterate_graphs (graph_hnd_t *hnd, void *env)
573 graph_info_t *ginfo = graph_infos_list;
575 while (NULL != ginfo) {
584 Iterate of all allocs of a given graph info
586 void ecg_iterate_allocs (graph_info_t *ginfo, alloc_hnd_t *hnd, void *env)
588 alloc_info_t *ainfo = ginfo->allocs;
590 while (NULL != ainfo) {
599 Iterate over all calls of the given graph info
601 void ecg_iterate_calls (graph_info_t *ginfo, call_hnd_t *hnd, void *env)
603 call_info_t *cinfo = ginfo->calls;
605 while (NULL != cinfo) {
614 Iterate over all callEds of the given call info
616 void ecg_iterate_callEds (call_info_t *cinfo, callEd_hnd_t *hnd, void *env)
618 callEd_info_t *ced = cinfo->callEds;
620 while (NULL != ced) {
629 get the call infos for the given graph
631 graph_info_t *ecg_get_info (ir_graph *graph)
633 graph_info_t *ginfo = (graph_info_t*) pmap_get (graph_infos, graph);
635 assert (ginfo && "no info for graph");
641 Get the Alloc Infos for the given graph
643 alloc_info_t *ecg_get_alloc_info (ir_graph *graph)
645 graph_info_t *ginfo = ecg_get_info (graph);
647 return (ginfo->allocs);
651 Get the Call Info for the given call
653 callEd_info_t *ecg_get_callEd_info (ir_node *call)
655 ir_graph *graph = get_irn_irg (call);
656 graph_info_t *ginfo = ecg_get_info (graph);
658 call_info_t *call_info = ginfo->calls;
660 while (NULL != call_info) {
661 if (call == call_info->call) {
662 return (call_info->callEds);
665 call_info = call_info->prev;
673 Dump the given graph and it's calls and it's calls callEds to the given file.
675 static int ecg_ecg_graph (FILE *dot, ir_graph *graph)
677 const char *name = get_irg_entity (graph) ?
678 get_entity_name (get_irg_entity (graph)) : "noEntity";
680 (get_entity_stickyness
681 (get_irg_entity (graph)) == stickyness_sticky) ?
682 "red" : "lightyellow";
684 /* graph_info_t *ginfo = (graph_info_t*) pmap_get (graph_infos, graph); */
685 graph_info_t *ginfo = ecg_get_info (graph);
687 if (0 != ginfo->ecg_seen) {
688 fprintf (dot, "\t/* recursive call to \"%s\" (%d) */\n",
689 name, (int) ginfo->ecg_seen);
691 fprintf (dot, "\t/* recursive call to \"%s\" (0x%08x) */\n",
694 return (ginfo->ecg_seen);
697 assert (0L <= _graphs);
699 const int graph_no = _graphs ++;
700 ginfo->ecg_seen = graph_no;
702 fprintf (dot, "\t/* Graph of \"%s.%s\" */\n",
703 get_type_name (get_entity_owner (get_irg_entity (graph))),
705 fprintf (dot, "\tgraph_%i [label=\"<HEAD>%s\\l%s\\l|<CTX>n_ctx = %i\\l\", color=\"%s\"];\n",
707 get_type_name (get_entity_owner (get_irg_entity (graph))),
713 if (visibility_external_allocated ==
714 get_entity_visibility (get_irg_entity (graph))) {
715 fprintf (dot, "\t/* graph \"%s\" is external */\n", name);
720 call_info_t *cinfo = ginfo->calls;
721 while (NULL != cinfo) {
722 ir_node *call = cinfo->call;
723 callEd_info_t *ced = cinfo->callEds;
724 const int call_no = _calls ++;
725 const char *call_color = (NULL == ced->prev) ? "lightblue" : "blue3";
727 fprintf (dot, "\t/* Call %li */\n", get_irn_node_nr (call));
728 fprintf (dot, "\tcall_%i [label=\"call\\[%li\\]\", color=\"%s\", shape=\"ellipse\"];\n",
729 call_no, get_irn_node_nr (call), call_color);
730 fprintf (dot, "\tgraph_%i -> call_%i [color=\"black\"];\n", graph_no, call_no);
732 while (NULL != ced) {
733 ir_graph *callEd_graph = ced->callEd;
734 const int callEd_no = ecg_ecg_graph (dot, callEd_graph);
735 const char *callEd_name = get_irg_entity (callEd_graph) ?
736 get_entity_name (get_irg_entity (callEd_graph)) : "noEntity";
737 const char *direction = (callEd_no <= graph_no) ? "forward" : "forward";
738 const char *callEd_color = (callEd_no <= graph_no) ? "red" : "black";
740 fprintf (dot, "\t/* Call from graph \"%s\" to graph \"%s\" */\n",
743 /* Check for recursive calls */
744 /* if (callEd_no > graph_no) */ { /* do recursive calls (for now) */
745 fprintf (dot, "\tcall_%i -> graph_%i:HEAD [color=\"%s\", dir=\"%s\"];\n",
746 call_no, callEd_no, callEd_color, direction);
751 } /* done all calEds (call) */
754 } /* done all calls (graph) */
757 alloc_info_t *ainfo = ecg_get_alloc_info (graph);
759 fprintf (dot, "\t/* now the allocs */\n");
761 fprintf (dot, "\t/* no allocs */\n");
764 while (NULL != ainfo) {
765 ir_node *alloc = ainfo->alloc;
766 const char *name = get_type_name (ainfo->tp);
767 const char *color = "red1";
770 fprintf (dot, "\talloc_0x%08x_%i [label=\"%s\", color=\"%s\"];\n",
771 (int) alloc, graph_no, name, color);
773 fprintf (dot, "\tgraph_%i -> alloc_0x%08x_%i;\n",
774 graph_no, (int) alloc, graph_no);
779 if (0 == ginfo->allocs_seen) {
780 ginfo->allocs_seen = 1;
783 /* write table of ctxs */
785 fprintf (dot, "\tctx_%i [label=\"<HEAD>", graph_no);
788 const int max_ctxs = 30;
789 const int n_ctxs = (ginfo->n_ctxs > max_ctxs) ? max_ctxs : ginfo->n_ctxs;
791 assert (ginfo->ctxs && "no ctx");
792 for (i = 0; i < n_ctxs; i ++) {
793 ctx_info_t *ctx_info = ginfo->ctxs [i];
795 if (NULL != ctx_info->enc) {
796 fprintf (dot, "ctx_info \\[%i\\] = ctx\\[%i\\-\\>%i\\]\\l",
801 fprintf (dot, "ctx_info \\[%i\\] = ctx\\[%i\\]\\l",
810 if (0 < ginfo->n_ctxs - max_ctxs) {
811 fprintf (dot, "(%i more)\\l", ginfo->n_ctxs - max_ctxs);
814 fprintf (dot, "\", color=\"green3\"];\n");
817 "\tgraph_%i:CTX -> ctx_%i:HEAD [label=\"ctx\", dir=\"none\", style=\"dotted\"];\n",
821 fprintf (dot, "\t/* done with graph of \"%s\" */\n\n", name);
830 Count how many nodes the ECG will have
832 static char spaces [BUF_SIZE];
834 static void ecg_ecg_count (ir_graph *graph)
836 graph_info_t *ginfo = (graph_info_t*) pmap_get (graph_infos, graph);
838 if (0 != ginfo->ecg_seen) {
843 if (_depth > _max_depth) {
847 fprintf (stdout, "_max_depth = %i\n", _max_depth);
848 fprintf (stdout, "\tn_graphs: %i\n", _graphs);
852 assert (0L <= _graphs);
855 if (0 == (_graphs % 1000000)) {
856 fprintf (stdout, "\tn_graphs: %i\n", _graphs);
857 fprintf (stdout, "_depth = %i\n", _depth);
861 const int graph_no = _graphs ++;
862 ginfo->ecg_seen = graph_no;
864 fprintf (stdout, "%sMethod \"%s.%s\"\n",
865 spaces + BUF_SIZE - _depth,
866 get_type_name (get_entity_owner (get_irg_entity (graph))),
867 get_entity_name (get_irg_entity (graph)));
869 call_info_t *cinfo = ginfo->calls;
870 while (NULL != cinfo) {
872 callEd_info_t *ced = cinfo->callEds;
874 fprintf (stdout, "%sCall \"0x%08x\"\n",
875 spaces + BUF_SIZE - _depth,
878 while (NULL != ced) {
879 ir_graph *callEd_graph = ced->callEd;
881 fprintf (stdout, "%sCall Target \"%s.%s\"\n",
882 spaces + BUF_SIZE - _depth,
883 get_type_name (get_entity_owner (get_irg_entity (callEd_graph))),
884 get_entity_name (get_irg_entity (callEd_graph)));
886 ecg_ecg_count (callEd_graph);
889 } /* done all calEds (call) */
891 } /* done all calls (graph) */
897 /* ====================
899 ==================== */
902 Initialise our data structures.
904 void ecg_init (int typalise)
906 do_typalise = typalise;
908 graph_infos = pmap_create ();
923 for (i = 0; i < get_irp_n_irgs (); i++) {
924 ir_graph *graph = get_irp_irg (i);
926 graph_info_t *info = pmap_get (graph_infos, graph);
927 call_info_t *cinfo = info->calls;
929 while (NULL != cinfo) {
932 callEd_info_t *ced = cinfo->callEds;
934 while (NULL != ced) {
935 callEd_info_t *nced = ced->prev;
942 cinfo->callEds = NULL;
949 pmap_insert (graph_infos, graph, NULL);
953 pmap_destroy (graph_infos);
960 Show what we have found.
966 FILE *dot = fopen ("calls.dot", "w");
968 fprintf (dot, "digraph \"calls\" {\n");
969 fprintf (dot, "\tnode [shape = \"record\", style = \"filled\"];\n");
970 fprintf (dot, "\tedge [color = \"black\"];\n");
972 fprintf (dot, "\tsize = \"11, 7\";\n");
973 fprintf (dot, "\trotate = \"90\";\n");
974 fprintf (dot, "\tratio = \"fill\";\n");
975 fprintf (dot, "\trankdir = \"LR\";\n");
978 for (i = 0; i < get_irp_n_irgs (); i++) {
979 ir_graph *graph = get_irp_irg (i);
980 graph_info_t *info = (graph_info_t*) pmap_get (graph_infos, graph);
982 const char *name = get_irg_entity (graph) ?
983 get_entity_name (get_irg_entity (graph)) : "noEntity";
985 const char *oname = get_type_name
986 (get_entity_owner (get_irg_entity (graph)));
989 (get_entity_stickyness
990 (get_irg_entity (graph)) == stickyness_sticky) ?
991 "red3" : "lightyellow";
993 fprintf (dot, "\t/* graph_0x%08x (\"%s\") */\n", (int) graph, name);
995 "\tgraph_0x%08x [label=\"%s\\l%s\", color=\"%s\"];\n",
996 (int) graph, oname, name, color);
999 call_info_t *cinfo = info->calls;
1001 fprintf (dot, "\t/* now the calls */\n");
1003 fprintf (dot, "\t/* no calls, nothing to see, move along! */\n");
1006 while (NULL != cinfo) {
1007 ir_node *call = cinfo->call;
1009 fprintf (dot, "\t/* call_0x%08x */\n", (int) call);
1010 fprintf (dot, "\tcall_0x%08x [label=\"call\\[%li\\]\\l0x%08x\"];\n",
1011 (int) call, get_irn_node_nr (call), (int) call);
1012 fprintf (dot, "\tgraph_0x%08x -> call_0x%08x;\n",
1013 (int) graph, (int) call);
1015 callEd_info_t *ced = cinfo->callEds;
1016 while (NULL != ced) {
1017 fprintf (dot, "\tcall_0x%08x -> graph_0x%08x;\n",
1018 (int) call, (int) ced->callEd);
1021 fprintf (dot, "\n");
1023 cinfo = cinfo->prev;
1025 fprintf (dot, "\n");
1027 alloc_info_t *ainfo = info->allocs;
1029 fprintf (dot, "\t/* now the allocs */\n");
1031 fprintf (dot, "\t/* no allocs */\n");
1035 while (NULL != ainfo) {
1036 ir_node *alloc = ainfo->alloc;
1037 const char *name = get_type_name (ainfo->tp);
1038 const char *color = "green3";
1040 fprintf (dot, "\talloc_0x%08x [label=\"%s\", color=\"%s\"];\n",
1041 (int) alloc, name, color);
1042 fprintf (dot, "\tgraph_0x%08x -> alloc_0x%08x;\n",
1043 (int) graph, (int) alloc);
1045 ainfo = ainfo->prev;
1048 fprintf (dot, "}\n");
1051 fprintf (stdout, " max_callEds: %i\n", _max_callEds);
1052 fprintf (stdout, " max_callEds_callR: \"%s\"\n",
1053 get_entity_name (_max_callEds_callR));
1059 Experimental: Print the ecg
1066 ir_graph *main_graph = get_irp_main_irg ();
1069 memset (spaces, '.', BUF_SIZE);
1070 spaces [BUF_SIZE-1] = '\0';
1072 ecg_ecg_count (main_graph);
1073 fprintf (stdout, "n_graphs: %i\n", _graphs);
1074 fprintf (stdout, "max_depth = %i\n", _max_depth);
1082 FILE *dot = fopen ("ecg.dot", "w");
1084 fprintf (dot, "digraph \"ecg\" {\n");
1085 fprintf (dot, "\tnode [shape = \"record\", style = \"filled\"];\n");
1086 fprintf (dot, "\tedge [color = \"black\"];\n");
1087 fprintf (dot, "\n");
1088 fprintf (dot, "\tsize = \"11, 7\";\n");
1089 fprintf (dot, "\trotate = \"90\";\n");
1090 fprintf (dot, "\tratio = \"fill\";\n");
1091 fprintf (dot, "\trankdir = \"LR\";\n");
1092 fprintf (dot, "\n");
1094 /* ir_graph *main_graph = get_irp_main_irg (); */
1095 ecg_ecg_graph (dot, main_graph);
1097 fprintf (dot, "\t/* Grand Total: */\n");
1098 fprintf (dot, "\t/* calls: %i */\n", (int) _calls);
1099 fprintf (dot, "\t/* graphs: %i */\n", (int) _graphs);
1100 fprintf (dot, "\t/* allocs: %i */\n", (int) _allocs);
1101 fprintf (dot, "\t/* (sales tax not included) */\n");
1103 fprintf (dot, "}\n");
1112 Revision 1.5 2004/11/20 21:20:29 liekweg
1113 Added iterator functions
1115 Revision 1.4 2004/11/18 16:36:37 liekweg
1116 Added unique ids for debugging, added access functions
1118 Revision 1.3 2004/11/04 14:54:44 liekweg
1121 Revision 1.2 2004/10/21 11:09:37 liekweg
1122 Moved memwalk stuf into irmemwalk
1123 Moved lset stuff into lset
1124 Moved typalise stuff into typalise
1126 Revision 1.1 2004/10/20 14:59:41 liekweg
1127 Added ana2, added ecg and pto
1129 Revision 1.6 2004/10/18 12:47:19 liekweg
1132 Revision 1.5 2004/10/14 11:31:28 liekweg
1135 Revision 1.4 2004/10/12 11:02:01 liekweg