* config/pa/linux-atomic.c (__kernel_cmpxchg): Reorder arguments to
[official-gcc.git] / gcc / sel-sched-dump.c
blob87d4dc5727dd52547af6958551f84ce059dd5278
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 "function.h"
30 #include "predict.h"
31 #include "dominance.h"
32 #include "cfg.h"
33 #include "basic-block.h"
34 #include "flags.h"
35 #include "insn-config.h"
36 #include "insn-attr.h"
37 #include "params.h"
38 #include "alloc-pool.h"
39 #include "cselib.h"
40 #include "target.h"
42 #ifdef INSN_SCHEDULING
43 #include "sel-sched-ir.h"
44 #include "sel-sched-dump.h"
47 /* These variables control high-level pretty printing. */
48 static int sel_dump_cfg_flags = SEL_DUMP_CFG_FLAGS;
49 static int sel_debug_cfg_flags = SEL_DUMP_CFG_FLAGS;
51 /* True when a cfg should be dumped. */
52 static bool sel_dump_cfg_p;
54 /* Variables that are used to build the cfg dump file name. */
55 static const char * const sel_debug_cfg_root = "./";
56 static const char * const sel_debug_cfg_root_postfix_default = "";
57 static const char *sel_debug_cfg_root_postfix = "";
58 static int sel_dump_cfg_fileno = -1;
59 static int sel_debug_cfg_fileno = -1;
61 /* When this flag is on, we are dumping to the .dot file.
62 When it is off, we are dumping to log.
63 This is useful to differentiate formatting between log and .dot
64 files. */
65 bool sched_dump_to_dot_p = false;
67 /* Controls how insns from a fence list should be dumped. */
68 static int dump_flist_insn_flags = (DUMP_INSN_UID | DUMP_INSN_BBN
69 | DUMP_INSN_SEQNO);
72 /* The variable used to hold the value of sched_dump when temporarily
73 switching dump output to the other source, e.g. the .dot file. */
74 static FILE *saved_sched_dump = NULL;
76 /* Switch sched_dump to TO. It must not be called twice. */
77 static void
78 switch_dump (FILE *to)
80 gcc_assert (saved_sched_dump == NULL);
82 saved_sched_dump = sched_dump;
83 sched_dump = to;
86 /* Restore previously switched dump. */
87 static void
88 restore_dump (void)
90 sched_dump = saved_sched_dump;
91 saved_sched_dump = NULL;
95 /* Functions for dumping instructions, av sets, and exprs. */
97 /* Default flags for dumping insns. */
98 static int dump_insn_rtx_flags = DUMP_INSN_RTX_UID | DUMP_INSN_RTX_PATTERN;
100 /* Default flags for dumping vinsns. */
101 static int dump_vinsn_flags = (DUMP_VINSN_INSN_RTX | DUMP_VINSN_TYPE
102 | DUMP_VINSN_COUNT);
104 /* Default flags for dumping expressions. */
105 static int dump_expr_flags = DUMP_EXPR_ALL;
107 /* Default flags for dumping insns when debugging. */
108 static int debug_insn_rtx_flags = DUMP_INSN_RTX_ALL;
110 /* Default flags for dumping vinsns when debugging. */
111 static int debug_vinsn_flags = DUMP_VINSN_ALL;
113 /* Default flags for dumping expressions when debugging. */
114 static int debug_expr_flags = DUMP_EXPR_ALL;
116 /* Controls how an insn from stream should be dumped when debugging. */
117 static int debug_insn_flags = DUMP_INSN_ALL;
119 /* Print an rtx X. */
120 void
121 sel_print_rtl (rtx x)
123 print_rtl_single (sched_dump, x);
126 /* Dump insn INSN honoring FLAGS. */
127 void
128 dump_insn_rtx_1 (rtx insn, int flags)
130 int all;
132 /* flags == -1 also means dumping all. */
133 all = (flags & 1);;
134 if (all)
135 flags |= DUMP_INSN_RTX_ALL;
137 sel_print ("(");
139 if (flags & DUMP_INSN_RTX_UID)
140 sel_print ("%d;", INSN_UID (insn));
142 if (flags & DUMP_INSN_RTX_PATTERN)
143 sel_print ("%s;", str_pattern_slim (PATTERN (insn)));
145 if (flags & DUMP_INSN_RTX_BBN)
147 basic_block bb = BLOCK_FOR_INSN (insn);
149 sel_print ("bb:%d;", bb != NULL ? bb->index : -1);
152 sel_print (")");
156 /* Dump INSN with default flags. */
157 void
158 dump_insn_rtx (rtx insn)
160 dump_insn_rtx_1 (insn, dump_insn_rtx_flags);
164 /* Dump INSN to stderr. */
165 DEBUG_FUNCTION void
166 debug_insn_rtx (rtx insn)
168 switch_dump (stderr);
169 dump_insn_rtx_1 (insn, debug_insn_rtx_flags);
170 sel_print ("\n");
171 restore_dump ();
174 /* Dump vinsn VI honoring flags. */
175 void
176 dump_vinsn_1 (vinsn_t vi, int flags)
178 int all;
180 /* flags == -1 also means dumping all. */
181 all = flags & 1;
182 if (all)
183 flags |= DUMP_VINSN_ALL;
185 sel_print ("(");
187 if (flags & DUMP_VINSN_INSN_RTX)
188 dump_insn_rtx_1 (VINSN_INSN_RTX (vi), dump_insn_rtx_flags | all);
190 if (flags & DUMP_VINSN_TYPE)
191 sel_print ("type:%s;", GET_RTX_NAME (VINSN_TYPE (vi)));
193 if (flags & DUMP_VINSN_COUNT)
194 sel_print ("count:%d;", VINSN_COUNT (vi));
196 if (flags & DUMP_VINSN_COST)
198 int cost = vi->cost;
200 if (cost != -1)
201 sel_print ("cost:%d;", cost);
204 sel_print (")");
207 /* Dump vinsn VI with default flags. */
208 void
209 dump_vinsn (vinsn_t vi)
211 dump_vinsn_1 (vi, dump_vinsn_flags);
214 DEBUG_FUNCTION void
215 debug (vinsn_def &ref)
217 switch_dump (stderr);
218 dump_vinsn_1 (&ref, dump_vinsn_flags);
219 sel_print ("\n");
220 restore_dump ();
223 DEBUG_FUNCTION void
224 debug (vinsn_def *ptr)
226 if (ptr)
227 debug (*ptr);
228 else
229 fprintf (stderr, "<nil>\n");
232 DEBUG_FUNCTION void
233 debug_verbose (vinsn_def &ref)
235 switch_dump (stderr);
236 dump_vinsn_1 (&ref, debug_vinsn_flags);
237 sel_print ("\n");
238 restore_dump ();
241 DEBUG_FUNCTION void
242 debug_verbose (vinsn_def *ptr)
244 if (ptr)
245 debug (*ptr);
246 else
247 fprintf (stderr, "<nil>\n");
250 /* Dump vinsn VI to stderr. */
251 DEBUG_FUNCTION void
252 debug_vinsn (vinsn_t vi)
254 switch_dump (stderr);
255 dump_vinsn_1 (vi, debug_vinsn_flags);
256 sel_print ("\n");
257 restore_dump ();
260 /* Dump EXPR honoring flags. */
261 void
262 dump_expr_1 (expr_t expr, int flags)
264 int all;
266 /* flags == -1 also means dumping all. */
267 all = flags & 1;
268 if (all)
269 flags |= DUMP_EXPR_ALL;
271 sel_print ("[");
273 if (flags & DUMP_EXPR_VINSN)
274 dump_vinsn_1 (EXPR_VINSN (expr), dump_vinsn_flags | all);
276 if (flags & DUMP_EXPR_SPEC)
278 int spec = EXPR_SPEC (expr);
280 if (spec != 0)
281 sel_print ("spec:%d;", spec);
284 if (flags & DUMP_EXPR_USEFULNESS)
286 int use = EXPR_USEFULNESS (expr);
288 if (use != REG_BR_PROB_BASE)
289 sel_print ("use:%d;", use);
292 if (flags & DUMP_EXPR_PRIORITY)
293 sel_print ("prio:%d;", EXPR_PRIORITY (expr));
295 if (flags & DUMP_EXPR_SCHED_TIMES)
297 int times = EXPR_SCHED_TIMES (expr);
299 if (times != 0)
300 sel_print ("times:%d;", times);
303 if (flags & DUMP_EXPR_SPEC_DONE_DS)
305 ds_t spec_done_ds = EXPR_SPEC_DONE_DS (expr);
307 if (spec_done_ds != 0)
308 sel_print ("ds:%d;", spec_done_ds);
311 if (flags & DUMP_EXPR_ORIG_BB)
313 int orig_bb = EXPR_ORIG_BB_INDEX (expr);
315 if (orig_bb != 0)
316 sel_print ("orig_bb:%d;", orig_bb);
319 if (EXPR_TARGET_AVAILABLE (expr) < 1)
320 sel_print ("target:%d;", EXPR_TARGET_AVAILABLE (expr));
321 sel_print ("]");
324 /* Dump expression EXPR with default flags. */
325 void
326 dump_expr (expr_t expr)
328 dump_expr_1 (expr, dump_expr_flags);
331 /* Dump expression EXPR to stderr. */
332 DEBUG_FUNCTION void
333 debug_expr (expr_t expr)
335 switch_dump (stderr);
336 dump_expr_1 (expr, debug_expr_flags);
337 sel_print ("\n");
338 restore_dump ();
341 /* Dump expression REF. */
343 DEBUG_FUNCTION void
344 debug (expr_def &ref)
346 switch_dump (stderr);
347 dump_expr_1 (&ref, 0);
348 sel_print ("\n");
349 restore_dump ();
352 DEBUG_FUNCTION void
353 debug (expr_def *ptr)
355 if (ptr)
356 debug (*ptr);
357 else
358 fprintf (stderr, "<nil>\n");
361 /* Dump expression REF verbosely. */
363 DEBUG_FUNCTION void
364 debug_verbose (expr_def &ref)
366 switch_dump (stderr);
367 dump_expr_1 (&ref, DUMP_EXPR_ALL);
368 sel_print ("\n");
369 restore_dump ();
372 DEBUG_FUNCTION void
373 debug_verbose (expr_def *ptr)
375 if (ptr)
376 debug_verbose (*ptr);
377 else
378 fprintf (stderr, "<nil>\n");
381 /* Dump insn I honoring FLAGS. */
382 void
383 dump_insn_1 (insn_t i, int flags)
385 int all;
387 all = flags & 1;
388 if (all)
389 flags |= DUMP_INSN_ALL;
391 if (!sched_dump_to_dot_p)
392 sel_print ("(");
394 if (flags & DUMP_INSN_EXPR)
396 dump_expr_1 (INSN_EXPR (i), dump_expr_flags | all);
397 sel_print (";");
399 else if (flags & DUMP_INSN_PATTERN)
401 dump_insn_rtx_1 (i, DUMP_INSN_RTX_PATTERN | all);
402 sel_print (";");
404 else if (flags & DUMP_INSN_UID)
405 sel_print ("uid:%d;", INSN_UID (i));
407 if (flags & DUMP_INSN_SEQNO)
408 sel_print ("seqno:%d;", INSN_SEQNO (i));
410 if (flags & DUMP_INSN_SCHED_CYCLE)
412 int cycle = INSN_SCHED_CYCLE (i);
414 if (cycle != 0)
415 sel_print ("cycle:%d;", cycle);
418 if (!sched_dump_to_dot_p)
419 sel_print (")");
422 /* Dump insn I with default flags. */
423 void
424 dump_insn (insn_t i)
426 dump_insn_1 (i, DUMP_INSN_EXPR | DUMP_INSN_SCHED_CYCLE);
429 /* Dump INSN to stderr. */
430 DEBUG_FUNCTION void
431 debug_insn (insn_t insn)
433 switch_dump (stderr);
434 dump_insn_1 (insn, debug_insn_flags);
435 sel_print ("\n");
436 restore_dump ();
439 /* Dumps av_set AV. */
440 void
441 dump_av_set (av_set_t av)
443 av_set_iterator i;
444 expr_t expr;
446 if (!sched_dump_to_dot_p)
447 sel_print ("{");
449 FOR_EACH_EXPR (expr, i, av)
451 dump_expr (expr);
452 if (!sched_dump_to_dot_p)
453 sel_print (" ");
454 else
455 sel_print ("\n");
458 if (!sched_dump_to_dot_p)
459 sel_print ("}");
462 /* Dumps lvset LV. */
463 void
464 dump_lv_set (regset lv)
466 sel_print ("{");
468 /* This code was adapted from cfg.c: dump_regset (). */
469 if (lv == NULL)
470 sel_print ("nil");
471 else
473 unsigned i;
474 reg_set_iterator rsi;
475 int count = 0;
477 EXECUTE_IF_SET_IN_REG_SET (lv, 0, i, rsi)
479 sel_print (" %d", i);
480 if (i < FIRST_PSEUDO_REGISTER)
482 sel_print (" [%s]", reg_names[i]);
483 ++count;
486 ++count;
488 if (sched_dump_to_dot_p && count == 12)
490 count = 0;
491 sel_print ("\n");
496 sel_print ("}\n");
499 /* Dumps a list of instructions pointed to by P. */
500 static void
501 dump_ilist (ilist_t p)
503 while (p)
505 dump_insn (ILIST_INSN (p));
506 p = ILIST_NEXT (p);
510 /* Dumps a list of boundaries pointed to by BNDS. */
511 void
512 dump_blist (blist_t bnds)
514 for (; bnds; bnds = BLIST_NEXT (bnds))
516 bnd_t bnd = BLIST_BND (bnds);
518 sel_print ("[to: %d; ptr: ", INSN_UID (BND_TO (bnd)));
519 dump_ilist (BND_PTR (bnd));
520 sel_print ("] ");
524 /* Dumps a list of fences pointed to by L. */
525 void
526 dump_flist (flist_t l)
528 while (l)
530 dump_insn_1 (FENCE_INSN (FLIST_FENCE (l)), dump_flist_insn_flags);
531 sel_print (" ");
532 l = FLIST_NEXT (l);
536 /* Dumps an insn vector SUCCS. */
537 void
538 dump_insn_vector (rtx_vec_t succs)
540 int i;
541 rtx_insn *succ;
543 FOR_EACH_VEC_ELT (succs, i, succ)
544 if (succ)
545 dump_insn (succ);
546 else
547 sel_print ("NULL ");
550 /* Dumps a hard reg set SET to FILE using PREFIX. */
551 static void
552 print_hard_reg_set (FILE *file, const char *prefix, HARD_REG_SET set)
554 int i;
556 fprintf (file, "%s{ ", prefix);
557 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
559 if (TEST_HARD_REG_BIT (set, i))
560 fprintf (file, "%d ", i);
562 fprintf (file, "}\n");
565 /* Dumps a hard reg set SET using PREFIX. */
566 void
567 dump_hard_reg_set (const char *prefix, HARD_REG_SET set)
569 print_hard_reg_set (sched_dump, prefix, set);
572 /* Pretty print INSN. This is used as a hook. */
573 const char *
574 sel_print_insn (const rtx_insn *insn, int aligned ATTRIBUTE_UNUSED)
576 static char buf[80];
578 /* '+' before insn means it is a new cycle start and it's not been
579 scheduled yet. '>' - has been scheduled. */
580 if (s_i_d.exists () && INSN_LUID (insn) > 0)
581 if (GET_MODE (insn) == TImode)
582 sprintf (buf, "%s %4d",
583 INSN_SCHED_TIMES (insn) > 0 ? "> " : "< ",
584 INSN_UID (insn));
585 else
586 sprintf (buf, "%s %4d",
587 INSN_SCHED_TIMES (insn) > 0 ? "! " : " ",
588 INSN_UID (insn));
589 else
590 if (GET_MODE (insn) == TImode)
591 sprintf (buf, "+ %4d", INSN_UID (insn));
592 else
593 sprintf (buf, " %4d", INSN_UID (insn));
595 return buf;
599 /* Functions for pretty printing of CFG. */
600 /* FIXME: Using pretty-print here could simplify this stuff. */
602 /* Replace all occurencies of STR1 to STR2 in BUF.
603 The BUF must be large enough to hold the result. */
604 static void
605 replace_str_in_buf (char *buf, const char *str1, const char *str2)
607 int buf_len = strlen (buf);
608 int str1_len = strlen (str1);
609 int str2_len = strlen (str2);
610 int diff = str2_len - str1_len;
612 char *p = buf;
615 p = strstr (p, str1);
616 if (p)
618 char *p1 = p + str1_len;
619 /* Copy the rest of buf and '\0'. */
620 int n = buf + buf_len - p1;
621 int i;
623 /* Shift str by DIFF chars. */
624 if (diff > 0)
625 for (i = n; i >= 0; i--)
626 p1[i + diff] = p1[i];
627 else
628 for (i = 0; i <= n; i++)
629 p1[i + diff] = p1[i];
631 /* Copy str2. */
632 for (i = 0; i < str2_len; i++)
633 p[i] = str2[i];
635 p += str2_len;
636 buf_len += diff;
640 while (p);
643 /* Replace characters in BUF that have special meaning in .dot file.
644 Similar to pp_write_text_as_dot_label_to_stream. */
645 static void
646 sel_prepare_string_for_dot_label (char *buf)
648 static char specials_from[7][2] = { "<", ">", "{", "|", "}", "\"",
649 "\n" };
650 static char specials_to[7][3] = { "\\<", "\\>", "\\{", "\\|", "\\}",
651 "\\\"", "\\l" };
652 unsigned i;
654 for (i = 0; i < 7; i++)
655 replace_str_in_buf (buf, specials_from[i], specials_to[i]);
658 /* This function acts like printf but dumps to the sched_dump file. */
659 void
660 sel_print (const char *fmt, ...)
662 va_list ap;
663 va_start (ap, fmt);
664 if (sched_dump_to_dot_p)
666 char *message;
667 if (vasprintf (&message, fmt, ap) >= 0 && message != NULL)
669 message = (char *) xrealloc (message, 2 * strlen (message) + 1);
670 sel_prepare_string_for_dot_label (message);
671 fprintf (sched_dump, "%s", message);
672 free (message);
675 else
676 vfprintf (sched_dump, fmt, ap);
677 va_end (ap);
680 /* Dump INSN with FLAGS. */
681 static void
682 sel_dump_cfg_insn (insn_t insn, int flags)
684 int insn_flags = DUMP_INSN_UID | DUMP_INSN_PATTERN;
686 if (sched_luids.exists () && INSN_LUID (insn) > 0)
688 if (flags & SEL_DUMP_CFG_INSN_SEQNO)
689 insn_flags |= DUMP_INSN_SEQNO | DUMP_INSN_SCHED_CYCLE | DUMP_INSN_EXPR;
692 dump_insn_1 (insn, insn_flags);
695 /* Dump E to the dot file F. */
696 static void
697 sel_dump_cfg_edge (FILE *f, edge e)
699 int w;
700 const char *color;
702 if (e->flags & EDGE_FALLTHRU)
704 w = 10;
705 color = ", color = red";
707 else if (e->src->next_bb == e->dest)
709 w = 3;
710 color = ", color = blue";
712 else
714 w = 1;
715 color = "";
718 fprintf (f, "\tbb%d -> bb%d [weight = %d%s];\n",
719 e->src->index, e->dest->index, w, color);
723 /* Return true if BB has a predesessor from current region.
724 TODO: Either make this function to trace back through empty block
725 or just remove those empty blocks. */
726 static bool
727 has_preds_in_current_region_p (basic_block bb)
729 edge e;
730 edge_iterator ei;
732 gcc_assert (!in_current_region_p (bb));
734 FOR_EACH_EDGE (e, ei, bb->preds)
735 if (in_current_region_p (e->src))
736 return true;
738 return false;
741 /* Dump a cfg region to the dot file F honoring FLAGS. */
742 static void
743 sel_dump_cfg_2 (FILE *f, int flags)
745 basic_block bb;
747 sched_dump_to_dot_p = true;
748 switch_dump (f);
750 fprintf (f, "digraph G {\n"
751 "\tratio = 2.25;\n"
752 "\tnode [shape = record, fontsize = 9];\n");
754 if (flags & SEL_DUMP_CFG_FUNCTION_NAME)
755 fprintf (f, "function [label = \"%s\"];\n", current_function_name ());
757 FOR_EACH_BB_FN (bb, cfun)
759 insn_t insn = BB_HEAD (bb);
760 insn_t next_tail = NEXT_INSN (BB_END (bb));
761 edge e;
762 edge_iterator ei;
763 bool in_region_p = ((flags & SEL_DUMP_CFG_CURRENT_REGION)
764 && in_current_region_p (bb));
765 bool full_p = (!(flags & SEL_DUMP_CFG_CURRENT_REGION)
766 || in_region_p);
767 bool some_p = full_p || has_preds_in_current_region_p (bb);
768 const char *color;
769 const char *style;
771 if (!some_p)
772 continue;
774 if ((flags & SEL_DUMP_CFG_CURRENT_REGION)
775 && in_current_region_p (bb)
776 && BLOCK_TO_BB (bb->index) == 0)
777 color = "color = green, ";
778 else
779 color = "";
781 if ((flags & SEL_DUMP_CFG_FENCES)
782 && in_region_p)
784 style = "";
786 if (!sel_bb_empty_p (bb))
788 bool first_p = true;
789 insn_t tail = BB_END (bb);
790 insn_t cur_insn;
792 cur_insn = bb_note (bb);
796 fence_t fence;
798 cur_insn = NEXT_INSN (cur_insn);
799 fence = flist_lookup (fences, cur_insn);
801 if (fence != NULL)
803 if (!FENCE_SCHEDULED_P (fence))
805 if (first_p)
806 color = "color = red, ";
807 else
808 color = "color = yellow, ";
810 else
811 color = "color = blue, ";
814 first_p = false;
816 while (cur_insn != tail);
819 else if (!full_p)
820 style = "style = dashed, ";
821 else
822 style = "";
824 fprintf (f, "\tbb%d [%s%slabel = \"{Basic block %d", bb->index,
825 style, color, bb->index);
827 if ((flags & SEL_DUMP_CFG_BB_LOOP)
828 && bb->loop_father != NULL)
829 fprintf (f, ", loop %d", bb->loop_father->num);
831 if (full_p
832 && (flags & SEL_DUMP_CFG_BB_NOTES_LIST))
834 insn_t notes = BB_NOTE_LIST (bb);
836 if (notes != NULL_RTX)
838 fprintf (f, "|");
840 /* For simplicity, we dump notes from note_list in reversed order
841 to that what they will appear in the code. */
842 while (notes != NULL_RTX)
844 sel_dump_cfg_insn (notes, flags);
845 fprintf (f, "\\l");
847 notes = PREV_INSN (notes);
852 if (full_p
853 && (flags & SEL_DUMP_CFG_AV_SET)
854 && in_current_region_p (bb)
855 && !sel_bb_empty_p (bb))
857 fprintf (f, "|");
859 if (BB_AV_SET_VALID_P (bb))
860 dump_av_set (BB_AV_SET (bb));
861 else if (BB_AV_LEVEL (bb) == -1)
862 fprintf (f, "AV_SET needs update");
865 if ((flags & SEL_DUMP_CFG_LV_SET)
866 && !sel_bb_empty_p (bb))
868 fprintf (f, "|");
870 if (BB_LV_SET_VALID_P (bb))
871 dump_lv_set (BB_LV_SET (bb));
872 else
873 fprintf (f, "LV_SET needs update");
876 if (full_p
877 && (flags & SEL_DUMP_CFG_BB_INSNS))
879 fprintf (f, "|");
880 while (insn != next_tail)
882 sel_dump_cfg_insn (insn, flags);
883 fprintf (f, "\\l");
885 insn = NEXT_INSN (insn);
889 fprintf (f, "}\"];\n");
891 FOR_EACH_EDGE (e, ei, bb->succs)
892 if (full_p || in_current_region_p (e->dest))
893 sel_dump_cfg_edge (f, e);
896 fprintf (f, "}");
898 restore_dump ();
899 sched_dump_to_dot_p = false;
902 /* Dump a cfg region to the file specified by TAG honoring flags.
903 The file is created by the function. */
904 static void
905 sel_dump_cfg_1 (const char *tag, int flags)
907 char *buf;
908 int i;
909 FILE *f;
911 ++sel_dump_cfg_fileno;
913 if (!sel_dump_cfg_p)
914 return;
916 i = 1 + snprintf (NULL, 0, "%s/%s%05d-%s.dot", sel_debug_cfg_root,
917 sel_debug_cfg_root_postfix, sel_dump_cfg_fileno, tag);
918 buf = XNEWVEC (char, i);
919 snprintf (buf, i, "%s/%s%05d-%s.dot", sel_debug_cfg_root,
920 sel_debug_cfg_root_postfix, sel_dump_cfg_fileno, tag);
922 f = fopen (buf, "w");
924 if (f == NULL)
925 fprintf (stderr, "Can't create file: %s.\n", buf);
926 else
928 sel_dump_cfg_2 (f, flags);
930 fclose (f);
933 free (buf);
936 /* Setup cfg dumping flags. Used for debugging. */
937 void
938 setup_dump_cfg_params (void)
940 sel_dump_cfg_flags = SEL_DUMP_CFG_FLAGS;
941 sel_dump_cfg_p = 0;
942 sel_debug_cfg_root_postfix = sel_debug_cfg_root_postfix_default;
945 /* Debug a cfg region with FLAGS. */
946 void
947 sel_debug_cfg_1 (int flags)
949 bool t1 = sel_dump_cfg_p;
950 int t2 = sel_dump_cfg_fileno;
952 sel_dump_cfg_p = true;
953 sel_dump_cfg_fileno = ++sel_debug_cfg_fileno;
955 sel_dump_cfg_1 ("sel-debug-cfg", flags);
957 sel_dump_cfg_fileno = t2;
958 sel_dump_cfg_p = t1;
961 /* Dumps av_set AV to stderr. */
962 DEBUG_FUNCTION void
963 debug_av_set (av_set_t av)
965 switch_dump (stderr);
966 dump_av_set (av);
967 sel_print ("\n");
968 restore_dump ();
971 /* Dump LV to stderr. */
972 DEBUG_FUNCTION void
973 debug_lv_set (regset lv)
975 switch_dump (stderr);
976 dump_lv_set (lv);
977 sel_print ("\n");
978 restore_dump ();
981 /* Dump an instruction list P to stderr. */
982 DEBUG_FUNCTION void
983 debug_ilist (ilist_t p)
985 switch_dump (stderr);
986 dump_ilist (p);
987 sel_print ("\n");
988 restore_dump ();
991 /* Dump a boundary list BNDS to stderr. */
992 DEBUG_FUNCTION void
993 debug_blist (blist_t bnds)
995 switch_dump (stderr);
996 dump_blist (bnds);
997 sel_print ("\n");
998 restore_dump ();
1001 /* Dump a rtx vector REF. */
1002 DEBUG_FUNCTION void
1003 debug (vec<rtx_insn *> &ref)
1005 switch_dump (stderr);
1006 dump_insn_vector (ref);
1007 sel_print ("\n");
1008 restore_dump ();
1011 DEBUG_FUNCTION void
1012 debug (vec<rtx_insn *> *ptr)
1014 if (ptr)
1015 debug (*ptr);
1016 else
1017 fprintf (stderr, "<nil>\n");
1020 /* Dump an insn vector SUCCS. */
1021 DEBUG_FUNCTION void
1022 debug_insn_vector (rtx_vec_t succs)
1024 switch_dump (stderr);
1025 dump_insn_vector (succs);
1026 sel_print ("\n");
1027 restore_dump ();
1030 /* Dump a hard reg set SET to stderr. */
1031 DEBUG_FUNCTION void
1032 debug_hard_reg_set (HARD_REG_SET set)
1034 switch_dump (stderr);
1035 dump_hard_reg_set ("", set);
1036 sel_print ("\n");
1037 restore_dump ();
1040 /* Debug a cfg region with default flags. */
1041 void
1042 sel_debug_cfg (void)
1044 sel_debug_cfg_1 (sel_debug_cfg_flags);
1047 /* Print a current cselib value for X's address to stderr. */
1048 DEBUG_FUNCTION rtx
1049 debug_mem_addr_value (rtx x)
1051 rtx t, addr;
1052 machine_mode address_mode;
1054 gcc_assert (MEM_P (x));
1055 address_mode = get_address_mode (x);
1057 t = shallow_copy_rtx (x);
1058 if (cselib_lookup (XEXP (t, 0), address_mode, 0, GET_MODE (t)))
1059 XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0), GET_MODE (t));
1061 t = canon_rtx (t);
1062 addr = get_addr (XEXP (t, 0));
1063 debug_rtx (t);
1064 debug_rtx (addr);
1065 return t;
1067 #endif