PR target/65871
[official-gcc.git] / gcc / sel-sched-dump.c
blob6f174a5f8508ae988765d3155c7515a463f3d9ee
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 "tm.h"
24 #include "diagnostic-core.h"
25 #include "rtl.h"
26 #include "tm_p.h"
27 #include "hard-reg-set.h"
28 #include "regs.h"
29 #include "hashtab.h"
30 #include "hash-set.h"
31 #include "vec.h"
32 #include "machmode.h"
33 #include "input.h"
34 #include "function.h"
35 #include "predict.h"
36 #include "dominance.h"
37 #include "cfg.h"
38 #include "basic-block.h"
39 #include "flags.h"
40 #include "insn-config.h"
41 #include "insn-attr.h"
42 #include "params.h"
43 #include "cselib.h"
44 #include "target.h"
46 #ifdef INSN_SCHEDULING
47 #include "sel-sched-ir.h"
48 #include "sel-sched-dump.h"
51 /* These variables control high-level pretty printing. */
52 static int sel_dump_cfg_flags = SEL_DUMP_CFG_FLAGS;
53 static int sel_debug_cfg_flags = SEL_DUMP_CFG_FLAGS;
55 /* True when a cfg should be dumped. */
56 static bool sel_dump_cfg_p;
58 /* Variables that are used to build the cfg dump file name. */
59 static const char * const sel_debug_cfg_root = "./";
60 static const char * const sel_debug_cfg_root_postfix_default = "";
61 static const char *sel_debug_cfg_root_postfix = "";
62 static int sel_dump_cfg_fileno = -1;
63 static int sel_debug_cfg_fileno = -1;
65 /* When this flag is on, we are dumping to the .dot file.
66 When it is off, we are dumping to log.
67 This is useful to differentiate formatting between log and .dot
68 files. */
69 bool sched_dump_to_dot_p = false;
71 /* Controls how insns from a fence list should be dumped. */
72 static int dump_flist_insn_flags = (DUMP_INSN_UID | DUMP_INSN_BBN
73 | DUMP_INSN_SEQNO);
76 /* The variable used to hold the value of sched_dump when temporarily
77 switching dump output to the other source, e.g. the .dot file. */
78 static FILE *saved_sched_dump = NULL;
80 /* Switch sched_dump to TO. It must not be called twice. */
81 static void
82 switch_dump (FILE *to)
84 gcc_assert (saved_sched_dump == NULL);
86 saved_sched_dump = sched_dump;
87 sched_dump = to;
90 /* Restore previously switched dump. */
91 static void
92 restore_dump (void)
94 sched_dump = saved_sched_dump;
95 saved_sched_dump = NULL;
99 /* Functions for dumping instructions, av sets, and exprs. */
101 /* Default flags for dumping insns. */
102 static int dump_insn_rtx_flags = DUMP_INSN_RTX_UID | DUMP_INSN_RTX_PATTERN;
104 /* Default flags for dumping vinsns. */
105 static int dump_vinsn_flags = (DUMP_VINSN_INSN_RTX | DUMP_VINSN_TYPE
106 | DUMP_VINSN_COUNT);
108 /* Default flags for dumping expressions. */
109 static int dump_expr_flags = DUMP_EXPR_ALL;
111 /* Default flags for dumping insns when debugging. */
112 static int debug_insn_rtx_flags = DUMP_INSN_RTX_ALL;
114 /* Default flags for dumping vinsns when debugging. */
115 static int debug_vinsn_flags = DUMP_VINSN_ALL;
117 /* Default flags for dumping expressions when debugging. */
118 static int debug_expr_flags = DUMP_EXPR_ALL;
120 /* Controls how an insn from stream should be dumped when debugging. */
121 static int debug_insn_flags = DUMP_INSN_ALL;
123 /* Print an rtx X. */
124 void
125 sel_print_rtl (rtx x)
127 print_rtl_single (sched_dump, x);
130 /* Dump insn INSN honoring FLAGS. */
131 void
132 dump_insn_rtx_1 (rtx insn, int flags)
134 int all;
136 /* flags == -1 also means dumping all. */
137 all = (flags & 1);;
138 if (all)
139 flags |= DUMP_INSN_RTX_ALL;
141 sel_print ("(");
143 if (flags & DUMP_INSN_RTX_UID)
144 sel_print ("%d;", INSN_UID (insn));
146 if (flags & DUMP_INSN_RTX_PATTERN)
147 sel_print ("%s;", str_pattern_slim (PATTERN (insn)));
149 if (flags & DUMP_INSN_RTX_BBN)
151 basic_block bb = BLOCK_FOR_INSN (insn);
153 sel_print ("bb:%d;", bb != NULL ? bb->index : -1);
156 sel_print (")");
160 /* Dump INSN with default flags. */
161 void
162 dump_insn_rtx (rtx insn)
164 dump_insn_rtx_1 (insn, dump_insn_rtx_flags);
168 /* Dump INSN to stderr. */
169 DEBUG_FUNCTION void
170 debug_insn_rtx (rtx insn)
172 switch_dump (stderr);
173 dump_insn_rtx_1 (insn, debug_insn_rtx_flags);
174 sel_print ("\n");
175 restore_dump ();
178 /* Dump vinsn VI honoring flags. */
179 void
180 dump_vinsn_1 (vinsn_t vi, int flags)
182 int all;
184 /* flags == -1 also means dumping all. */
185 all = flags & 1;
186 if (all)
187 flags |= DUMP_VINSN_ALL;
189 sel_print ("(");
191 if (flags & DUMP_VINSN_INSN_RTX)
192 dump_insn_rtx_1 (VINSN_INSN_RTX (vi), dump_insn_rtx_flags | all);
194 if (flags & DUMP_VINSN_TYPE)
195 sel_print ("type:%s;", GET_RTX_NAME (VINSN_TYPE (vi)));
197 if (flags & DUMP_VINSN_COUNT)
198 sel_print ("count:%d;", VINSN_COUNT (vi));
200 if (flags & DUMP_VINSN_COST)
202 int cost = vi->cost;
204 if (cost != -1)
205 sel_print ("cost:%d;", cost);
208 sel_print (")");
211 /* Dump vinsn VI with default flags. */
212 void
213 dump_vinsn (vinsn_t vi)
215 dump_vinsn_1 (vi, dump_vinsn_flags);
218 DEBUG_FUNCTION void
219 debug (vinsn_def &ref)
221 switch_dump (stderr);
222 dump_vinsn_1 (&ref, dump_vinsn_flags);
223 sel_print ("\n");
224 restore_dump ();
227 DEBUG_FUNCTION void
228 debug (vinsn_def *ptr)
230 if (ptr)
231 debug (*ptr);
232 else
233 fprintf (stderr, "<nil>\n");
236 DEBUG_FUNCTION void
237 debug_verbose (vinsn_def &ref)
239 switch_dump (stderr);
240 dump_vinsn_1 (&ref, debug_vinsn_flags);
241 sel_print ("\n");
242 restore_dump ();
245 DEBUG_FUNCTION void
246 debug_verbose (vinsn_def *ptr)
248 if (ptr)
249 debug (*ptr);
250 else
251 fprintf (stderr, "<nil>\n");
254 /* Dump vinsn VI to stderr. */
255 DEBUG_FUNCTION void
256 debug_vinsn (vinsn_t vi)
258 switch_dump (stderr);
259 dump_vinsn_1 (vi, debug_vinsn_flags);
260 sel_print ("\n");
261 restore_dump ();
264 /* Dump EXPR honoring flags. */
265 void
266 dump_expr_1 (expr_t expr, int flags)
268 int all;
270 /* flags == -1 also means dumping all. */
271 all = flags & 1;
272 if (all)
273 flags |= DUMP_EXPR_ALL;
275 sel_print ("[");
277 if (flags & DUMP_EXPR_VINSN)
278 dump_vinsn_1 (EXPR_VINSN (expr), dump_vinsn_flags | all);
280 if (flags & DUMP_EXPR_SPEC)
282 int spec = EXPR_SPEC (expr);
284 if (spec != 0)
285 sel_print ("spec:%d;", spec);
288 if (flags & DUMP_EXPR_USEFULNESS)
290 int use = EXPR_USEFULNESS (expr);
292 if (use != REG_BR_PROB_BASE)
293 sel_print ("use:%d;", use);
296 if (flags & DUMP_EXPR_PRIORITY)
297 sel_print ("prio:%d;", EXPR_PRIORITY (expr));
299 if (flags & DUMP_EXPR_SCHED_TIMES)
301 int times = EXPR_SCHED_TIMES (expr);
303 if (times != 0)
304 sel_print ("times:%d;", times);
307 if (flags & DUMP_EXPR_SPEC_DONE_DS)
309 ds_t spec_done_ds = EXPR_SPEC_DONE_DS (expr);
311 if (spec_done_ds != 0)
312 sel_print ("ds:%d;", spec_done_ds);
315 if (flags & DUMP_EXPR_ORIG_BB)
317 int orig_bb = EXPR_ORIG_BB_INDEX (expr);
319 if (orig_bb != 0)
320 sel_print ("orig_bb:%d;", orig_bb);
323 if (EXPR_TARGET_AVAILABLE (expr) < 1)
324 sel_print ("target:%d;", EXPR_TARGET_AVAILABLE (expr));
325 sel_print ("]");
328 /* Dump expression EXPR with default flags. */
329 void
330 dump_expr (expr_t expr)
332 dump_expr_1 (expr, dump_expr_flags);
335 /* Dump expression EXPR to stderr. */
336 DEBUG_FUNCTION void
337 debug_expr (expr_t expr)
339 switch_dump (stderr);
340 dump_expr_1 (expr, debug_expr_flags);
341 sel_print ("\n");
342 restore_dump ();
345 /* Dump expression REF. */
347 DEBUG_FUNCTION void
348 debug (expr_def &ref)
350 switch_dump (stderr);
351 dump_expr_1 (&ref, 0);
352 sel_print ("\n");
353 restore_dump ();
356 DEBUG_FUNCTION void
357 debug (expr_def *ptr)
359 if (ptr)
360 debug (*ptr);
361 else
362 fprintf (stderr, "<nil>\n");
365 /* Dump expression REF verbosely. */
367 DEBUG_FUNCTION void
368 debug_verbose (expr_def &ref)
370 switch_dump (stderr);
371 dump_expr_1 (&ref, DUMP_EXPR_ALL);
372 sel_print ("\n");
373 restore_dump ();
376 DEBUG_FUNCTION void
377 debug_verbose (expr_def *ptr)
379 if (ptr)
380 debug_verbose (*ptr);
381 else
382 fprintf (stderr, "<nil>\n");
385 /* Dump insn I honoring FLAGS. */
386 void
387 dump_insn_1 (insn_t i, int flags)
389 int all;
391 all = flags & 1;
392 if (all)
393 flags |= DUMP_INSN_ALL;
395 if (!sched_dump_to_dot_p)
396 sel_print ("(");
398 if (flags & DUMP_INSN_EXPR)
400 dump_expr_1 (INSN_EXPR (i), dump_expr_flags | all);
401 sel_print (";");
403 else if (flags & DUMP_INSN_PATTERN)
405 dump_insn_rtx_1 (i, DUMP_INSN_RTX_PATTERN | all);
406 sel_print (";");
408 else if (flags & DUMP_INSN_UID)
409 sel_print ("uid:%d;", INSN_UID (i));
411 if (flags & DUMP_INSN_SEQNO)
412 sel_print ("seqno:%d;", INSN_SEQNO (i));
414 if (flags & DUMP_INSN_SCHED_CYCLE)
416 int cycle = INSN_SCHED_CYCLE (i);
418 if (cycle != 0)
419 sel_print ("cycle:%d;", cycle);
422 if (!sched_dump_to_dot_p)
423 sel_print (")");
426 /* Dump insn I with default flags. */
427 void
428 dump_insn (insn_t i)
430 dump_insn_1 (i, DUMP_INSN_EXPR | DUMP_INSN_SCHED_CYCLE);
433 /* Dump INSN to stderr. */
434 DEBUG_FUNCTION void
435 debug_insn (insn_t insn)
437 switch_dump (stderr);
438 dump_insn_1 (insn, debug_insn_flags);
439 sel_print ("\n");
440 restore_dump ();
443 /* Dumps av_set AV. */
444 void
445 dump_av_set (av_set_t av)
447 av_set_iterator i;
448 expr_t expr;
450 if (!sched_dump_to_dot_p)
451 sel_print ("{");
453 FOR_EACH_EXPR (expr, i, av)
455 dump_expr (expr);
456 if (!sched_dump_to_dot_p)
457 sel_print (" ");
458 else
459 sel_print ("\n");
462 if (!sched_dump_to_dot_p)
463 sel_print ("}");
466 /* Dumps lvset LV. */
467 void
468 dump_lv_set (regset lv)
470 sel_print ("{");
472 /* This code was adapted from cfg.c: dump_regset (). */
473 if (lv == NULL)
474 sel_print ("nil");
475 else
477 unsigned i;
478 reg_set_iterator rsi;
479 int count = 0;
481 EXECUTE_IF_SET_IN_REG_SET (lv, 0, i, rsi)
483 sel_print (" %d", i);
484 if (i < FIRST_PSEUDO_REGISTER)
486 sel_print (" [%s]", reg_names[i]);
487 ++count;
490 ++count;
492 if (sched_dump_to_dot_p && count == 12)
494 count = 0;
495 sel_print ("\n");
500 sel_print ("}\n");
503 /* Dumps a list of instructions pointed to by P. */
504 static void
505 dump_ilist (ilist_t p)
507 while (p)
509 dump_insn (ILIST_INSN (p));
510 p = ILIST_NEXT (p);
514 /* Dumps a list of boundaries pointed to by BNDS. */
515 void
516 dump_blist (blist_t bnds)
518 for (; bnds; bnds = BLIST_NEXT (bnds))
520 bnd_t bnd = BLIST_BND (bnds);
522 sel_print ("[to: %d; ptr: ", INSN_UID (BND_TO (bnd)));
523 dump_ilist (BND_PTR (bnd));
524 sel_print ("] ");
528 /* Dumps a list of fences pointed to by L. */
529 void
530 dump_flist (flist_t l)
532 while (l)
534 dump_insn_1 (FENCE_INSN (FLIST_FENCE (l)), dump_flist_insn_flags);
535 sel_print (" ");
536 l = FLIST_NEXT (l);
540 /* Dumps an insn vector SUCCS. */
541 void
542 dump_insn_vector (rtx_vec_t succs)
544 int i;
545 rtx_insn *succ;
547 FOR_EACH_VEC_ELT (succs, i, succ)
548 if (succ)
549 dump_insn (succ);
550 else
551 sel_print ("NULL ");
554 /* Dumps a hard reg set SET to FILE using PREFIX. */
555 static void
556 print_hard_reg_set (FILE *file, const char *prefix, HARD_REG_SET set)
558 int i;
560 fprintf (file, "%s{ ", prefix);
561 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
563 if (TEST_HARD_REG_BIT (set, i))
564 fprintf (file, "%d ", i);
566 fprintf (file, "}\n");
569 /* Dumps a hard reg set SET using PREFIX. */
570 void
571 dump_hard_reg_set (const char *prefix, HARD_REG_SET set)
573 print_hard_reg_set (sched_dump, prefix, set);
576 /* Pretty print INSN. This is used as a hook. */
577 const char *
578 sel_print_insn (const rtx_insn *insn, int aligned ATTRIBUTE_UNUSED)
580 static char buf[80];
582 /* '+' before insn means it is a new cycle start and it's not been
583 scheduled yet. '>' - has been scheduled. */
584 if (s_i_d.exists () && INSN_LUID (insn) > 0)
585 if (GET_MODE (insn) == TImode)
586 sprintf (buf, "%s %4d",
587 INSN_SCHED_TIMES (insn) > 0 ? "> " : "< ",
588 INSN_UID (insn));
589 else
590 sprintf (buf, "%s %4d",
591 INSN_SCHED_TIMES (insn) > 0 ? "! " : " ",
592 INSN_UID (insn));
593 else
594 if (GET_MODE (insn) == TImode)
595 sprintf (buf, "+ %4d", INSN_UID (insn));
596 else
597 sprintf (buf, " %4d", INSN_UID (insn));
599 return buf;
603 /* Functions for pretty printing of CFG. */
604 /* FIXME: Using pretty-print here could simplify this stuff. */
606 /* Replace all occurencies of STR1 to STR2 in BUF.
607 The BUF must be large enough to hold the result. */
608 static void
609 replace_str_in_buf (char *buf, const char *str1, const char *str2)
611 int buf_len = strlen (buf);
612 int str1_len = strlen (str1);
613 int str2_len = strlen (str2);
614 int diff = str2_len - str1_len;
616 char *p = buf;
619 p = strstr (p, str1);
620 if (p)
622 char *p1 = p + str1_len;
623 /* Copy the rest of buf and '\0'. */
624 int n = buf + buf_len - p1;
625 int i;
627 /* Shift str by DIFF chars. */
628 if (diff > 0)
629 for (i = n; i >= 0; i--)
630 p1[i + diff] = p1[i];
631 else
632 for (i = 0; i <= n; i++)
633 p1[i + diff] = p1[i];
635 /* Copy str2. */
636 for (i = 0; i < str2_len; i++)
637 p[i] = str2[i];
639 p += str2_len;
640 buf_len += diff;
644 while (p);
647 /* Replace characters in BUF that have special meaning in .dot file.
648 Similar to pp_write_text_as_dot_label_to_stream. */
649 static void
650 sel_prepare_string_for_dot_label (char *buf)
652 static char specials_from[7][2] = { "<", ">", "{", "|", "}", "\"",
653 "\n" };
654 static char specials_to[7][3] = { "\\<", "\\>", "\\{", "\\|", "\\}",
655 "\\\"", "\\l" };
656 unsigned i;
658 for (i = 0; i < 7; i++)
659 replace_str_in_buf (buf, specials_from[i], specials_to[i]);
662 /* This function acts like printf but dumps to the sched_dump file. */
663 void
664 sel_print (const char *fmt, ...)
666 va_list ap;
667 va_start (ap, fmt);
668 if (sched_dump_to_dot_p)
670 char *message;
671 if (vasprintf (&message, fmt, ap) >= 0 && message != NULL)
673 message = (char *) xrealloc (message, 2 * strlen (message) + 1);
674 sel_prepare_string_for_dot_label (message);
675 fprintf (sched_dump, "%s", message);
676 free (message);
679 else
680 vfprintf (sched_dump, fmt, ap);
681 va_end (ap);
684 /* Dump INSN with FLAGS. */
685 static void
686 sel_dump_cfg_insn (insn_t insn, int flags)
688 int insn_flags = DUMP_INSN_UID | DUMP_INSN_PATTERN;
690 if (sched_luids.exists () && INSN_LUID (insn) > 0)
692 if (flags & SEL_DUMP_CFG_INSN_SEQNO)
693 insn_flags |= DUMP_INSN_SEQNO | DUMP_INSN_SCHED_CYCLE | DUMP_INSN_EXPR;
696 dump_insn_1 (insn, insn_flags);
699 /* Dump E to the dot file F. */
700 static void
701 sel_dump_cfg_edge (FILE *f, edge e)
703 int w;
704 const char *color;
706 if (e->flags & EDGE_FALLTHRU)
708 w = 10;
709 color = ", color = red";
711 else if (e->src->next_bb == e->dest)
713 w = 3;
714 color = ", color = blue";
716 else
718 w = 1;
719 color = "";
722 fprintf (f, "\tbb%d -> bb%d [weight = %d%s];\n",
723 e->src->index, e->dest->index, w, color);
727 /* Return true if BB has a predesessor from current region.
728 TODO: Either make this function to trace back through empty block
729 or just remove those empty blocks. */
730 static bool
731 has_preds_in_current_region_p (basic_block bb)
733 edge e;
734 edge_iterator ei;
736 gcc_assert (!in_current_region_p (bb));
738 FOR_EACH_EDGE (e, ei, bb->preds)
739 if (in_current_region_p (e->src))
740 return true;
742 return false;
745 /* Dump a cfg region to the dot file F honoring FLAGS. */
746 static void
747 sel_dump_cfg_2 (FILE *f, int flags)
749 basic_block bb;
751 sched_dump_to_dot_p = true;
752 switch_dump (f);
754 fprintf (f, "digraph G {\n"
755 "\tratio = 2.25;\n"
756 "\tnode [shape = record, fontsize = 9];\n");
758 if (flags & SEL_DUMP_CFG_FUNCTION_NAME)
759 fprintf (f, "function [label = \"%s\"];\n", current_function_name ());
761 FOR_EACH_BB_FN (bb, cfun)
763 insn_t insn = BB_HEAD (bb);
764 insn_t next_tail = NEXT_INSN (BB_END (bb));
765 edge e;
766 edge_iterator ei;
767 bool in_region_p = ((flags & SEL_DUMP_CFG_CURRENT_REGION)
768 && in_current_region_p (bb));
769 bool full_p = (!(flags & SEL_DUMP_CFG_CURRENT_REGION)
770 || in_region_p);
771 bool some_p = full_p || has_preds_in_current_region_p (bb);
772 const char *color;
773 const char *style;
775 if (!some_p)
776 continue;
778 if ((flags & SEL_DUMP_CFG_CURRENT_REGION)
779 && in_current_region_p (bb)
780 && BLOCK_TO_BB (bb->index) == 0)
781 color = "color = green, ";
782 else
783 color = "";
785 if ((flags & SEL_DUMP_CFG_FENCES)
786 && in_region_p)
788 style = "";
790 if (!sel_bb_empty_p (bb))
792 bool first_p = true;
793 insn_t tail = BB_END (bb);
794 insn_t cur_insn;
796 cur_insn = bb_note (bb);
800 fence_t fence;
802 cur_insn = NEXT_INSN (cur_insn);
803 fence = flist_lookup (fences, cur_insn);
805 if (fence != NULL)
807 if (!FENCE_SCHEDULED_P (fence))
809 if (first_p)
810 color = "color = red, ";
811 else
812 color = "color = yellow, ";
814 else
815 color = "color = blue, ";
818 first_p = false;
820 while (cur_insn != tail);
823 else if (!full_p)
824 style = "style = dashed, ";
825 else
826 style = "";
828 fprintf (f, "\tbb%d [%s%slabel = \"{Basic block %d", bb->index,
829 style, color, bb->index);
831 if ((flags & SEL_DUMP_CFG_BB_LOOP)
832 && bb->loop_father != NULL)
833 fprintf (f, ", loop %d", bb->loop_father->num);
835 if (full_p
836 && (flags & SEL_DUMP_CFG_BB_NOTES_LIST))
838 insn_t notes = BB_NOTE_LIST (bb);
840 if (notes != NULL_RTX)
842 fprintf (f, "|");
844 /* For simplicity, we dump notes from note_list in reversed order
845 to that what they will appear in the code. */
846 while (notes != NULL_RTX)
848 sel_dump_cfg_insn (notes, flags);
849 fprintf (f, "\\l");
851 notes = PREV_INSN (notes);
856 if (full_p
857 && (flags & SEL_DUMP_CFG_AV_SET)
858 && in_current_region_p (bb)
859 && !sel_bb_empty_p (bb))
861 fprintf (f, "|");
863 if (BB_AV_SET_VALID_P (bb))
864 dump_av_set (BB_AV_SET (bb));
865 else if (BB_AV_LEVEL (bb) == -1)
866 fprintf (f, "AV_SET needs update");
869 if ((flags & SEL_DUMP_CFG_LV_SET)
870 && !sel_bb_empty_p (bb))
872 fprintf (f, "|");
874 if (BB_LV_SET_VALID_P (bb))
875 dump_lv_set (BB_LV_SET (bb));
876 else
877 fprintf (f, "LV_SET needs update");
880 if (full_p
881 && (flags & SEL_DUMP_CFG_BB_INSNS))
883 fprintf (f, "|");
884 while (insn != next_tail)
886 sel_dump_cfg_insn (insn, flags);
887 fprintf (f, "\\l");
889 insn = NEXT_INSN (insn);
893 fprintf (f, "}\"];\n");
895 FOR_EACH_EDGE (e, ei, bb->succs)
896 if (full_p || in_current_region_p (e->dest))
897 sel_dump_cfg_edge (f, e);
900 fprintf (f, "}");
902 restore_dump ();
903 sched_dump_to_dot_p = false;
906 /* Dump a cfg region to the file specified by TAG honoring flags.
907 The file is created by the function. */
908 static void
909 sel_dump_cfg_1 (const char *tag, int flags)
911 char *buf;
912 int i;
913 FILE *f;
915 ++sel_dump_cfg_fileno;
917 if (!sel_dump_cfg_p)
918 return;
920 i = 1 + snprintf (NULL, 0, "%s/%s%05d-%s.dot", sel_debug_cfg_root,
921 sel_debug_cfg_root_postfix, sel_dump_cfg_fileno, tag);
922 buf = XNEWVEC (char, i);
923 snprintf (buf, i, "%s/%s%05d-%s.dot", sel_debug_cfg_root,
924 sel_debug_cfg_root_postfix, sel_dump_cfg_fileno, tag);
926 f = fopen (buf, "w");
928 if (f == NULL)
929 fprintf (stderr, "Can't create file: %s.\n", buf);
930 else
932 sel_dump_cfg_2 (f, flags);
934 fclose (f);
937 free (buf);
940 /* Setup cfg dumping flags. Used for debugging. */
941 void
942 setup_dump_cfg_params (void)
944 sel_dump_cfg_flags = SEL_DUMP_CFG_FLAGS;
945 sel_dump_cfg_p = 0;
946 sel_debug_cfg_root_postfix = sel_debug_cfg_root_postfix_default;
949 /* Debug a cfg region with FLAGS. */
950 void
951 sel_debug_cfg_1 (int flags)
953 bool t1 = sel_dump_cfg_p;
954 int t2 = sel_dump_cfg_fileno;
956 sel_dump_cfg_p = true;
957 sel_dump_cfg_fileno = ++sel_debug_cfg_fileno;
959 sel_dump_cfg_1 ("sel-debug-cfg", flags);
961 sel_dump_cfg_fileno = t2;
962 sel_dump_cfg_p = t1;
965 /* Dumps av_set AV to stderr. */
966 DEBUG_FUNCTION void
967 debug_av_set (av_set_t av)
969 switch_dump (stderr);
970 dump_av_set (av);
971 sel_print ("\n");
972 restore_dump ();
975 /* Dump LV to stderr. */
976 DEBUG_FUNCTION void
977 debug_lv_set (regset lv)
979 switch_dump (stderr);
980 dump_lv_set (lv);
981 sel_print ("\n");
982 restore_dump ();
985 /* Dump an instruction list P to stderr. */
986 DEBUG_FUNCTION void
987 debug_ilist (ilist_t p)
989 switch_dump (stderr);
990 dump_ilist (p);
991 sel_print ("\n");
992 restore_dump ();
995 /* Dump a boundary list BNDS to stderr. */
996 DEBUG_FUNCTION void
997 debug_blist (blist_t bnds)
999 switch_dump (stderr);
1000 dump_blist (bnds);
1001 sel_print ("\n");
1002 restore_dump ();
1005 /* Dump a rtx vector REF. */
1006 DEBUG_FUNCTION void
1007 debug (vec<rtx_insn *> &ref)
1009 switch_dump (stderr);
1010 dump_insn_vector (ref);
1011 sel_print ("\n");
1012 restore_dump ();
1015 DEBUG_FUNCTION void
1016 debug (vec<rtx_insn *> *ptr)
1018 if (ptr)
1019 debug (*ptr);
1020 else
1021 fprintf (stderr, "<nil>\n");
1024 /* Dump an insn vector SUCCS. */
1025 DEBUG_FUNCTION void
1026 debug_insn_vector (rtx_vec_t succs)
1028 switch_dump (stderr);
1029 dump_insn_vector (succs);
1030 sel_print ("\n");
1031 restore_dump ();
1034 /* Dump a hard reg set SET to stderr. */
1035 DEBUG_FUNCTION void
1036 debug_hard_reg_set (HARD_REG_SET set)
1038 switch_dump (stderr);
1039 dump_hard_reg_set ("", set);
1040 sel_print ("\n");
1041 restore_dump ();
1044 /* Debug a cfg region with default flags. */
1045 void
1046 sel_debug_cfg (void)
1048 sel_debug_cfg_1 (sel_debug_cfg_flags);
1051 /* Print a current cselib value for X's address to stderr. */
1052 DEBUG_FUNCTION rtx
1053 debug_mem_addr_value (rtx x)
1055 rtx t, addr;
1056 machine_mode address_mode;
1058 gcc_assert (MEM_P (x));
1059 address_mode = get_address_mode (x);
1061 t = shallow_copy_rtx (x);
1062 if (cselib_lookup (XEXP (t, 0), address_mode, 0, GET_MODE (t)))
1063 XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0), GET_MODE (t));
1065 t = canon_rtx (t);
1066 addr = get_addr (XEXP (t, 0));
1067 debug_rtx (t);
1068 debug_rtx (addr);
1069 return t;
1071 #endif