PR tree-optimization/66718
[official-gcc.git] / gcc / sel-sched-dump.c
blobbc1cdadaf5ea79fdb61ba75fe458cc63c611266e
1 /* Instruction scheduling pass. Log dumping infrastructure.
2 Copyright (C) 2006-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "rtl.h"
25 #include "df.h"
26 #include "diagnostic-core.h"
27 #include "tm_p.h"
28 #include "regs.h"
29 #include "flags.h"
30 #include "insn-config.h"
31 #include "insn-attr.h"
32 #include "params.h"
33 #include "alloc-pool.h"
34 #include "cselib.h"
35 #include "target.h"
37 #ifdef INSN_SCHEDULING
38 #include "regset.h"
39 #include "sched-int.h"
40 #include "cfgloop.h"
41 #include "sel-sched-ir.h"
42 #include "sel-sched-dump.h"
45 /* These variables control high-level pretty printing. */
46 static int sel_dump_cfg_flags = SEL_DUMP_CFG_FLAGS;
47 static int sel_debug_cfg_flags = SEL_DUMP_CFG_FLAGS;
49 /* True when a cfg should be dumped. */
50 static bool sel_dump_cfg_p;
52 /* Variables that are used to build the cfg dump file name. */
53 static const char * const sel_debug_cfg_root = "./";
54 static const char * const sel_debug_cfg_root_postfix_default = "";
55 static const char *sel_debug_cfg_root_postfix = "";
56 static int sel_dump_cfg_fileno = -1;
57 static int sel_debug_cfg_fileno = -1;
59 /* When this flag is on, we are dumping to the .dot file.
60 When it is off, we are dumping to log.
61 This is useful to differentiate formatting between log and .dot
62 files. */
63 bool sched_dump_to_dot_p = false;
65 /* Controls how insns from a fence list should be dumped. */
66 static int dump_flist_insn_flags = (DUMP_INSN_UID | DUMP_INSN_BBN
67 | DUMP_INSN_SEQNO);
70 /* The variable used to hold the value of sched_dump when temporarily
71 switching dump output to the other source, e.g. the .dot file. */
72 static FILE *saved_sched_dump = NULL;
74 /* Switch sched_dump to TO. It must not be called twice. */
75 static void
76 switch_dump (FILE *to)
78 gcc_assert (saved_sched_dump == NULL);
80 saved_sched_dump = sched_dump;
81 sched_dump = to;
84 /* Restore previously switched dump. */
85 static void
86 restore_dump (void)
88 sched_dump = saved_sched_dump;
89 saved_sched_dump = NULL;
93 /* Functions for dumping instructions, av sets, and exprs. */
95 /* Default flags for dumping insns. */
96 static int dump_insn_rtx_flags = DUMP_INSN_RTX_UID | DUMP_INSN_RTX_PATTERN;
98 /* Default flags for dumping vinsns. */
99 static int dump_vinsn_flags = (DUMP_VINSN_INSN_RTX | DUMP_VINSN_TYPE
100 | DUMP_VINSN_COUNT);
102 /* Default flags for dumping expressions. */
103 static int dump_expr_flags = DUMP_EXPR_ALL;
105 /* Default flags for dumping insns when debugging. */
106 static int debug_insn_rtx_flags = DUMP_INSN_RTX_ALL;
108 /* Default flags for dumping vinsns when debugging. */
109 static int debug_vinsn_flags = DUMP_VINSN_ALL;
111 /* Default flags for dumping expressions when debugging. */
112 static int debug_expr_flags = DUMP_EXPR_ALL;
114 /* Controls how an insn from stream should be dumped when debugging. */
115 static int debug_insn_flags = DUMP_INSN_ALL;
117 /* Print an rtx X. */
118 void
119 sel_print_rtl (rtx x)
121 print_rtl_single (sched_dump, x);
124 /* Dump insn INSN honoring FLAGS. */
125 void
126 dump_insn_rtx_1 (rtx insn, int flags)
128 int all;
130 /* flags == -1 also means dumping all. */
131 all = (flags & 1);;
132 if (all)
133 flags |= DUMP_INSN_RTX_ALL;
135 sel_print ("(");
137 if (flags & DUMP_INSN_RTX_UID)
138 sel_print ("%d;", INSN_UID (insn));
140 if (flags & DUMP_INSN_RTX_PATTERN)
141 sel_print ("%s;", str_pattern_slim (PATTERN (insn)));
143 if (flags & DUMP_INSN_RTX_BBN)
145 basic_block bb = BLOCK_FOR_INSN (insn);
147 sel_print ("bb:%d;", bb != NULL ? bb->index : -1);
150 sel_print (")");
154 /* Dump INSN with default flags. */
155 void
156 dump_insn_rtx (rtx insn)
158 dump_insn_rtx_1 (insn, dump_insn_rtx_flags);
162 /* Dump INSN to stderr. */
163 DEBUG_FUNCTION void
164 debug_insn_rtx (rtx insn)
166 switch_dump (stderr);
167 dump_insn_rtx_1 (insn, debug_insn_rtx_flags);
168 sel_print ("\n");
169 restore_dump ();
172 /* Dump vinsn VI honoring flags. */
173 void
174 dump_vinsn_1 (vinsn_t vi, int flags)
176 int all;
178 /* flags == -1 also means dumping all. */
179 all = flags & 1;
180 if (all)
181 flags |= DUMP_VINSN_ALL;
183 sel_print ("(");
185 if (flags & DUMP_VINSN_INSN_RTX)
186 dump_insn_rtx_1 (VINSN_INSN_RTX (vi), dump_insn_rtx_flags | all);
188 if (flags & DUMP_VINSN_TYPE)
189 sel_print ("type:%s;", GET_RTX_NAME (VINSN_TYPE (vi)));
191 if (flags & DUMP_VINSN_COUNT)
192 sel_print ("count:%d;", VINSN_COUNT (vi));
194 if (flags & DUMP_VINSN_COST)
196 int cost = vi->cost;
198 if (cost != -1)
199 sel_print ("cost:%d;", cost);
202 sel_print (")");
205 /* Dump vinsn VI with default flags. */
206 void
207 dump_vinsn (vinsn_t vi)
209 dump_vinsn_1 (vi, dump_vinsn_flags);
212 DEBUG_FUNCTION void
213 debug (vinsn_def &ref)
215 switch_dump (stderr);
216 dump_vinsn_1 (&ref, dump_vinsn_flags);
217 sel_print ("\n");
218 restore_dump ();
221 DEBUG_FUNCTION void
222 debug (vinsn_def *ptr)
224 if (ptr)
225 debug (*ptr);
226 else
227 fprintf (stderr, "<nil>\n");
230 DEBUG_FUNCTION void
231 debug_verbose (vinsn_def &ref)
233 switch_dump (stderr);
234 dump_vinsn_1 (&ref, debug_vinsn_flags);
235 sel_print ("\n");
236 restore_dump ();
239 DEBUG_FUNCTION void
240 debug_verbose (vinsn_def *ptr)
242 if (ptr)
243 debug (*ptr);
244 else
245 fprintf (stderr, "<nil>\n");
248 /* Dump vinsn VI to stderr. */
249 DEBUG_FUNCTION void
250 debug_vinsn (vinsn_t vi)
252 switch_dump (stderr);
253 dump_vinsn_1 (vi, debug_vinsn_flags);
254 sel_print ("\n");
255 restore_dump ();
258 /* Dump EXPR honoring flags. */
259 void
260 dump_expr_1 (expr_t expr, int flags)
262 int all;
264 /* flags == -1 also means dumping all. */
265 all = flags & 1;
266 if (all)
267 flags |= DUMP_EXPR_ALL;
269 sel_print ("[");
271 if (flags & DUMP_EXPR_VINSN)
272 dump_vinsn_1 (EXPR_VINSN (expr), dump_vinsn_flags | all);
274 if (flags & DUMP_EXPR_SPEC)
276 int spec = EXPR_SPEC (expr);
278 if (spec != 0)
279 sel_print ("spec:%d;", spec);
282 if (flags & DUMP_EXPR_USEFULNESS)
284 int use = EXPR_USEFULNESS (expr);
286 if (use != REG_BR_PROB_BASE)
287 sel_print ("use:%d;", use);
290 if (flags & DUMP_EXPR_PRIORITY)
291 sel_print ("prio:%d;", EXPR_PRIORITY (expr));
293 if (flags & DUMP_EXPR_SCHED_TIMES)
295 int times = EXPR_SCHED_TIMES (expr);
297 if (times != 0)
298 sel_print ("times:%d;", times);
301 if (flags & DUMP_EXPR_SPEC_DONE_DS)
303 ds_t spec_done_ds = EXPR_SPEC_DONE_DS (expr);
305 if (spec_done_ds != 0)
306 sel_print ("ds:%d;", spec_done_ds);
309 if (flags & DUMP_EXPR_ORIG_BB)
311 int orig_bb = EXPR_ORIG_BB_INDEX (expr);
313 if (orig_bb != 0)
314 sel_print ("orig_bb:%d;", orig_bb);
317 if (EXPR_TARGET_AVAILABLE (expr) < 1)
318 sel_print ("target:%d;", EXPR_TARGET_AVAILABLE (expr));
319 sel_print ("]");
322 /* Dump expression EXPR with default flags. */
323 void
324 dump_expr (expr_t expr)
326 dump_expr_1 (expr, dump_expr_flags);
329 /* Dump expression EXPR to stderr. */
330 DEBUG_FUNCTION void
331 debug_expr (expr_t expr)
333 switch_dump (stderr);
334 dump_expr_1 (expr, debug_expr_flags);
335 sel_print ("\n");
336 restore_dump ();
339 /* Dump expression REF. */
341 DEBUG_FUNCTION void
342 debug (expr_def &ref)
344 switch_dump (stderr);
345 dump_expr_1 (&ref, 0);
346 sel_print ("\n");
347 restore_dump ();
350 DEBUG_FUNCTION void
351 debug (expr_def *ptr)
353 if (ptr)
354 debug (*ptr);
355 else
356 fprintf (stderr, "<nil>\n");
359 /* Dump expression REF verbosely. */
361 DEBUG_FUNCTION void
362 debug_verbose (expr_def &ref)
364 switch_dump (stderr);
365 dump_expr_1 (&ref, DUMP_EXPR_ALL);
366 sel_print ("\n");
367 restore_dump ();
370 DEBUG_FUNCTION void
371 debug_verbose (expr_def *ptr)
373 if (ptr)
374 debug_verbose (*ptr);
375 else
376 fprintf (stderr, "<nil>\n");
379 /* Dump insn I honoring FLAGS. */
380 void
381 dump_insn_1 (insn_t i, int flags)
383 int all;
385 all = flags & 1;
386 if (all)
387 flags |= DUMP_INSN_ALL;
389 if (!sched_dump_to_dot_p)
390 sel_print ("(");
392 if (flags & DUMP_INSN_EXPR)
394 dump_expr_1 (INSN_EXPR (i), dump_expr_flags | all);
395 sel_print (";");
397 else if (flags & DUMP_INSN_PATTERN)
399 dump_insn_rtx_1 (i, DUMP_INSN_RTX_PATTERN | all);
400 sel_print (";");
402 else if (flags & DUMP_INSN_UID)
403 sel_print ("uid:%d;", INSN_UID (i));
405 if (flags & DUMP_INSN_SEQNO)
406 sel_print ("seqno:%d;", INSN_SEQNO (i));
408 if (flags & DUMP_INSN_SCHED_CYCLE)
410 int cycle = INSN_SCHED_CYCLE (i);
412 if (cycle != 0)
413 sel_print ("cycle:%d;", cycle);
416 if (!sched_dump_to_dot_p)
417 sel_print (")");
420 /* Dump insn I with default flags. */
421 void
422 dump_insn (insn_t i)
424 dump_insn_1 (i, DUMP_INSN_EXPR | DUMP_INSN_SCHED_CYCLE);
427 /* Dump INSN to stderr. */
428 DEBUG_FUNCTION void
429 debug_insn (insn_t insn)
431 switch_dump (stderr);
432 dump_insn_1 (insn, debug_insn_flags);
433 sel_print ("\n");
434 restore_dump ();
437 /* Dumps av_set AV. */
438 void
439 dump_av_set (av_set_t av)
441 av_set_iterator i;
442 expr_t expr;
444 if (!sched_dump_to_dot_p)
445 sel_print ("{");
447 FOR_EACH_EXPR (expr, i, av)
449 dump_expr (expr);
450 if (!sched_dump_to_dot_p)
451 sel_print (" ");
452 else
453 sel_print ("\n");
456 if (!sched_dump_to_dot_p)
457 sel_print ("}");
460 /* Dumps lvset LV. */
461 void
462 dump_lv_set (regset lv)
464 sel_print ("{");
466 /* This code was adapted from cfg.c: dump_regset (). */
467 if (lv == NULL)
468 sel_print ("nil");
469 else
471 unsigned i;
472 reg_set_iterator rsi;
473 int count = 0;
475 EXECUTE_IF_SET_IN_REG_SET (lv, 0, i, rsi)
477 sel_print (" %d", i);
478 if (i < FIRST_PSEUDO_REGISTER)
480 sel_print (" [%s]", reg_names[i]);
481 ++count;
484 ++count;
486 if (sched_dump_to_dot_p && count == 12)
488 count = 0;
489 sel_print ("\n");
494 sel_print ("}\n");
497 /* Dumps a list of instructions pointed to by P. */
498 static void
499 dump_ilist (ilist_t p)
501 while (p)
503 dump_insn (ILIST_INSN (p));
504 p = ILIST_NEXT (p);
508 /* Dumps a list of boundaries pointed to by BNDS. */
509 void
510 dump_blist (blist_t bnds)
512 for (; bnds; bnds = BLIST_NEXT (bnds))
514 bnd_t bnd = BLIST_BND (bnds);
516 sel_print ("[to: %d; ptr: ", INSN_UID (BND_TO (bnd)));
517 dump_ilist (BND_PTR (bnd));
518 sel_print ("] ");
522 /* Dumps a list of fences pointed to by L. */
523 void
524 dump_flist (flist_t l)
526 while (l)
528 dump_insn_1 (FENCE_INSN (FLIST_FENCE (l)), dump_flist_insn_flags);
529 sel_print (" ");
530 l = FLIST_NEXT (l);
534 /* Dumps an insn vector SUCCS. */
535 void
536 dump_insn_vector (rtx_vec_t succs)
538 int i;
539 rtx_insn *succ;
541 FOR_EACH_VEC_ELT (succs, i, succ)
542 if (succ)
543 dump_insn (succ);
544 else
545 sel_print ("NULL ");
548 /* Dumps a hard reg set SET to FILE using PREFIX. */
549 static void
550 print_hard_reg_set (FILE *file, const char *prefix, HARD_REG_SET set)
552 int i;
554 fprintf (file, "%s{ ", prefix);
555 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
557 if (TEST_HARD_REG_BIT (set, i))
558 fprintf (file, "%d ", i);
560 fprintf (file, "}\n");
563 /* Dumps a hard reg set SET using PREFIX. */
564 void
565 dump_hard_reg_set (const char *prefix, HARD_REG_SET set)
567 print_hard_reg_set (sched_dump, prefix, set);
570 /* Pretty print INSN. This is used as a hook. */
571 const char *
572 sel_print_insn (const rtx_insn *insn, int aligned ATTRIBUTE_UNUSED)
574 static char buf[80];
576 /* '+' before insn means it is a new cycle start and it's not been
577 scheduled yet. '>' - has been scheduled. */
578 if (s_i_d.exists () && INSN_LUID (insn) > 0)
579 if (GET_MODE (insn) == TImode)
580 sprintf (buf, "%s %4d",
581 INSN_SCHED_TIMES (insn) > 0 ? "> " : "< ",
582 INSN_UID (insn));
583 else
584 sprintf (buf, "%s %4d",
585 INSN_SCHED_TIMES (insn) > 0 ? "! " : " ",
586 INSN_UID (insn));
587 else
588 if (GET_MODE (insn) == TImode)
589 sprintf (buf, "+ %4d", INSN_UID (insn));
590 else
591 sprintf (buf, " %4d", INSN_UID (insn));
593 return buf;
597 /* Functions for pretty printing of CFG. */
598 /* FIXME: Using pretty-print here could simplify this stuff. */
600 /* Replace all occurencies of STR1 to STR2 in BUF.
601 The BUF must be large enough to hold the result. */
602 static void
603 replace_str_in_buf (char *buf, const char *str1, const char *str2)
605 int buf_len = strlen (buf);
606 int str1_len = strlen (str1);
607 int str2_len = strlen (str2);
608 int diff = str2_len - str1_len;
610 char *p = buf;
613 p = strstr (p, str1);
614 if (p)
616 char *p1 = p + str1_len;
617 /* Copy the rest of buf and '\0'. */
618 int n = buf + buf_len - p1;
619 int i;
621 /* Shift str by DIFF chars. */
622 if (diff > 0)
623 for (i = n; i >= 0; i--)
624 p1[i + diff] = p1[i];
625 else
626 for (i = 0; i <= n; i++)
627 p1[i + diff] = p1[i];
629 /* Copy str2. */
630 for (i = 0; i < str2_len; i++)
631 p[i] = str2[i];
633 p += str2_len;
634 buf_len += diff;
638 while (p);
641 /* Replace characters in BUF that have special meaning in .dot file.
642 Similar to pp_write_text_as_dot_label_to_stream. */
643 static void
644 sel_prepare_string_for_dot_label (char *buf)
646 static char specials_from[7][2] = { "<", ">", "{", "|", "}", "\"",
647 "\n" };
648 static char specials_to[7][3] = { "\\<", "\\>", "\\{", "\\|", "\\}",
649 "\\\"", "\\l" };
650 unsigned i;
652 for (i = 0; i < 7; i++)
653 replace_str_in_buf (buf, specials_from[i], specials_to[i]);
656 /* This function acts like printf but dumps to the sched_dump file. */
657 void
658 sel_print (const char *fmt, ...)
660 va_list ap;
661 va_start (ap, fmt);
662 if (sched_dump_to_dot_p)
664 char *message;
665 if (vasprintf (&message, fmt, ap) >= 0 && message != NULL)
667 message = (char *) xrealloc (message, 2 * strlen (message) + 1);
668 sel_prepare_string_for_dot_label (message);
669 fprintf (sched_dump, "%s", message);
670 free (message);
673 else
674 vfprintf (sched_dump, fmt, ap);
675 va_end (ap);
678 /* Dump INSN with FLAGS. */
679 static void
680 sel_dump_cfg_insn (insn_t insn, int flags)
682 int insn_flags = DUMP_INSN_UID | DUMP_INSN_PATTERN;
684 if (sched_luids.exists () && INSN_LUID (insn) > 0)
686 if (flags & SEL_DUMP_CFG_INSN_SEQNO)
687 insn_flags |= DUMP_INSN_SEQNO | DUMP_INSN_SCHED_CYCLE | DUMP_INSN_EXPR;
690 dump_insn_1 (insn, insn_flags);
693 /* Dump E to the dot file F. */
694 static void
695 sel_dump_cfg_edge (FILE *f, edge e)
697 int w;
698 const char *color;
700 if (e->flags & EDGE_FALLTHRU)
702 w = 10;
703 color = ", color = red";
705 else if (e->src->next_bb == e->dest)
707 w = 3;
708 color = ", color = blue";
710 else
712 w = 1;
713 color = "";
716 fprintf (f, "\tbb%d -> bb%d [weight = %d%s];\n",
717 e->src->index, e->dest->index, w, color);
721 /* Return true if BB has a predesessor from current region.
722 TODO: Either make this function to trace back through empty block
723 or just remove those empty blocks. */
724 static bool
725 has_preds_in_current_region_p (basic_block bb)
727 edge e;
728 edge_iterator ei;
730 gcc_assert (!in_current_region_p (bb));
732 FOR_EACH_EDGE (e, ei, bb->preds)
733 if (in_current_region_p (e->src))
734 return true;
736 return false;
739 /* Dump a cfg region to the dot file F honoring FLAGS. */
740 static void
741 sel_dump_cfg_2 (FILE *f, int flags)
743 basic_block bb;
745 sched_dump_to_dot_p = true;
746 switch_dump (f);
748 fprintf (f, "digraph G {\n"
749 "\tratio = 2.25;\n"
750 "\tnode [shape = record, fontsize = 9];\n");
752 if (flags & SEL_DUMP_CFG_FUNCTION_NAME)
753 fprintf (f, "function [label = \"%s\"];\n", current_function_name ());
755 FOR_EACH_BB_FN (bb, cfun)
757 insn_t insn = BB_HEAD (bb);
758 insn_t next_tail = NEXT_INSN (BB_END (bb));
759 edge e;
760 edge_iterator ei;
761 bool in_region_p = ((flags & SEL_DUMP_CFG_CURRENT_REGION)
762 && in_current_region_p (bb));
763 bool full_p = (!(flags & SEL_DUMP_CFG_CURRENT_REGION)
764 || in_region_p);
765 bool some_p = full_p || has_preds_in_current_region_p (bb);
766 const char *color;
767 const char *style;
769 if (!some_p)
770 continue;
772 if ((flags & SEL_DUMP_CFG_CURRENT_REGION)
773 && in_current_region_p (bb)
774 && BLOCK_TO_BB (bb->index) == 0)
775 color = "color = green, ";
776 else
777 color = "";
779 if ((flags & SEL_DUMP_CFG_FENCES)
780 && in_region_p)
782 style = "";
784 if (!sel_bb_empty_p (bb))
786 bool first_p = true;
787 insn_t tail = BB_END (bb);
788 insn_t cur_insn;
790 cur_insn = bb_note (bb);
794 fence_t fence;
796 cur_insn = NEXT_INSN (cur_insn);
797 fence = flist_lookup (fences, cur_insn);
799 if (fence != NULL)
801 if (!FENCE_SCHEDULED_P (fence))
803 if (first_p)
804 color = "color = red, ";
805 else
806 color = "color = yellow, ";
808 else
809 color = "color = blue, ";
812 first_p = false;
814 while (cur_insn != tail);
817 else if (!full_p)
818 style = "style = dashed, ";
819 else
820 style = "";
822 fprintf (f, "\tbb%d [%s%slabel = \"{Basic block %d", bb->index,
823 style, color, bb->index);
825 if ((flags & SEL_DUMP_CFG_BB_LOOP)
826 && bb->loop_father != NULL)
827 fprintf (f, ", loop %d", bb->loop_father->num);
829 if (full_p
830 && (flags & SEL_DUMP_CFG_BB_NOTES_LIST))
832 insn_t notes = BB_NOTE_LIST (bb);
834 if (notes != NULL_RTX)
836 fprintf (f, "|");
838 /* For simplicity, we dump notes from note_list in reversed order
839 to that what they will appear in the code. */
840 while (notes != NULL_RTX)
842 sel_dump_cfg_insn (notes, flags);
843 fprintf (f, "\\l");
845 notes = PREV_INSN (notes);
850 if (full_p
851 && (flags & SEL_DUMP_CFG_AV_SET)
852 && in_current_region_p (bb)
853 && !sel_bb_empty_p (bb))
855 fprintf (f, "|");
857 if (BB_AV_SET_VALID_P (bb))
858 dump_av_set (BB_AV_SET (bb));
859 else if (BB_AV_LEVEL (bb) == -1)
860 fprintf (f, "AV_SET needs update");
863 if ((flags & SEL_DUMP_CFG_LV_SET)
864 && !sel_bb_empty_p (bb))
866 fprintf (f, "|");
868 if (BB_LV_SET_VALID_P (bb))
869 dump_lv_set (BB_LV_SET (bb));
870 else
871 fprintf (f, "LV_SET needs update");
874 if (full_p
875 && (flags & SEL_DUMP_CFG_BB_INSNS))
877 fprintf (f, "|");
878 while (insn != next_tail)
880 sel_dump_cfg_insn (insn, flags);
881 fprintf (f, "\\l");
883 insn = NEXT_INSN (insn);
887 fprintf (f, "}\"];\n");
889 FOR_EACH_EDGE (e, ei, bb->succs)
890 if (full_p || in_current_region_p (e->dest))
891 sel_dump_cfg_edge (f, e);
894 fprintf (f, "}");
896 restore_dump ();
897 sched_dump_to_dot_p = false;
900 /* Dump a cfg region to the file specified by TAG honoring flags.
901 The file is created by the function. */
902 static void
903 sel_dump_cfg_1 (const char *tag, int flags)
905 char *buf;
906 int i;
907 FILE *f;
909 ++sel_dump_cfg_fileno;
911 if (!sel_dump_cfg_p)
912 return;
914 i = 1 + snprintf (NULL, 0, "%s/%s%05d-%s.dot", sel_debug_cfg_root,
915 sel_debug_cfg_root_postfix, sel_dump_cfg_fileno, tag);
916 buf = XNEWVEC (char, i);
917 snprintf (buf, i, "%s/%s%05d-%s.dot", sel_debug_cfg_root,
918 sel_debug_cfg_root_postfix, sel_dump_cfg_fileno, tag);
920 f = fopen (buf, "w");
922 if (f == NULL)
923 fprintf (stderr, "Can't create file: %s.\n", buf);
924 else
926 sel_dump_cfg_2 (f, flags);
928 fclose (f);
931 free (buf);
934 /* Setup cfg dumping flags. Used for debugging. */
935 void
936 setup_dump_cfg_params (void)
938 sel_dump_cfg_flags = SEL_DUMP_CFG_FLAGS;
939 sel_dump_cfg_p = 0;
940 sel_debug_cfg_root_postfix = sel_debug_cfg_root_postfix_default;
943 /* Debug a cfg region with FLAGS. */
944 void
945 sel_debug_cfg_1 (int flags)
947 bool t1 = sel_dump_cfg_p;
948 int t2 = sel_dump_cfg_fileno;
950 sel_dump_cfg_p = true;
951 sel_dump_cfg_fileno = ++sel_debug_cfg_fileno;
953 sel_dump_cfg_1 ("sel-debug-cfg", flags);
955 sel_dump_cfg_fileno = t2;
956 sel_dump_cfg_p = t1;
959 /* Dumps av_set AV to stderr. */
960 DEBUG_FUNCTION void
961 debug_av_set (av_set_t av)
963 switch_dump (stderr);
964 dump_av_set (av);
965 sel_print ("\n");
966 restore_dump ();
969 /* Dump LV to stderr. */
970 DEBUG_FUNCTION void
971 debug_lv_set (regset lv)
973 switch_dump (stderr);
974 dump_lv_set (lv);
975 sel_print ("\n");
976 restore_dump ();
979 /* Dump an instruction list P to stderr. */
980 DEBUG_FUNCTION void
981 debug_ilist (ilist_t p)
983 switch_dump (stderr);
984 dump_ilist (p);
985 sel_print ("\n");
986 restore_dump ();
989 /* Dump a boundary list BNDS to stderr. */
990 DEBUG_FUNCTION void
991 debug_blist (blist_t bnds)
993 switch_dump (stderr);
994 dump_blist (bnds);
995 sel_print ("\n");
996 restore_dump ();
999 /* Dump a rtx vector REF. */
1000 DEBUG_FUNCTION void
1001 debug (vec<rtx_insn *> &ref)
1003 switch_dump (stderr);
1004 dump_insn_vector (ref);
1005 sel_print ("\n");
1006 restore_dump ();
1009 DEBUG_FUNCTION void
1010 debug (vec<rtx_insn *> *ptr)
1012 if (ptr)
1013 debug (*ptr);
1014 else
1015 fprintf (stderr, "<nil>\n");
1018 /* Dump an insn vector SUCCS. */
1019 DEBUG_FUNCTION void
1020 debug_insn_vector (rtx_vec_t succs)
1022 switch_dump (stderr);
1023 dump_insn_vector (succs);
1024 sel_print ("\n");
1025 restore_dump ();
1028 /* Dump a hard reg set SET to stderr. */
1029 DEBUG_FUNCTION void
1030 debug_hard_reg_set (HARD_REG_SET set)
1032 switch_dump (stderr);
1033 dump_hard_reg_set ("", set);
1034 sel_print ("\n");
1035 restore_dump ();
1038 /* Debug a cfg region with default flags. */
1039 void
1040 sel_debug_cfg (void)
1042 sel_debug_cfg_1 (sel_debug_cfg_flags);
1045 /* Print a current cselib value for X's address to stderr. */
1046 DEBUG_FUNCTION rtx
1047 debug_mem_addr_value (rtx x)
1049 rtx t, addr;
1050 machine_mode address_mode;
1052 gcc_assert (MEM_P (x));
1053 address_mode = get_address_mode (x);
1055 t = shallow_copy_rtx (x);
1056 if (cselib_lookup (XEXP (t, 0), address_mode, 0, GET_MODE (t)))
1057 XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0), GET_MODE (t));
1059 t = canon_rtx (t);
1060 addr = get_addr (XEXP (t, 0));
1061 debug_rtx (t);
1062 debug_rtx (addr);
1063 return t;
1065 #endif