OSDN Git Service

2008-12-09 Tobias Grosser <grosser@fim.uni-passau.de>
[pf3gnuchains/gcc-fork.git] / gcc / gimple-pretty-print.c
1 /* Pretty formatting of GIMPLE statements and expressions.
2    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
3    Free Software Foundation, Inc.
4    Contributed by Aldy Hernandez <aldyh@redhat.com> and
5    Diego Novillo <dnovillo@google.com>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "tree.h"
28 #include "diagnostic.h"
29 #include "real.h"
30 #include "hashtab.h"
31 #include "tree-flow.h"
32 #include "tree-pass.h"
33 #include "gimple.h"
34 #include "value-prof.h"
35
36 #define INDENT(SPACE)                                                   \
37   do { int i; for (i = 0; i < SPACE; i++) pp_space (buffer); } while (0)
38
39 static pretty_printer buffer;
40 static bool initialized = false;
41
42 #define GIMPLE_NIY do_niy (buffer,gs)
43
44 /* Try to print on BUFFER a default message for the unrecognized
45    gimple statement GS.  */
46
47 static void
48 do_niy (pretty_printer *buffer, gimple gs)
49 {
50   pp_printf (buffer, "<<< Unknown GIMPLE statement: %s >>>\n",
51              gimple_code_name[(int) gimple_code (gs)]);
52 }
53
54
55 /* Initialize the pretty printer on FILE if needed.  */
56
57 static void
58 maybe_init_pretty_print (FILE *file)
59 {
60   if (!initialized)
61     {
62       pp_construct (&buffer, NULL, 0);
63       pp_needs_newline (&buffer) = true;
64       initialized = true;
65     }
66
67   buffer.buffer->stream = file;
68 }
69
70
71 /* Emit a newline and SPC indentantion spaces to BUFFER.  */
72
73 static void
74 newline_and_indent (pretty_printer *buffer, int spc)
75 {
76   pp_newline (buffer);
77   INDENT (spc);
78 }
79
80
81 /* Print the GIMPLE statement GS on stderr.  */
82
83 void
84 debug_gimple_stmt (gimple gs)
85 {
86   print_gimple_stmt (stderr, gs, 0, TDF_VOPS|TDF_MEMSYMS);
87   fprintf (stderr, "\n");
88 }
89
90
91 /* Dump GIMPLE statement G to FILE using SPC indentantion spaces and
92    FLAGS as in dump_gimple_stmt.  */
93
94 void
95 print_gimple_stmt (FILE *file, gimple g, int spc, int flags)
96 {
97   maybe_init_pretty_print (file);
98   dump_gimple_stmt (&buffer, g, spc, flags);
99   pp_flush (&buffer);
100 }
101
102
103 /* Dump GIMPLE statement G to FILE using SPC indentantion spaces and
104    FLAGS as in dump_gimple_stmt.  Print only the right-hand side
105    of the statement.  */
106
107 void
108 print_gimple_expr (FILE *file, gimple g, int spc, int flags)
109 {
110   flags |= TDF_RHS_ONLY;
111   maybe_init_pretty_print (file);
112   dump_gimple_stmt (&buffer, g, spc, flags);
113 }
114
115
116 /* Print the GIMPLE sequence SEQ on BUFFER using SPC indentantion
117    spaces and FLAGS as in dump_gimple_stmt.  */
118
119 static void
120 dump_gimple_seq (pretty_printer *buffer, gimple_seq seq, int spc, int flags)
121 {
122   gimple_stmt_iterator i;
123
124   for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
125     {
126       gimple gs = gsi_stmt (i);
127       INDENT (spc);
128       dump_gimple_stmt (buffer, gs, spc, flags);
129       if (!gsi_one_before_end_p (i))
130         pp_newline (buffer);
131     }
132 }
133
134
135 /* Dump GIMPLE sequence SEQ to FILE using SPC indentantion spaces and
136    FLAGS as in dump_gimple_stmt.  */
137
138 void
139 print_gimple_seq (FILE *file, gimple_seq seq, int spc, int flags)
140 {
141   maybe_init_pretty_print (file);
142   dump_gimple_seq (&buffer, seq, spc, flags);
143   pp_flush (&buffer);
144 }
145
146
147 /* Print the GIMPLE sequence SEQ on stderr.  */
148
149 void
150 debug_gimple_seq (gimple_seq seq)
151 {
152   print_gimple_seq (stderr, seq, 0, TDF_VOPS|TDF_MEMSYMS);
153 }
154
155
156 /* A simple helper to pretty-print some of the gimple tuples in the printf
157    style. The format modifiers are preceeded by '%' and are:
158      'G' - outputs a string corresponding to the code of the given gimple,
159      'S' - outputs a gimple_seq with indent of spc + 2,
160      'T' - outputs the tree t,
161      'd' - outputs an int as a decimal,
162      's' - outputs a string,
163      'n' - outputs a newline,
164      '+' - increases indent by 2 then outputs a newline,
165      '-' - decreases indent by 2 then outputs a newline.   */
166
167 static void
168 dump_gimple_fmt (pretty_printer *buffer, int spc, int flags,
169                  const char *fmt, ...)
170 {
171   va_list args;
172   const char *c;
173   const char *tmp;
174
175   va_start (args, fmt);
176   for (c = fmt; *c; c++)
177     {
178       if (*c == '%')
179         {
180           gimple_seq seq;
181           tree t;
182           gimple g;
183           switch (*++c)
184             {
185               case 'G':
186                 g = va_arg (args, gimple);
187                 tmp = gimple_code_name[gimple_code (g)];
188                 pp_string (buffer, tmp);
189                 break;
190
191               case 'S':
192                 seq = va_arg (args, gimple_seq);
193                 pp_newline (buffer);
194                 dump_gimple_seq (buffer, seq, spc + 2, flags);
195                 newline_and_indent (buffer, spc);
196                 break;
197
198               case 'T':
199                 t = va_arg (args, tree);
200                 if (t == NULL_TREE)
201                   pp_string (buffer, "NULL");
202                 else
203                   dump_generic_node (buffer, t, spc, flags, false);
204                 break;
205
206               case 'd':
207                 pp_decimal_int (buffer, va_arg (args, int));
208                 break;
209
210               case 's':
211                 pp_string (buffer, va_arg (args, char *));
212                 break;
213
214               case 'n':
215                 newline_and_indent (buffer, spc);
216                 break;
217
218               case '+':
219                 spc += 2;
220                 newline_and_indent (buffer, spc);
221                 break;
222
223               case '-':
224                 spc -= 2;
225                 newline_and_indent (buffer, spc);
226                 break;
227
228               default:
229                 gcc_unreachable ();
230             }
231         } 
232       else
233         pp_character (buffer, *c);
234     }
235   va_end (args);
236 }
237
238
239 /* Helper for dump_gimple_assign.  Print the unary RHS of the
240    assignment GS.  BUFFER, SPC and FLAGS are as in dump_gimple_stmt.  */
241
242 static void
243 dump_unary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
244 {
245   enum tree_code rhs_code = gimple_assign_rhs_code (gs);
246   tree lhs = gimple_assign_lhs (gs);
247   tree rhs = gimple_assign_rhs1 (gs);
248
249   switch (rhs_code)
250     {
251     case VIEW_CONVERT_EXPR:
252     case ASSERT_EXPR:
253       dump_generic_node (buffer, rhs, spc, flags, false);
254       break;
255
256     case FIXED_CONVERT_EXPR:
257     case FIX_TRUNC_EXPR:
258     case FLOAT_EXPR:
259     CASE_CONVERT:
260       pp_string (buffer, "(");
261       dump_generic_node (buffer, TREE_TYPE (lhs), spc, flags, false);
262       pp_string (buffer, ") ");
263       dump_generic_node (buffer, rhs, spc, flags, false);
264       break;
265       
266     case PAREN_EXPR:
267       pp_string (buffer, "((");
268       dump_generic_node (buffer, rhs, spc, flags, false);
269       pp_string (buffer, "))");
270       break;
271       
272     case ABS_EXPR:
273       pp_string (buffer, "ABS_EXPR <");
274       dump_generic_node (buffer, rhs, spc, flags, false);
275       pp_string (buffer, ">");
276       break;
277
278     default:
279       if (TREE_CODE_CLASS (rhs_code) == tcc_declaration
280           || TREE_CODE_CLASS (rhs_code) == tcc_constant
281           || TREE_CODE_CLASS (rhs_code) == tcc_reference
282           || rhs_code == SSA_NAME
283           || rhs_code == ADDR_EXPR
284           || rhs_code == CONSTRUCTOR)
285         ; /* do nothing.  */
286       else if (rhs_code == BIT_NOT_EXPR)
287         pp_string (buffer, "~");
288       else if (rhs_code == TRUTH_NOT_EXPR)
289         pp_string (buffer, "!");
290       else if (rhs_code == NEGATE_EXPR)
291         pp_string (buffer, "-");
292       else
293         {
294           pp_string (buffer, "[");
295           pp_string (buffer, tree_code_name [rhs_code]);
296           pp_string (buffer, "] ");
297         }
298
299       dump_generic_node (buffer, rhs, spc, flags, false);
300       break;
301     }
302 }
303
304
305 /* Helper for dump_gimple_assign.  Print the binary RHS of the
306    assignment GS.  BUFFER, SPC and FLAGS are as in dump_gimple_stmt.  */
307
308 static void
309 dump_binary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
310 {
311   switch (gimple_assign_rhs_code (gs))
312     {
313     case COMPLEX_EXPR:
314       pp_string (buffer, "COMPLEX_EXPR <");
315       dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
316       pp_string (buffer, ", ");
317       dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
318       pp_string (buffer, ">");
319       break;
320       
321     case MIN_EXPR:
322       pp_string (buffer, "MIN_EXPR <");
323       dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
324       pp_string (buffer, ", ");
325       dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
326       pp_string (buffer, ">");
327       break;
328       
329     case MAX_EXPR:
330       pp_string (buffer, "MAX_EXPR <");
331       dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
332       pp_string (buffer, ", ");
333       dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
334       pp_string (buffer, ">");
335       break;
336
337     default:
338       dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
339       pp_space (buffer);
340       pp_string (buffer, op_symbol_code (gimple_assign_rhs_code (gs)));
341       pp_space (buffer);
342       dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
343     }
344 }
345
346
347 /* Dump the gimple assignment GS.  BUFFER, SPC and FLAGS are as in
348    dump_gimple_stmt.  */
349
350 static void
351 dump_gimple_assign (pretty_printer *buffer, gimple gs, int spc, int flags)
352 {
353   if (flags & TDF_RAW)
354     {
355       tree last;
356       if (gimple_num_ops (gs) == 2)
357         last = NULL_TREE;
358       else if (gimple_num_ops (gs) == 3)
359         last = gimple_assign_rhs2 (gs);
360       else
361         gcc_unreachable ();
362
363       dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T, %T, %T>", gs,
364                        tree_code_name[gimple_assign_rhs_code (gs)],
365                        gimple_assign_lhs (gs), gimple_assign_rhs1 (gs), last);
366     }
367   else
368     {
369       if (!(flags & TDF_RHS_ONLY))
370         {
371           dump_generic_node (buffer, gimple_assign_lhs (gs), spc, flags, false);
372           pp_space (buffer);
373           pp_character (buffer, '=');
374
375           if (gimple_assign_nontemporal_move_p (gs))
376             pp_string (buffer, "{nt}");
377
378           if (gimple_has_volatile_ops (gs))
379             pp_string (buffer, "{v}");
380
381           pp_space (buffer);
382         }
383
384       if (gimple_num_ops (gs) == 2)
385         dump_unary_rhs (buffer, gs, spc, flags);
386       else if (gimple_num_ops (gs) == 3)
387         dump_binary_rhs (buffer, gs, spc, flags);
388       else
389         gcc_unreachable ();
390       if (!(flags & TDF_RHS_ONLY))
391         pp_semicolon(buffer);
392     }
393 }
394
395
396 /* Dump the return statement GS.  BUFFER, SPC and FLAGS are as in
397    dump_gimple_stmt.  */
398
399 static void
400 dump_gimple_return (pretty_printer *buffer, gimple gs, int spc, int flags)
401 {
402   tree t;
403
404   t = gimple_return_retval (gs);
405   if (flags & TDF_RAW)
406     dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs, t);
407   else
408     {
409       pp_string (buffer, "return");
410       if (t)
411         {
412           pp_space (buffer);
413           dump_generic_node (buffer, t, spc, flags, false);
414         }
415       pp_semicolon (buffer);
416     }
417 }
418
419
420 /* Dump the call arguments for a gimple call. BUFFER, FLAGS are as in
421    dump_gimple_call.  */
422
423 static void
424 dump_gimple_call_args (pretty_printer *buffer, gimple gs, int flags)
425 {
426   size_t i;
427
428   for (i = 0; i < gimple_call_num_args (gs); i++)
429     {
430       dump_generic_node (buffer, gimple_call_arg (gs, i), 0, flags, false);
431       if (i < gimple_call_num_args (gs) - 1)
432         pp_string (buffer, ", ");
433     }
434
435   if (gimple_call_va_arg_pack_p (gs))
436     {
437       if (gimple_call_num_args (gs) > 0)
438         {
439           pp_character (buffer, ',');
440           pp_space (buffer);
441         }
442
443       pp_string (buffer, "__builtin_va_arg_pack ()");
444     }
445 }
446
447
448 /* Dump the call statement GS.  BUFFER, SPC and FLAGS are as in
449    dump_gimple_stmt.  */
450
451 static void
452 dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags)
453 {
454   tree lhs = gimple_call_lhs (gs);
455
456   if (flags & TDF_RAW)
457     {
458       dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T",
459                      gs, gimple_call_fn (gs), lhs);
460       if (gimple_call_num_args (gs) > 0)
461         {
462           pp_string (buffer, ", ");
463           dump_gimple_call_args (buffer, gs, flags);
464         }
465       pp_string (buffer, ">");
466     }
467   else
468     {
469       if (lhs && !(flags & TDF_RHS_ONLY))
470         {
471           dump_generic_node (buffer, lhs, spc, flags, false);
472           pp_string (buffer, " =");
473
474           if (gimple_has_volatile_ops (gs))
475             pp_string (buffer, "{v}");
476
477           pp_space (buffer);
478         }
479       dump_generic_node (buffer, gimple_call_fn (gs), spc, flags, false);
480       pp_string (buffer, " (");
481       dump_gimple_call_args (buffer, gs, flags);
482       pp_string (buffer, ")");
483       if (!(flags & TDF_RHS_ONLY))
484         pp_semicolon (buffer);
485     }
486
487   if (gimple_call_chain (gs))
488     {
489       pp_string (buffer, " [static-chain: ");
490       dump_generic_node (buffer, gimple_call_chain (gs), spc, flags, false);
491       pp_character (buffer, ']');
492     }
493
494   if (gimple_call_return_slot_opt_p (gs))
495     pp_string (buffer, " [return slot optimization]");
496
497   if (gimple_call_tail_p (gs))
498     pp_string (buffer, " [tail call]");
499 }
500
501
502 /* Dump the switch statement GS.  BUFFER, SPC and FLAGS are as in
503    dump_gimple_stmt.  */
504
505 static void
506 dump_gimple_switch (pretty_printer *buffer, gimple gs, int spc, int flags)
507 {
508   unsigned int i;
509
510   GIMPLE_CHECK (gs, GIMPLE_SWITCH);
511   if (flags & TDF_RAW)
512     dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", gs,
513                    gimple_switch_index (gs));
514   else
515     {
516       pp_string (buffer, "switch (");
517       dump_generic_node (buffer, gimple_switch_index (gs), spc, flags, true);
518       pp_string (buffer, ") <");
519     }
520
521   for (i = 0; i < gimple_switch_num_labels (gs); i++)
522     {
523       tree case_label = gimple_switch_label (gs, i);
524       if (case_label == NULL_TREE)
525         continue;
526
527       dump_generic_node (buffer, case_label, spc, flags, false);
528       pp_string (buffer, " ");
529       dump_generic_node (buffer, CASE_LABEL (case_label), spc, flags, false);
530       if (i < gimple_switch_num_labels (gs) - 1)
531         pp_string (buffer, ", ");
532     }
533   pp_string (buffer, ">");
534 }
535
536
537 /* Dump the gimple conditional GS.  BUFFER, SPC and FLAGS are as in
538    dump_gimple_stmt.  */
539
540 static void
541 dump_gimple_cond (pretty_printer *buffer, gimple gs, int spc, int flags)
542 {
543   if (flags & TDF_RAW)
544     dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T, %T, %T, %T>", gs,
545                    tree_code_name [gimple_cond_code (gs)],
546                    gimple_cond_lhs (gs), gimple_cond_rhs (gs),
547                    gimple_cond_true_label (gs), gimple_cond_false_label (gs));
548   else
549     {
550       if (!(flags & TDF_RHS_ONLY))
551         pp_string (buffer, "if (");
552       dump_generic_node (buffer, gimple_cond_lhs (gs), spc, flags, false);
553       pp_space (buffer);
554       pp_string (buffer, op_symbol_code (gimple_cond_code (gs)));
555       pp_space (buffer);
556       dump_generic_node (buffer, gimple_cond_rhs (gs), spc, flags, false);
557       if (!(flags & TDF_RHS_ONLY))
558         {
559           pp_string (buffer, ")");
560
561           if (gimple_cond_true_label (gs))
562             {
563               pp_string (buffer, " goto ");
564               dump_generic_node (buffer, gimple_cond_true_label (gs),
565                                  spc, flags, false);
566               pp_semicolon (buffer);
567             }
568           if (gimple_cond_false_label (gs))
569             {
570               pp_string (buffer, " else goto ");
571               dump_generic_node (buffer, gimple_cond_false_label (gs),
572                                  spc, flags, false);
573               pp_semicolon (buffer);
574             }
575         }
576     }
577 }
578
579
580 /* Dump a GIMPLE_LABEL tuple on the pretty_printer BUFFER, SPC
581    spaces of indent.  FLAGS specifies details to show in the dump (see
582    TDF_* in tree-pass.h).  */
583
584 static void
585 dump_gimple_label (pretty_printer *buffer, gimple gs, int spc, int flags)
586 {
587   tree label = gimple_label_label (gs);
588   if (flags & TDF_RAW)
589       dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs, label);
590   else
591     {
592       dump_generic_node (buffer, label, spc, flags, false);
593       pp_string (buffer, ":");
594     }
595   if (DECL_NONLOCAL (label))
596     pp_string (buffer, " [non-local]");
597 }
598
599 /* Dump a GIMPLE_GOTO tuple on the pretty_printer BUFFER, SPC
600    spaces of indent.  FLAGS specifies details to show in the dump (see
601    TDF_* in tree-pass.h).  */
602
603 static void
604 dump_gimple_goto (pretty_printer *buffer, gimple gs, int spc, int flags)
605 {
606   tree label = gimple_goto_dest (gs);
607   if (flags & TDF_RAW)
608     dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs, label);
609   else
610     dump_gimple_fmt (buffer, spc, flags, "goto %T;", label);
611 }
612
613
614 /* Dump a GIMPLE_BIND tuple on the pretty_printer BUFFER, SPC
615    spaces of indent.  FLAGS specifies details to show in the dump (see
616    TDF_* in tree-pass.h).  */
617
618 static void
619 dump_gimple_bind (pretty_printer *buffer, gimple gs, int spc, int flags)
620 {
621   if (flags & TDF_RAW)
622     dump_gimple_fmt (buffer, spc, flags, "%G <", gs);
623   else
624     pp_character (buffer, '{');
625   if (!(flags & TDF_SLIM))
626     {
627       tree var;
628
629       for (var = gimple_bind_vars (gs); var; var = TREE_CHAIN (var))
630         {
631           newline_and_indent (buffer, 2);
632           print_declaration (buffer, var, spc, flags);
633         }
634       if (gimple_bind_vars (gs))
635         pp_newline (buffer);
636     }
637   pp_newline (buffer);
638   dump_gimple_seq (buffer, gimple_bind_body (gs), spc + 2, flags);
639   newline_and_indent (buffer, spc);
640   if (flags & TDF_RAW)
641     pp_character (buffer, '>');
642   else
643     pp_character (buffer, '}');
644 }
645
646
647 /* Dump a GIMPLE_TRY tuple on the pretty_printer BUFFER, SPC spaces of
648    indent.  FLAGS specifies details to show in the dump (see TDF_* in
649    tree-pass.h).  */
650
651 static void
652 dump_gimple_try (pretty_printer *buffer, gimple gs, int spc, int flags)
653 {
654   if (flags & TDF_RAW)
655     {
656       const char *type;
657       if (gimple_try_kind (gs) == GIMPLE_TRY_CATCH)
658         type = "GIMPLE_TRY_CATCH";
659       else if (gimple_try_kind (gs) == GIMPLE_TRY_FINALLY)
660         type = "GIMPLE_TRY_FINALLY";
661       else
662         type = "UNKNOWN GIMPLE_TRY";
663       dump_gimple_fmt (buffer, spc, flags,
664                        "%G <%s,%+EVAL <%S>%nCLEANUP <%S>%->", gs, type,
665                        gimple_try_eval (gs), gimple_try_cleanup (gs));
666     }
667   else
668     {
669       pp_string (buffer, "try");
670       newline_and_indent (buffer, spc + 2);
671       pp_string (buffer, "{");
672       pp_newline (buffer);
673
674       dump_gimple_seq (buffer, gimple_try_eval (gs), spc + 4, flags);
675       newline_and_indent (buffer, spc + 2);
676       pp_string (buffer, "}");
677
678       if (gimple_try_kind (gs) == GIMPLE_TRY_CATCH)
679         {
680           newline_and_indent (buffer, spc);
681           pp_string (buffer, "catch");
682           newline_and_indent (buffer, spc + 2);
683           pp_string (buffer, "{");
684         }
685       else if (gimple_try_kind (gs) == GIMPLE_TRY_FINALLY)
686         {
687           newline_and_indent (buffer, spc);
688           pp_string (buffer, "finally");
689           newline_and_indent (buffer, spc + 2);
690           pp_string (buffer, "{");
691         }
692       else
693         pp_string (buffer, " <UNKNOWN GIMPLE_TRY> {");
694
695       pp_newline (buffer);
696       dump_gimple_seq (buffer, gimple_try_cleanup (gs), spc + 4, flags);
697       newline_and_indent (buffer, spc + 2);
698       pp_character (buffer, '}');
699     }
700 }
701
702
703 /* Dump a GIMPLE_CATCH tuple on the pretty_printer BUFFER, SPC spaces of
704    indent.  FLAGS specifies details to show in the dump (see TDF_* in
705    tree-pass.h).  */
706
707 static void
708 dump_gimple_catch (pretty_printer *buffer, gimple gs, int spc, int flags)
709 {
710   if (flags & TDF_RAW)
711       dump_gimple_fmt (buffer, spc, flags, "%G <%T, %+CATCH <%S>%->", gs,
712                        gimple_catch_types (gs), gimple_catch_handler (gs));
713   else
714       dump_gimple_fmt (buffer, spc, flags, "catch (%T)%+{%S}",
715                        gimple_catch_types (gs), gimple_catch_handler (gs));
716 }
717
718
719 /* Dump a GIMPLE_EH_FILTER tuple on the pretty_printer BUFFER, SPC spaces of
720    indent.  FLAGS specifies details to show in the dump (see TDF_* in
721    tree-pass.h).  */
722
723 static void
724 dump_gimple_eh_filter (pretty_printer *buffer, gimple gs, int spc, int flags)
725 {
726   if (flags & TDF_RAW)
727     dump_gimple_fmt (buffer, spc, flags, "%G <%T, %+FAILURE <%S>%->", gs,
728                      gimple_eh_filter_types (gs),
729                      gimple_eh_filter_failure (gs));
730   else
731     dump_gimple_fmt (buffer, spc, flags, "<<<eh_filter (%T)>>>%+{%+%S%-}",
732                      gimple_eh_filter_types (gs),
733                      gimple_eh_filter_failure (gs));
734 }
735
736
737 /* Dump a GIMPLE_RESX tuple on the pretty_printer BUFFER, SPC spaces of
738    indent.  FLAGS specifies details to show in the dump (see TDF_* in
739    tree-pass.h).  */
740
741 static void
742 dump_gimple_resx (pretty_printer *buffer, gimple gs, int spc, int flags)
743 {
744   if (flags & TDF_RAW)
745     dump_gimple_fmt (buffer, spc, flags, "%G <%d>", gs,
746                      gimple_resx_region (gs));
747   else
748     dump_gimple_fmt (buffer, spc, flags, "resx %d", gimple_resx_region (gs));
749 }
750
751 /* Dump a GIMPLE_OMP_FOR tuple on the pretty_printer BUFFER.  */
752 static void
753 dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
754 {
755   size_t i;
756
757   if (flags & TDF_RAW)
758     {
759       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
760                        gimple_omp_body (gs));
761       dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
762       dump_gimple_fmt (buffer, spc, flags, " >,");
763       for (i = 0; i < gimple_omp_for_collapse (gs); i++)
764         dump_gimple_fmt (buffer, spc, flags,
765                          "%+%T, %T, %T, %s, %T,%n",
766                          gimple_omp_for_index (gs, i),
767                          gimple_omp_for_initial (gs, i),
768                          gimple_omp_for_final (gs, i),
769                          tree_code_name[gimple_omp_for_cond (gs, i)],
770                          gimple_omp_for_incr (gs, i));
771       dump_gimple_fmt (buffer, spc, flags, "PRE_BODY <%S>%->",
772                        gimple_omp_for_pre_body (gs));
773     }
774   else
775     {
776       pp_string (buffer, "#pragma omp for");
777       dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
778       for (i = 0; i < gimple_omp_for_collapse (gs); i++)
779         {
780           if (i)
781             spc += 2;
782           newline_and_indent (buffer, spc);
783           pp_string (buffer, "for (");
784           dump_generic_node (buffer, gimple_omp_for_index (gs, i), spc,
785                              flags, false);
786           pp_string (buffer, " = ");
787           dump_generic_node (buffer, gimple_omp_for_initial (gs, i), spc,
788                              flags, false);
789           pp_string (buffer, "; ");
790
791           dump_generic_node (buffer, gimple_omp_for_index (gs, i), spc,
792                              flags, false);
793           pp_space (buffer);
794           switch (gimple_omp_for_cond (gs, i))
795             {
796             case LT_EXPR:
797               pp_character (buffer, '<');
798               break;
799             case GT_EXPR:
800               pp_character (buffer, '>');
801               break;
802             case LE_EXPR:
803               pp_string (buffer, "<=");
804               break;
805             case GE_EXPR:
806               pp_string (buffer, ">=");
807               break;
808             default:
809               gcc_unreachable ();
810             }
811           pp_space (buffer);
812           dump_generic_node (buffer, gimple_omp_for_final (gs, i), spc,
813                              flags, false);
814           pp_string (buffer, "; ");
815
816           dump_generic_node (buffer, gimple_omp_for_index (gs, i), spc,
817                              flags, false);
818           pp_string (buffer, " = ");
819           dump_generic_node (buffer, gimple_omp_for_incr (gs, i), spc,
820                              flags, false);
821           pp_character (buffer, ')');
822         }
823
824       if (!gimple_seq_empty_p (gimple_omp_body (gs)))
825         {
826           newline_and_indent (buffer, spc + 2);
827           pp_character (buffer, '{');
828           pp_newline (buffer);
829           dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
830           newline_and_indent (buffer, spc + 2);
831           pp_character (buffer, '}');
832         }
833     }
834 }
835
836 /* Dump a GIMPLE_OMP_CONTINUE tuple on the pretty_printer BUFFER.  */
837
838 static void
839 dump_gimple_omp_continue (pretty_printer *buffer, gimple gs, int spc, int flags)
840 {
841   if (flags & TDF_RAW)
842     {
843       dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T>", gs,
844                        gimple_omp_continue_control_def (gs),
845                        gimple_omp_continue_control_use (gs));
846     }
847   else
848     {
849       pp_string (buffer, "#pragma omp continue (");
850       dump_generic_node (buffer, gimple_omp_continue_control_def (gs),
851                          spc, flags, false);
852       pp_character (buffer, ',');
853       pp_space (buffer);
854       dump_generic_node (buffer, gimple_omp_continue_control_use (gs),
855                          spc, flags, false);
856       pp_character (buffer, ')');
857     }
858 }
859
860 /* Dump a GIMPLE_OMP_SINGLE tuple on the pretty_printer BUFFER.  */
861
862 static void
863 dump_gimple_omp_single (pretty_printer *buffer, gimple gs, int spc, int flags)
864 {
865   if (flags & TDF_RAW)
866     {
867       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
868                        gimple_omp_body (gs));
869       dump_omp_clauses (buffer, gimple_omp_single_clauses (gs), spc, flags);
870       dump_gimple_fmt (buffer, spc, flags, " >");
871     }
872   else
873     {
874       pp_string (buffer, "#pragma omp single");
875       dump_omp_clauses (buffer, gimple_omp_single_clauses (gs), spc, flags);
876       if (!gimple_seq_empty_p (gimple_omp_body (gs)))
877         {
878           newline_and_indent (buffer, spc + 2);
879           pp_character (buffer, '{');
880           pp_newline (buffer);
881           dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
882           newline_and_indent (buffer, spc + 2);
883           pp_character (buffer, '}');
884         }
885     }
886 }
887
888 /* Dump a GIMPLE_OMP_SECTIONS tuple on the pretty_printer BUFFER.  */
889
890 static void
891 dump_gimple_omp_sections (pretty_printer *buffer, gimple gs, int spc,
892                           int flags)
893 {
894   if (flags & TDF_RAW)
895     {
896       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
897                        gimple_omp_body (gs));
898       dump_omp_clauses (buffer, gimple_omp_sections_clauses (gs), spc, flags);
899       dump_gimple_fmt (buffer, spc, flags, " >");
900     }
901   else
902     {
903       pp_string (buffer, "#pragma omp sections");
904       if (gimple_omp_sections_control (gs))
905         {
906           pp_string (buffer, " <");
907           dump_generic_node (buffer, gimple_omp_sections_control (gs), spc,
908                              flags, false);
909           pp_character (buffer, '>');
910         }
911       dump_omp_clauses (buffer, gimple_omp_sections_clauses (gs), spc, flags);
912       if (!gimple_seq_empty_p (gimple_omp_body (gs)))
913         {
914           newline_and_indent (buffer, spc + 2);
915           pp_character (buffer, '{');
916           pp_newline (buffer);
917           dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
918           newline_and_indent (buffer, spc + 2);
919           pp_character (buffer, '}');
920         }
921     }
922 }
923
924 /* Dump a GIMPLE_OMP_{MASTER,ORDERED,SECTION} tuple on the pretty_printer
925    BUFFER.  */
926
927 static void
928 dump_gimple_omp_block (pretty_printer *buffer, gimple gs, int spc, int flags)
929 {
930   if (flags & TDF_RAW)
931     dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S> >", gs,
932                      gimple_omp_body (gs));
933   else
934     {
935       switch (gimple_code (gs))
936         {
937         case GIMPLE_OMP_MASTER:
938           pp_string (buffer, "#pragma omp master");
939           break;
940         case GIMPLE_OMP_ORDERED:
941           pp_string (buffer, "#pragma omp ordered");
942           break;
943         case GIMPLE_OMP_SECTION:
944           pp_string (buffer, "#pragma omp section");
945           break;
946         default:
947           gcc_unreachable ();
948         }
949       if (!gimple_seq_empty_p (gimple_omp_body (gs)))
950         {
951           newline_and_indent (buffer, spc + 2);
952           pp_character (buffer, '{');
953           pp_newline (buffer);
954           dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
955           newline_and_indent (buffer, spc + 2);
956           pp_character (buffer, '}');
957         }
958     }
959 }
960
961 /* Dump a GIMPLE_OMP_CRITICAL tuple on the pretty_printer BUFFER.  */
962
963 static void
964 dump_gimple_omp_critical (pretty_printer *buffer, gimple gs, int spc,
965                           int flags)
966 {
967   if (flags & TDF_RAW)
968     dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S> >", gs,
969                      gimple_omp_body (gs));
970   else
971     {
972       pp_string (buffer, "#pragma omp critical");
973       if (gimple_omp_critical_name (gs))
974         {
975           pp_string (buffer, " (");
976           dump_generic_node (buffer, gimple_omp_critical_name (gs), spc,
977                              flags, false);
978           pp_character (buffer, ')');
979         }
980       if (!gimple_seq_empty_p (gimple_omp_body (gs)))
981         {
982           newline_and_indent (buffer, spc + 2);
983           pp_character (buffer, '{');
984           pp_newline (buffer);
985           dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
986           newline_and_indent (buffer, spc + 2);
987           pp_character (buffer, '}');
988         }
989     }
990 }
991
992 /* Dump a GIMPLE_OMP_RETURN tuple on the pretty_printer BUFFER.  */
993
994 static void
995 dump_gimple_omp_return (pretty_printer *buffer, gimple gs, int spc, int flags)
996 {
997   if (flags & TDF_RAW)
998     {
999       dump_gimple_fmt (buffer, spc, flags, "%G <nowait=%d>", gs,
1000                        (int) gimple_omp_return_nowait_p (gs));
1001     }
1002   else
1003     {
1004       pp_string (buffer, "#pragma omp return");
1005       if (gimple_omp_return_nowait_p (gs))
1006         pp_string (buffer, "(nowait)");
1007     }
1008 }
1009
1010 /* Dump a GIMPLE_ASM tuple on the pretty_printer BUFFER, SPC spaces of
1011    indent.  FLAGS specifies details to show in the dump (see TDF_* in
1012    tree-pass.h).  */
1013
1014 static void
1015 dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags)
1016 {
1017   unsigned int i;
1018
1019   if (flags & TDF_RAW)
1020     dump_gimple_fmt (buffer, spc, flags, "%G <%+STRING <%n%s%n>", gs,
1021                      gimple_asm_string (gs));
1022   else
1023     {
1024       pp_string (buffer, "__asm__");
1025       if (gimple_asm_volatile_p (gs))
1026         pp_string (buffer, " __volatile__");
1027       pp_string (buffer, "(\"");
1028       pp_string (buffer, gimple_asm_string (gs));
1029       pp_string (buffer, "\"");
1030     }
1031
1032   if (gimple_asm_ninputs (gs)
1033      || gimple_asm_noutputs (gs) 
1034      || gimple_asm_nclobbers (gs))
1035     {
1036       if (gimple_asm_noutputs (gs))
1037         {
1038           if (flags & TDF_RAW)
1039             {
1040               newline_and_indent (buffer, spc + 2);
1041               pp_string (buffer, "OUTPUT: ");
1042             }
1043           else
1044             pp_string (buffer, " : ");
1045         }
1046
1047       for (i = 0; i < gimple_asm_noutputs (gs); i++)
1048         {
1049           dump_generic_node (buffer, gimple_asm_output_op (gs, i), spc, flags,
1050                              false);
1051           if ( i < gimple_asm_noutputs (gs) -1)
1052             pp_string (buffer, ", ");
1053         }
1054
1055       if (gimple_asm_ninputs (gs))
1056         {
1057           if (flags & TDF_RAW)
1058             {
1059               newline_and_indent (buffer, spc + 2);
1060               pp_string (buffer, "INPUT: ");
1061             }
1062           else
1063             pp_string (buffer, " : ");
1064         }
1065
1066       for (i = 0; i < gimple_asm_ninputs (gs); i++)
1067         {
1068           dump_generic_node (buffer, gimple_asm_input_op (gs, i), spc, flags,
1069                              false);
1070           if (i < gimple_asm_ninputs (gs) -1)
1071             pp_string (buffer, " : ");
1072         }
1073
1074       if (gimple_asm_nclobbers (gs))
1075         {
1076           if (flags & TDF_RAW)
1077             {
1078               newline_and_indent (buffer, spc + 2);
1079               pp_string (buffer, "CLOBBER: ");
1080             }
1081           else
1082             pp_string (buffer, " : ");
1083         }
1084
1085       for (i = 0; i < gimple_asm_nclobbers (gs); i++)
1086         {
1087           dump_generic_node (buffer, gimple_asm_clobber_op (gs, i), spc, flags,
1088                              false);
1089           if ( i < gimple_asm_nclobbers (gs) -1)
1090             pp_string (buffer, ", ");
1091         }
1092     }
1093   if (flags & TDF_RAW)
1094     {
1095       newline_and_indent (buffer, spc);
1096       pp_character (buffer, '>');
1097     }
1098   else
1099     pp_string (buffer, ");");
1100 }
1101
1102
1103 /* Dump the set of decls SYMS.  BUFFER, SPC and FLAGS are as in
1104    dump_generic_node.  */
1105
1106 static void
1107 dump_symbols (pretty_printer *buffer, bitmap syms, int flags)
1108 {
1109   unsigned i;
1110   bitmap_iterator bi;
1111
1112   if (syms == NULL)
1113     pp_string (buffer, "NIL");
1114   else
1115     {
1116       pp_string (buffer, " { ");
1117
1118       EXECUTE_IF_SET_IN_BITMAP (syms, 0, i, bi)
1119         {
1120           tree sym = referenced_var_lookup (i);
1121           dump_generic_node (buffer, sym, 0, flags, false);
1122           pp_string (buffer, " ");
1123         }
1124
1125       pp_string (buffer, "}");
1126     }
1127 }
1128
1129
1130 /* Dump a PHI node PHI.  BUFFER, SPC and FLAGS are as in
1131    dump_gimple_stmt.  */
1132
1133 static void
1134 dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
1135 {
1136   size_t i;
1137
1138   if (flags & TDF_RAW)
1139       dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", phi,
1140                        gimple_phi_result (phi));
1141   else
1142     {
1143       dump_generic_node (buffer, gimple_phi_result (phi), spc, flags, false);
1144       pp_string (buffer, " = PHI <");
1145     }
1146   for (i = 0; i < gimple_phi_num_args (phi); i++)
1147     {
1148       dump_generic_node (buffer, gimple_phi_arg_def (phi, i), spc, flags,
1149                          false);
1150       pp_string (buffer, "(");
1151       pp_decimal_int (buffer, gimple_phi_arg_edge (phi, i)->src->index);
1152       pp_string (buffer, ")");
1153       if (i < gimple_phi_num_args (phi) - 1)
1154         pp_string (buffer, ", ");
1155     }
1156   pp_string (buffer, ">");
1157 }
1158
1159
1160 /* Dump a GIMPLE_OMP_PARALLEL tuple on the pretty_printer BUFFER, SPC spaces
1161    of indent.  FLAGS specifies details to show in the dump (see TDF_* in
1162    tree-pass.h).  */
1163
1164 static void
1165 dump_gimple_omp_parallel (pretty_printer *buffer, gimple gs, int spc,
1166                           int flags)
1167 {
1168   if (flags & TDF_RAW)
1169     {
1170       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
1171                        gimple_omp_body (gs));
1172       dump_omp_clauses (buffer, gimple_omp_parallel_clauses (gs), spc, flags);
1173       dump_gimple_fmt (buffer, spc, flags, " >, %T, %T%n>",
1174                        gimple_omp_parallel_child_fn (gs),
1175                        gimple_omp_parallel_data_arg (gs));
1176     }
1177   else
1178     {
1179       gimple_seq body;
1180       pp_string (buffer, "#pragma omp parallel");
1181       dump_omp_clauses (buffer, gimple_omp_parallel_clauses (gs), spc, flags);
1182       if (gimple_omp_parallel_child_fn (gs))
1183         {
1184           pp_string (buffer, " [child fn: ");
1185           dump_generic_node (buffer, gimple_omp_parallel_child_fn (gs),
1186                              spc, flags, false);
1187           pp_string (buffer, " (");
1188           if (gimple_omp_parallel_data_arg (gs))
1189             dump_generic_node (buffer, gimple_omp_parallel_data_arg (gs),
1190                                spc, flags, false);
1191           else
1192             pp_string (buffer, "???");
1193           pp_string (buffer, ")]");
1194         }
1195       body = gimple_omp_body (gs);
1196       if (body && gimple_code (gimple_seq_first_stmt (body)) != GIMPLE_BIND)
1197         {
1198           newline_and_indent (buffer, spc + 2);
1199           pp_character (buffer, '{');
1200           pp_newline (buffer);
1201           dump_gimple_seq (buffer, body, spc + 4, flags);
1202           newline_and_indent (buffer, spc + 2);
1203           pp_character (buffer, '}');
1204         }
1205       else if (body)
1206         {
1207           pp_newline (buffer);
1208           dump_gimple_seq (buffer, body, spc + 2, flags);
1209         }
1210     }
1211 }
1212
1213
1214 /* Dump a GIMPLE_OMP_TASK tuple on the pretty_printer BUFFER, SPC spaces
1215    of indent.  FLAGS specifies details to show in the dump (see TDF_* in
1216    tree-pass.h).  */
1217
1218 static void
1219 dump_gimple_omp_task (pretty_printer *buffer, gimple gs, int spc,
1220                       int flags)
1221 {
1222   if (flags & TDF_RAW)
1223     {
1224       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
1225                        gimple_omp_body (gs));
1226       dump_omp_clauses (buffer, gimple_omp_task_clauses (gs), spc, flags);
1227       dump_gimple_fmt (buffer, spc, flags, " >, %T, %T, %T, %T, %T%n>",
1228                        gimple_omp_task_child_fn (gs),
1229                        gimple_omp_task_data_arg (gs),
1230                        gimple_omp_task_copy_fn (gs),
1231                        gimple_omp_task_arg_size (gs),
1232                        gimple_omp_task_arg_size (gs));
1233     }
1234   else
1235     {
1236       gimple_seq body;
1237       pp_string (buffer, "#pragma omp task");
1238       dump_omp_clauses (buffer, gimple_omp_task_clauses (gs), spc, flags);
1239       if (gimple_omp_task_child_fn (gs))
1240         {
1241           pp_string (buffer, " [child fn: ");
1242           dump_generic_node (buffer, gimple_omp_task_child_fn (gs),
1243                              spc, flags, false);
1244           pp_string (buffer, " (");
1245           if (gimple_omp_task_data_arg (gs))
1246             dump_generic_node (buffer, gimple_omp_task_data_arg (gs),
1247                                spc, flags, false);
1248           else
1249             pp_string (buffer, "???");
1250           pp_string (buffer, ")]");
1251         }
1252       body = gimple_omp_body (gs);
1253       if (body && gimple_code (gimple_seq_first_stmt (body)) != GIMPLE_BIND)
1254         {
1255           newline_and_indent (buffer, spc + 2);
1256           pp_character (buffer, '{');
1257           pp_newline (buffer);
1258           dump_gimple_seq (buffer, body, spc + 4, flags);
1259           newline_and_indent (buffer, spc + 2);
1260           pp_character (buffer, '}');
1261         }
1262       else if (body)
1263         {
1264           pp_newline (buffer);
1265           dump_gimple_seq (buffer, body, spc + 2, flags);
1266         }
1267     }
1268 }
1269
1270
1271 /* Dump a GIMPLE_OMP_ATOMIC_LOAD tuple on the pretty_printer BUFFER, SPC
1272    spaces of indent.  FLAGS specifies details to show in the dump (see TDF_*
1273    in tree-pass.h).  */
1274
1275 static void
1276 dump_gimple_omp_atomic_load (pretty_printer *buffer, gimple gs, int spc,
1277                              int flags)
1278 {
1279   if (flags & TDF_RAW)
1280     {
1281       dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T>", gs,
1282                        gimple_omp_atomic_load_lhs (gs),
1283                        gimple_omp_atomic_load_rhs (gs));
1284     }
1285   else
1286     {
1287       pp_string (buffer, "#pragma omp atomic_load");
1288       newline_and_indent (buffer, spc + 2);
1289       dump_generic_node (buffer, gimple_omp_atomic_load_lhs (gs),
1290                          spc, flags, false);
1291       pp_space (buffer);
1292       pp_character (buffer, '=');
1293       pp_space (buffer);
1294       pp_character (buffer, '*');
1295       dump_generic_node (buffer, gimple_omp_atomic_load_rhs (gs),
1296                          spc, flags, false);
1297     }
1298 }
1299
1300 /* Dump a GIMPLE_OMP_ATOMIC_STORE tuple on the pretty_printer BUFFER, SPC
1301    spaces of indent.  FLAGS specifies details to show in the dump (see TDF_*
1302    in tree-pass.h).  */
1303
1304 static void
1305 dump_gimple_omp_atomic_store (pretty_printer *buffer, gimple gs, int spc,
1306                              int flags)
1307 {
1308   if (flags & TDF_RAW)
1309     {
1310       dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs,
1311                        gimple_omp_atomic_store_val (gs));
1312     }
1313   else
1314     {
1315       pp_string (buffer, "#pragma omp atomic_store (");
1316       dump_generic_node (buffer, gimple_omp_atomic_store_val (gs),
1317                          spc, flags, false);
1318       pp_character (buffer, ')');
1319     }
1320 }
1321
1322 /* Dump a GIMPLE_CHANGE_DYNAMIC_TYPE statement GS.  BUFFER, SPC and
1323    FLAGS are as in dump_gimple_stmt.  */
1324
1325 static void
1326 dump_gimple_cdt (pretty_printer *buffer, gimple gs, int spc, int flags)
1327 {
1328   if (flags & TDF_RAW)
1329     dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T>", gs,
1330                      gimple_cdt_new_type (gs), gimple_cdt_location (gs));
1331   else
1332     {
1333       pp_string (buffer, "<<<change_dynamic_type (");
1334       dump_generic_node (buffer, gimple_cdt_new_type (gs), spc + 2, flags,
1335                          false);
1336       pp_string (buffer, ") ");
1337       dump_generic_node (buffer, gimple_cdt_location (gs), spc + 2, flags,
1338                          false);
1339       pp_string (buffer, ")>>>");
1340     }
1341 }
1342
1343
1344 /* Dump all the memory operands for statement GS.  BUFFER, SPC and
1345    FLAGS are as in dump_gimple_stmt.  */
1346
1347 static void
1348 dump_gimple_mem_ops (pretty_printer *buffer, gimple gs, int spc, int flags)
1349 {
1350   struct voptype_d *vdefs;
1351   struct voptype_d *vuses;
1352   int i, n;
1353
1354   if (!ssa_operands_active () || !gimple_references_memory_p (gs))
1355     return;
1356
1357   /* Even if the statement doesn't have virtual operators yet, it may
1358      contain symbol information (this happens before aliases have been
1359      computed).  */
1360   if ((flags & TDF_MEMSYMS)
1361       && gimple_vuse_ops (gs) == NULL
1362       && gimple_vdef_ops (gs) == NULL)
1363     {
1364       if (gimple_loaded_syms (gs))
1365         {
1366           pp_string (buffer, "# LOADS: ");
1367           dump_symbols (buffer, gimple_loaded_syms (gs), flags);
1368           newline_and_indent (buffer, spc);
1369         }
1370
1371       if (gimple_stored_syms (gs))
1372         {
1373           pp_string (buffer, "# STORES: ");
1374           dump_symbols (buffer, gimple_stored_syms (gs), flags);
1375           newline_and_indent (buffer, spc);
1376         }
1377
1378       return;
1379     }
1380
1381   vuses = gimple_vuse_ops (gs);
1382   while (vuses)
1383     {
1384       pp_string (buffer, "# VUSE <");
1385
1386       n = VUSE_NUM (vuses);
1387       for (i = 0; i < n; i++)
1388         {
1389           dump_generic_node (buffer, VUSE_OP (vuses, i), spc + 2, flags, false);
1390           if (i < n - 1)
1391             pp_string (buffer, ", ");
1392         }
1393
1394       pp_string (buffer, ">");
1395
1396       if (flags & TDF_MEMSYMS)
1397         dump_symbols (buffer, gimple_loaded_syms (gs), flags);
1398
1399       newline_and_indent (buffer, spc);
1400       vuses = vuses->next;
1401     }
1402
1403   vdefs = gimple_vdef_ops (gs);
1404   while (vdefs)
1405     {
1406       pp_string (buffer, "# ");
1407       dump_generic_node (buffer, VDEF_RESULT (vdefs), spc + 2, flags, false);
1408       pp_string (buffer, " = VDEF <");
1409
1410       n = VDEF_NUM (vdefs);
1411       for (i = 0; i < n; i++)
1412         {
1413           dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, 0);
1414           if (i < n - 1)
1415             pp_string (buffer, ", ");
1416         }
1417
1418       pp_string (buffer, ">");
1419
1420       if ((flags & TDF_MEMSYMS) && vdefs->next == NULL)
1421         dump_symbols (buffer, gimple_stored_syms (gs), flags);
1422
1423       newline_and_indent (buffer, spc);
1424       vdefs = vdefs->next;
1425     }
1426 }
1427
1428
1429 /* Dump the gimple statement GS on the pretty printer BUFFER, SPC
1430    spaces of indent.  FLAGS specifies details to show in the dump (see
1431    TDF_* in tree-pass.h).  */
1432
1433 void
1434 dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
1435 {
1436   if (!gs)
1437     return;
1438
1439   if (flags & TDF_STMTADDR)
1440     pp_printf (buffer, "<&%p> ", (void *) gs);
1441
1442   if ((flags & TDF_LINENO) && gimple_has_location (gs))
1443     {
1444       expanded_location xloc = expand_location (gimple_location (gs));
1445       pp_character (buffer, '[');
1446       if (xloc.file)
1447         {
1448           pp_string (buffer, xloc.file);
1449           pp_string (buffer, " : ");
1450         }
1451       pp_decimal_int (buffer, xloc.line);
1452       pp_string (buffer, "] ");
1453     }
1454
1455   if ((flags & (TDF_VOPS|TDF_MEMSYMS))
1456       && gimple_has_mem_ops (gs))
1457     dump_gimple_mem_ops (buffer, gs, spc, flags);
1458
1459   switch (gimple_code (gs))
1460     {
1461     case GIMPLE_ASM:
1462       dump_gimple_asm (buffer, gs, spc, flags);
1463       break;
1464
1465     case GIMPLE_ASSIGN:
1466       dump_gimple_assign (buffer, gs, spc, flags);
1467       break;
1468
1469     case GIMPLE_BIND:
1470       dump_gimple_bind (buffer, gs, spc, flags);
1471       break;
1472
1473     case GIMPLE_CALL:
1474       dump_gimple_call (buffer, gs, spc, flags);
1475       break;
1476
1477     case GIMPLE_COND:
1478       dump_gimple_cond (buffer, gs, spc, flags);
1479       break;
1480
1481     case GIMPLE_LABEL:
1482       dump_gimple_label (buffer, gs, spc, flags);
1483       break;
1484
1485     case GIMPLE_GOTO:
1486       dump_gimple_goto (buffer, gs, spc, flags);
1487       break;
1488
1489     case GIMPLE_NOP:
1490       pp_string (buffer, "GIMPLE_NOP");
1491       break;
1492
1493     case GIMPLE_RETURN:
1494       dump_gimple_return (buffer, gs, spc, flags);
1495       break;
1496
1497     case GIMPLE_SWITCH:
1498       dump_gimple_switch (buffer, gs, spc, flags);
1499       break;
1500
1501     case GIMPLE_TRY:
1502       dump_gimple_try (buffer, gs, spc, flags);
1503       break;
1504
1505     case GIMPLE_PHI:
1506       dump_gimple_phi (buffer, gs, spc, flags);
1507       break;
1508
1509     case GIMPLE_OMP_PARALLEL:
1510       dump_gimple_omp_parallel (buffer, gs, spc, flags);
1511       break;
1512
1513     case GIMPLE_OMP_TASK:
1514       dump_gimple_omp_task (buffer, gs, spc, flags);
1515       break;
1516
1517     case GIMPLE_OMP_ATOMIC_LOAD:
1518       dump_gimple_omp_atomic_load (buffer, gs, spc, flags);
1519
1520       break;
1521
1522     case GIMPLE_OMP_ATOMIC_STORE:
1523       dump_gimple_omp_atomic_store (buffer, gs, spc, flags);
1524       break;
1525
1526     case GIMPLE_OMP_FOR:
1527       dump_gimple_omp_for (buffer, gs, spc, flags);
1528       break;
1529
1530     case GIMPLE_OMP_CONTINUE:
1531       dump_gimple_omp_continue (buffer, gs, spc, flags);
1532       break;
1533
1534     case GIMPLE_OMP_SINGLE:
1535       dump_gimple_omp_single (buffer, gs, spc, flags);
1536       break;
1537
1538     case GIMPLE_OMP_RETURN:
1539       dump_gimple_omp_return (buffer, gs, spc, flags);
1540       break;
1541
1542     case GIMPLE_OMP_SECTIONS:
1543       dump_gimple_omp_sections (buffer, gs, spc, flags);
1544       break;
1545
1546     case GIMPLE_OMP_SECTIONS_SWITCH:
1547       pp_string (buffer, "GIMPLE_SECTIONS_SWITCH");
1548       break;
1549
1550     case GIMPLE_OMP_MASTER:
1551     case GIMPLE_OMP_ORDERED:
1552     case GIMPLE_OMP_SECTION:
1553       dump_gimple_omp_block (buffer, gs, spc, flags);
1554       break;
1555
1556     case GIMPLE_OMP_CRITICAL:
1557       dump_gimple_omp_critical (buffer, gs, spc, flags);
1558       break;
1559
1560     case GIMPLE_CHANGE_DYNAMIC_TYPE:
1561       dump_gimple_cdt (buffer, gs, spc, flags);
1562       break;
1563
1564     case GIMPLE_CATCH:
1565       dump_gimple_catch (buffer, gs, spc, flags);
1566       break;
1567
1568     case GIMPLE_EH_FILTER:
1569       dump_gimple_eh_filter (buffer, gs, spc, flags);
1570       break;
1571
1572     case GIMPLE_RESX:
1573       dump_gimple_resx (buffer, gs, spc, flags);
1574       break;
1575
1576     case GIMPLE_PREDICT:
1577       pp_string (buffer, "// predicted ");
1578       if (gimple_predict_outcome (gs))
1579         pp_string (buffer, "likely by ");
1580       else
1581         pp_string (buffer, "unlikely by ");
1582       pp_string (buffer, predictor_name (gimple_predict_predictor (gs)));
1583       pp_string (buffer, " predictor.");
1584       break;
1585
1586     default:
1587       GIMPLE_NIY;
1588     }
1589
1590   /* If we're building a diagnostic, the formatted text will be
1591      written into BUFFER's stream by the caller; otherwise, write it
1592      now.  */
1593   if (!(flags & TDF_DIAGNOSTIC))
1594     pp_write_text_to_stream (buffer);
1595 }
1596
1597
1598 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
1599    spaces and details described by flags.  */
1600
1601 static void
1602 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
1603 {
1604   edge e;
1605   gimple stmt;
1606   edge_iterator ei;
1607
1608   if (flags & TDF_BLOCKS)
1609     {
1610       INDENT (indent);
1611       pp_string (buffer, "# BLOCK ");
1612       pp_decimal_int (buffer, bb->index);
1613       if (bb->frequency)
1614         {
1615           pp_string (buffer, " freq:");
1616           pp_decimal_int (buffer, bb->frequency);
1617         }
1618       if (bb->count)
1619         {
1620           pp_string (buffer, " count:");
1621           pp_widest_integer (buffer, bb->count);
1622         }
1623
1624       if (flags & TDF_LINENO)
1625         {
1626           gimple_stmt_iterator gsi;
1627
1628           for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1629             if (get_lineno (gsi_stmt (gsi)) != -1)
1630               {
1631                 pp_string (buffer, ", starting at line ");
1632                 pp_decimal_int (buffer, get_lineno (gsi_stmt (gsi)));
1633                 break;
1634               }
1635         }
1636       newline_and_indent (buffer, indent);
1637
1638       pp_string (buffer, "# PRED:");
1639       pp_write_text_to_stream (buffer);
1640       FOR_EACH_EDGE (e, ei, bb->preds)
1641         if (flags & TDF_SLIM)
1642           {
1643             pp_string (buffer, " ");
1644             if (e->src == ENTRY_BLOCK_PTR)
1645               pp_string (buffer, "ENTRY");
1646             else
1647               pp_decimal_int (buffer, e->src->index);
1648           }
1649         else
1650           dump_edge_info (buffer->buffer->stream, e, 0);
1651       pp_newline (buffer);
1652     }
1653   else
1654     {
1655       stmt = first_stmt (bb);
1656       if (!stmt || gimple_code (stmt) != GIMPLE_LABEL)
1657         {
1658           INDENT (indent - 2);
1659           pp_string (buffer, "<bb ");
1660           pp_decimal_int (buffer, bb->index);
1661           pp_string (buffer, ">:");
1662           pp_newline (buffer);
1663         }
1664     }
1665   pp_write_text_to_stream (buffer);
1666   check_bb_profile (bb, buffer->buffer->stream);
1667 }
1668
1669
1670 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
1671    spaces.  */
1672
1673 static void
1674 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
1675 {
1676   edge e;
1677   edge_iterator ei;
1678
1679   INDENT (indent);
1680   pp_string (buffer, "# SUCC:");
1681   pp_write_text_to_stream (buffer);
1682   FOR_EACH_EDGE (e, ei, bb->succs)
1683     if (flags & TDF_SLIM)
1684       {
1685         pp_string (buffer, " ");
1686         if (e->dest == EXIT_BLOCK_PTR)
1687           pp_string (buffer, "EXIT");
1688         else
1689           pp_decimal_int (buffer, e->dest->index);
1690       }
1691     else
1692       dump_edge_info (buffer->buffer->stream, e, 1);
1693   pp_newline (buffer);
1694 }
1695
1696
1697 /* Dump PHI nodes of basic block BB to BUFFER with details described
1698    by FLAGS and indented by INDENT spaces.  */
1699
1700 static void
1701 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
1702 {
1703   gimple_stmt_iterator i;
1704
1705   for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
1706     {
1707       gimple phi = gsi_stmt (i);
1708       if (is_gimple_reg (gimple_phi_result (phi)) || (flags & TDF_VOPS))
1709         {
1710           INDENT (indent);
1711           pp_string (buffer, "# ");
1712           dump_gimple_phi (buffer, phi, indent, flags);
1713           pp_newline (buffer);
1714         }
1715     }
1716 }
1717
1718
1719 /* Dump jump to basic block BB that is represented implicitly in the cfg
1720    to BUFFER.  */
1721
1722 static void
1723 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
1724 {
1725   gimple stmt;
1726
1727   stmt = first_stmt (bb);
1728
1729   pp_string (buffer, "goto <bb ");
1730   pp_decimal_int (buffer, bb->index);
1731   pp_string (buffer, ">");
1732   if (stmt && gimple_code (stmt) == GIMPLE_LABEL)
1733     {
1734       pp_string (buffer, " (");
1735       dump_generic_node (buffer, gimple_label_label (stmt), 0, 0, false);
1736       pp_string (buffer, ")");
1737       pp_semicolon (buffer);
1738     }
1739   else
1740     pp_semicolon (buffer);
1741 }
1742
1743
1744 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
1745    by INDENT spaces, with details given by FLAGS.  */
1746
1747 static void
1748 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
1749                      int flags)
1750 {
1751   edge e;
1752   edge_iterator ei;
1753   gimple stmt;
1754
1755   stmt = last_stmt (bb);
1756
1757   if (stmt && gimple_code (stmt) == GIMPLE_COND)
1758     {
1759       edge true_edge, false_edge;
1760
1761       /* When we are emitting the code or changing CFG, it is possible that
1762          the edges are not yet created.  When we are using debug_bb in such
1763          a situation, we do not want it to crash.  */
1764       if (EDGE_COUNT (bb->succs) != 2)
1765         return;
1766       extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
1767
1768       INDENT (indent + 2);
1769       pp_cfg_jump (buffer, true_edge->dest);
1770       newline_and_indent (buffer, indent);
1771       pp_string (buffer, "else");
1772       newline_and_indent (buffer, indent + 2);
1773       pp_cfg_jump (buffer, false_edge->dest);
1774       pp_newline (buffer);
1775       return;
1776     }
1777
1778   /* If there is a fallthru edge, we may need to add an artificial
1779      goto to the dump.  */
1780   FOR_EACH_EDGE (e, ei, bb->succs)
1781     if (e->flags & EDGE_FALLTHRU)
1782       break;
1783
1784   if (e && e->dest != bb->next_bb)
1785     {
1786       INDENT (indent);
1787
1788       if ((flags & TDF_LINENO)
1789           && e->goto_locus != UNKNOWN_LOCATION
1790           )
1791         {
1792           expanded_location goto_xloc;
1793           goto_xloc = expand_location (e->goto_locus);
1794           pp_character (buffer, '[');
1795           if (goto_xloc.file)
1796             {
1797               pp_string (buffer, goto_xloc.file);
1798               pp_string (buffer, " : ");
1799             }
1800           pp_decimal_int (buffer, goto_xloc.line);
1801           pp_string (buffer, "] ");
1802         }
1803
1804       pp_cfg_jump (buffer, e->dest);
1805       pp_newline (buffer);
1806     }
1807 }
1808
1809
1810 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
1811    indented by INDENT spaces.  */
1812
1813 static void
1814 gimple_dump_bb_buff (pretty_printer *buffer, basic_block bb, int indent,
1815                      int flags)
1816 {
1817   gimple_stmt_iterator gsi;
1818   gimple stmt;
1819   int label_indent = indent - 2;
1820
1821   if (label_indent < 0)
1822     label_indent = 0;
1823
1824   dump_bb_header (buffer, bb, indent, flags);
1825   dump_phi_nodes (buffer, bb, indent, flags);
1826
1827   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1828     {
1829       int curr_indent;
1830
1831       stmt = gsi_stmt (gsi);
1832
1833       curr_indent = gimple_code (stmt) == GIMPLE_LABEL ? label_indent : indent;
1834
1835       INDENT (curr_indent);
1836       dump_gimple_stmt (buffer, stmt, curr_indent, flags);
1837       pp_newline (buffer);
1838       dump_histograms_for_stmt (cfun, buffer->buffer->stream, stmt);
1839     }
1840
1841   dump_implicit_edges (buffer, bb, indent, flags);
1842
1843   if (flags & TDF_BLOCKS)
1844     dump_bb_end (buffer, bb, indent, flags);
1845 }
1846
1847
1848 /* Dumps basic block BB to FILE with details described by FLAGS and
1849    indented by INDENT spaces.  */
1850
1851 void
1852 gimple_dump_bb (basic_block bb, FILE *file, int indent, int flags)
1853 {
1854   maybe_init_pretty_print (file);
1855   gimple_dump_bb_buff (&buffer, bb, indent, flags);
1856   pp_flush (&buffer);
1857 }