OSDN Git Service

* builtins.c (expand_builtin_synchronize): Use gimple_build_asm_vec.
[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, 2009
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_character (buffer, '(');
261       dump_generic_node (buffer, TREE_TYPE (lhs), spc, flags, false);
262       pp_string (buffer, ") ");
263       if (op_prio (rhs) < op_code_prio (rhs_code))
264         {
265           pp_character (buffer, '(');
266           dump_generic_node (buffer, rhs, spc, flags, false);
267           pp_character (buffer, ')');
268         }
269       else
270         dump_generic_node (buffer, rhs, spc, flags, false);
271       break;
272       
273     case PAREN_EXPR:
274       pp_string (buffer, "((");
275       dump_generic_node (buffer, rhs, spc, flags, false);
276       pp_string (buffer, "))");
277       break;
278       
279     case ABS_EXPR:
280       pp_string (buffer, "ABS_EXPR <");
281       dump_generic_node (buffer, rhs, spc, flags, false);
282       pp_character (buffer, '>');
283       break;
284
285     default:
286       if (TREE_CODE_CLASS (rhs_code) == tcc_declaration
287           || TREE_CODE_CLASS (rhs_code) == tcc_constant
288           || TREE_CODE_CLASS (rhs_code) == tcc_reference
289           || rhs_code == SSA_NAME
290           || rhs_code == ADDR_EXPR
291           || rhs_code == CONSTRUCTOR)
292         {
293           dump_generic_node (buffer, rhs, spc, flags, false);
294           break;
295         }
296       else if (rhs_code == BIT_NOT_EXPR)
297         pp_character (buffer, '~');
298       else if (rhs_code == TRUTH_NOT_EXPR)
299         pp_character (buffer, '!');
300       else if (rhs_code == NEGATE_EXPR)
301         pp_character (buffer, '-');
302       else
303         {
304           pp_character (buffer, '[');
305           pp_string (buffer, tree_code_name [rhs_code]);
306           pp_string (buffer, "] ");
307         }
308
309       if (op_prio (rhs) < op_code_prio (rhs_code))
310         {
311           pp_character (buffer, '(');
312           dump_generic_node (buffer, rhs, spc, flags, false);
313           pp_character (buffer, ')');
314         }
315       else
316         dump_generic_node (buffer, rhs, spc, flags, false);
317       break;
318     }
319 }
320
321
322 /* Helper for dump_gimple_assign.  Print the binary RHS of the
323    assignment GS.  BUFFER, SPC and FLAGS are as in dump_gimple_stmt.  */
324
325 static void
326 dump_binary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
327 {
328   const char *p;
329   enum tree_code code = gimple_assign_rhs_code (gs);
330   switch (code)
331     {
332     case COMPLEX_EXPR:
333     case MIN_EXPR:
334     case MAX_EXPR:
335     case VEC_WIDEN_MULT_HI_EXPR:
336     case VEC_WIDEN_MULT_LO_EXPR:
337     case VEC_PACK_TRUNC_EXPR:
338     case VEC_PACK_SAT_EXPR:
339     case VEC_PACK_FIX_TRUNC_EXPR:
340     case VEC_EXTRACT_EVEN_EXPR:
341     case VEC_EXTRACT_ODD_EXPR:
342     case VEC_INTERLEAVE_HIGH_EXPR:
343     case VEC_INTERLEAVE_LOW_EXPR:
344       for (p = tree_code_name [(int) code]; *p; p++)
345         pp_character (buffer, TOUPPER (*p));
346       pp_string (buffer, " <");
347       dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
348       pp_string (buffer, ", ");
349       dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
350       pp_character (buffer, '>');
351       break;
352
353     default:
354       if (op_prio (gimple_assign_rhs1 (gs)) <= op_code_prio (code))
355         {
356           pp_character (buffer, '(');
357           dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags,
358                              false);
359           pp_character (buffer, ')');
360         }
361       else
362         dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
363       pp_space (buffer);
364       pp_string (buffer, op_symbol_code (gimple_assign_rhs_code (gs)));
365       pp_space (buffer);
366       if (op_prio (gimple_assign_rhs2 (gs)) <= op_code_prio (code))
367         {
368           pp_character (buffer, '(');
369           dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags,
370                              false);
371           pp_character (buffer, ')');
372         }
373       else
374         dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
375     }
376 }
377
378
379 /* Dump the gimple assignment GS.  BUFFER, SPC and FLAGS are as in
380    dump_gimple_stmt.  */
381
382 static void
383 dump_gimple_assign (pretty_printer *buffer, gimple gs, int spc, int flags)
384 {
385   if (flags & TDF_RAW)
386     {
387       tree last;
388       if (gimple_num_ops (gs) == 2)
389         last = NULL_TREE;
390       else if (gimple_num_ops (gs) == 3)
391         last = gimple_assign_rhs2 (gs);
392       else
393         gcc_unreachable ();
394
395       dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T, %T, %T>", gs,
396                        tree_code_name[gimple_assign_rhs_code (gs)],
397                        gimple_assign_lhs (gs), gimple_assign_rhs1 (gs), last);
398     }
399   else
400     {
401       if (!(flags & TDF_RHS_ONLY))
402         {
403           dump_generic_node (buffer, gimple_assign_lhs (gs), spc, flags, false);
404           pp_space (buffer);
405           pp_character (buffer, '=');
406
407           if (gimple_assign_nontemporal_move_p (gs))
408             pp_string (buffer, "{nt}");
409
410           if (gimple_has_volatile_ops (gs))
411             pp_string (buffer, "{v}");
412
413           pp_space (buffer);
414         }
415
416       if (gimple_num_ops (gs) == 2)
417         dump_unary_rhs (buffer, gs, spc, flags);
418       else if (gimple_num_ops (gs) == 3)
419         dump_binary_rhs (buffer, gs, spc, flags);
420       else
421         gcc_unreachable ();
422       if (!(flags & TDF_RHS_ONLY))
423         pp_semicolon(buffer);
424     }
425 }
426
427
428 /* Dump the return statement GS.  BUFFER, SPC and FLAGS are as in
429    dump_gimple_stmt.  */
430
431 static void
432 dump_gimple_return (pretty_printer *buffer, gimple gs, int spc, int flags)
433 {
434   tree t;
435
436   t = gimple_return_retval (gs);
437   if (flags & TDF_RAW)
438     dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs, t);
439   else
440     {
441       pp_string (buffer, "return");
442       if (t)
443         {
444           pp_space (buffer);
445           dump_generic_node (buffer, t, spc, flags, false);
446         }
447       pp_semicolon (buffer);
448     }
449 }
450
451
452 /* Dump the call arguments for a gimple call. BUFFER, FLAGS are as in
453    dump_gimple_call.  */
454
455 static void
456 dump_gimple_call_args (pretty_printer *buffer, gimple gs, int flags)
457 {
458   size_t i;
459
460   for (i = 0; i < gimple_call_num_args (gs); i++)
461     {
462       dump_generic_node (buffer, gimple_call_arg (gs, i), 0, flags, false);
463       if (i < gimple_call_num_args (gs) - 1)
464         pp_string (buffer, ", ");
465     }
466
467   if (gimple_call_va_arg_pack_p (gs))
468     {
469       if (gimple_call_num_args (gs) > 0)
470         {
471           pp_character (buffer, ',');
472           pp_space (buffer);
473         }
474
475       pp_string (buffer, "__builtin_va_arg_pack ()");
476     }
477 }
478
479
480 /* Dump the call statement GS.  BUFFER, SPC and FLAGS are as in
481    dump_gimple_stmt.  */
482
483 static void
484 dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags)
485 {
486   tree lhs = gimple_call_lhs (gs);
487
488   if (flags & TDF_RAW)
489     {
490       dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T",
491                      gs, gimple_call_fn (gs), lhs);
492       if (gimple_call_num_args (gs) > 0)
493         {
494           pp_string (buffer, ", ");
495           dump_gimple_call_args (buffer, gs, flags);
496         }
497       pp_character (buffer, '>');
498     }
499   else
500     {
501       if (lhs && !(flags & TDF_RHS_ONLY))
502         {
503           dump_generic_node (buffer, lhs, spc, flags, false);
504           pp_string (buffer, " =");
505
506           if (gimple_has_volatile_ops (gs))
507             pp_string (buffer, "{v}");
508
509           pp_space (buffer);
510         }
511       print_call_name (buffer, gimple_call_fn (gs), flags);
512       pp_string (buffer, " (");
513       dump_gimple_call_args (buffer, gs, flags);
514       pp_character (buffer, ')');
515       if (!(flags & TDF_RHS_ONLY))
516         pp_semicolon (buffer);
517     }
518
519   if (gimple_call_chain (gs))
520     {
521       pp_string (buffer, " [static-chain: ");
522       dump_generic_node (buffer, gimple_call_chain (gs), spc, flags, false);
523       pp_character (buffer, ']');
524     }
525
526   if (gimple_call_return_slot_opt_p (gs))
527     pp_string (buffer, " [return slot optimization]");
528
529   if (gimple_call_tail_p (gs))
530     pp_string (buffer, " [tail call]");
531 }
532
533
534 /* Dump the switch statement GS.  BUFFER, SPC and FLAGS are as in
535    dump_gimple_stmt.  */
536
537 static void
538 dump_gimple_switch (pretty_printer *buffer, gimple gs, int spc, int flags)
539 {
540   unsigned int i;
541
542   GIMPLE_CHECK (gs, GIMPLE_SWITCH);
543   if (flags & TDF_RAW)
544     dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", gs,
545                    gimple_switch_index (gs));
546   else
547     {
548       pp_string (buffer, "switch (");
549       dump_generic_node (buffer, gimple_switch_index (gs), spc, flags, true);
550       pp_string (buffer, ") <");
551     }
552
553   for (i = 0; i < gimple_switch_num_labels (gs); i++)
554     {
555       tree case_label = gimple_switch_label (gs, i);
556       if (case_label == NULL_TREE)
557         continue;
558
559       dump_generic_node (buffer, case_label, spc, flags, false);
560       pp_character (buffer, ' ');
561       dump_generic_node (buffer, CASE_LABEL (case_label), spc, flags, false);
562       if (i < gimple_switch_num_labels (gs) - 1)
563         pp_string (buffer, ", ");
564     }
565   pp_character (buffer, '>');
566 }
567
568
569 /* Dump the gimple conditional GS.  BUFFER, SPC and FLAGS are as in
570    dump_gimple_stmt.  */
571
572 static void
573 dump_gimple_cond (pretty_printer *buffer, gimple gs, int spc, int flags)
574 {
575   if (flags & TDF_RAW)
576     dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T, %T, %T, %T>", gs,
577                    tree_code_name [gimple_cond_code (gs)],
578                    gimple_cond_lhs (gs), gimple_cond_rhs (gs),
579                    gimple_cond_true_label (gs), gimple_cond_false_label (gs));
580   else
581     {
582       if (!(flags & TDF_RHS_ONLY))
583         pp_string (buffer, "if (");
584       dump_generic_node (buffer, gimple_cond_lhs (gs), spc, flags, false);
585       pp_space (buffer);
586       pp_string (buffer, op_symbol_code (gimple_cond_code (gs)));
587       pp_space (buffer);
588       dump_generic_node (buffer, gimple_cond_rhs (gs), spc, flags, false);
589       if (!(flags & TDF_RHS_ONLY))
590         {
591           pp_character (buffer, ')');
592
593           if (gimple_cond_true_label (gs))
594             {
595               pp_string (buffer, " goto ");
596               dump_generic_node (buffer, gimple_cond_true_label (gs),
597                                  spc, flags, false);
598               pp_semicolon (buffer);
599             }
600           if (gimple_cond_false_label (gs))
601             {
602               pp_string (buffer, " else goto ");
603               dump_generic_node (buffer, gimple_cond_false_label (gs),
604                                  spc, flags, false);
605               pp_semicolon (buffer);
606             }
607         }
608     }
609 }
610
611
612 /* Dump a GIMPLE_LABEL tuple on the pretty_printer BUFFER, SPC
613    spaces of indent.  FLAGS specifies details to show in the dump (see
614    TDF_* in tree-pass.h).  */
615
616 static void
617 dump_gimple_label (pretty_printer *buffer, gimple gs, int spc, int flags)
618 {
619   tree label = gimple_label_label (gs);
620   if (flags & TDF_RAW)
621       dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs, label);
622   else
623     {
624       dump_generic_node (buffer, label, spc, flags, false);
625       pp_character (buffer, ':');
626     }
627   if (DECL_NONLOCAL (label))
628     pp_string (buffer, " [non-local]");
629   if ((flags & TDF_EH) && EH_LANDING_PAD_NR (label))
630     pp_printf (buffer, " [LP %d]", EH_LANDING_PAD_NR (label));
631 }
632
633 /* Dump a GIMPLE_GOTO tuple on the pretty_printer BUFFER, SPC
634    spaces of indent.  FLAGS specifies details to show in the dump (see
635    TDF_* in tree-pass.h).  */
636
637 static void
638 dump_gimple_goto (pretty_printer *buffer, gimple gs, int spc, int flags)
639 {
640   tree label = gimple_goto_dest (gs);
641   if (flags & TDF_RAW)
642     dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs, label);
643   else
644     dump_gimple_fmt (buffer, spc, flags, "goto %T;", label);
645 }
646
647
648 /* Dump a GIMPLE_BIND tuple on the pretty_printer BUFFER, SPC
649    spaces of indent.  FLAGS specifies details to show in the dump (see
650    TDF_* in tree-pass.h).  */
651
652 static void
653 dump_gimple_bind (pretty_printer *buffer, gimple gs, int spc, int flags)
654 {
655   if (flags & TDF_RAW)
656     dump_gimple_fmt (buffer, spc, flags, "%G <", gs);
657   else
658     pp_character (buffer, '{');
659   if (!(flags & TDF_SLIM))
660     {
661       tree var;
662
663       for (var = gimple_bind_vars (gs); var; var = TREE_CHAIN (var))
664         {
665           newline_and_indent (buffer, 2);
666           print_declaration (buffer, var, spc, flags);
667         }
668       if (gimple_bind_vars (gs))
669         pp_newline (buffer);
670     }
671   pp_newline (buffer);
672   dump_gimple_seq (buffer, gimple_bind_body (gs), spc + 2, flags);
673   newline_and_indent (buffer, spc);
674   if (flags & TDF_RAW)
675     pp_character (buffer, '>');
676   else
677     pp_character (buffer, '}');
678 }
679
680
681 /* Dump a GIMPLE_TRY tuple on the pretty_printer BUFFER, SPC spaces of
682    indent.  FLAGS specifies details to show in the dump (see TDF_* in
683    tree-pass.h).  */
684
685 static void
686 dump_gimple_try (pretty_printer *buffer, gimple gs, int spc, int flags)
687 {
688   if (flags & TDF_RAW)
689     {
690       const char *type;
691       if (gimple_try_kind (gs) == GIMPLE_TRY_CATCH)
692         type = "GIMPLE_TRY_CATCH";
693       else if (gimple_try_kind (gs) == GIMPLE_TRY_FINALLY)
694         type = "GIMPLE_TRY_FINALLY";
695       else
696         type = "UNKNOWN GIMPLE_TRY";
697       dump_gimple_fmt (buffer, spc, flags,
698                        "%G <%s,%+EVAL <%S>%nCLEANUP <%S>%->", gs, type,
699                        gimple_try_eval (gs), gimple_try_cleanup (gs));
700     }
701   else
702     {
703       pp_string (buffer, "try");
704       newline_and_indent (buffer, spc + 2);
705       pp_character (buffer, '{');
706       pp_newline (buffer);
707
708       dump_gimple_seq (buffer, gimple_try_eval (gs), spc + 4, flags);
709       newline_and_indent (buffer, spc + 2);
710       pp_character (buffer, '}');
711
712       if (gimple_try_kind (gs) == GIMPLE_TRY_CATCH)
713         {
714           newline_and_indent (buffer, spc);
715           pp_string (buffer, "catch");
716           newline_and_indent (buffer, spc + 2);
717           pp_character (buffer, '{');
718         }
719       else if (gimple_try_kind (gs) == GIMPLE_TRY_FINALLY)
720         {
721           newline_and_indent (buffer, spc);
722           pp_string (buffer, "finally");
723           newline_and_indent (buffer, spc + 2);
724           pp_character (buffer, '{');
725         }
726       else
727         pp_string (buffer, " <UNKNOWN GIMPLE_TRY> {");
728
729       pp_newline (buffer);
730       dump_gimple_seq (buffer, gimple_try_cleanup (gs), spc + 4, flags);
731       newline_and_indent (buffer, spc + 2);
732       pp_character (buffer, '}');
733     }
734 }
735
736
737 /* Dump a GIMPLE_CATCH 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_catch (pretty_printer *buffer, gimple gs, int spc, int flags)
743 {
744   if (flags & TDF_RAW)
745       dump_gimple_fmt (buffer, spc, flags, "%G <%T, %+CATCH <%S>%->", gs,
746                        gimple_catch_types (gs), gimple_catch_handler (gs));
747   else
748       dump_gimple_fmt (buffer, spc, flags, "catch (%T)%+{%S}",
749                        gimple_catch_types (gs), gimple_catch_handler (gs));
750 }
751
752
753 /* Dump a GIMPLE_EH_FILTER tuple on the pretty_printer BUFFER, SPC spaces of
754    indent.  FLAGS specifies details to show in the dump (see TDF_* in
755    tree-pass.h).  */
756
757 static void
758 dump_gimple_eh_filter (pretty_printer *buffer, gimple gs, int spc, int flags)
759 {
760   if (flags & TDF_RAW)
761     dump_gimple_fmt (buffer, spc, flags, "%G <%T, %+FAILURE <%S>%->", gs,
762                      gimple_eh_filter_types (gs),
763                      gimple_eh_filter_failure (gs));
764   else
765     dump_gimple_fmt (buffer, spc, flags, "<<<eh_filter (%T)>>>%+{%+%S%-}",
766                      gimple_eh_filter_types (gs),
767                      gimple_eh_filter_failure (gs));
768 }
769
770
771 /* Dump a GIMPLE_EH_MUST_NOT_THROW tuple.  */
772
773 static void
774 dump_gimple_eh_must_not_throw (pretty_printer *buffer, gimple gs,
775                                int spc, int flags)
776 {
777   if (flags & TDF_RAW)
778     dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs,
779                      gimple_eh_must_not_throw_fndecl (gs));
780   else
781     dump_gimple_fmt (buffer, spc, flags, "<<<eh_must_not_throw (%T)>>>",
782                      gimple_eh_must_not_throw_fndecl (gs));
783 }
784
785
786 /* Dump a GIMPLE_RESX tuple on the pretty_printer BUFFER, SPC spaces of
787    indent.  FLAGS specifies details to show in the dump (see TDF_* in
788    tree-pass.h).  */
789
790 static void
791 dump_gimple_resx (pretty_printer *buffer, gimple gs, int spc, int flags)
792 {
793   if (flags & TDF_RAW)
794     dump_gimple_fmt (buffer, spc, flags, "%G <%d>", gs,
795                      gimple_resx_region (gs));
796   else
797     dump_gimple_fmt (buffer, spc, flags, "resx %d", gimple_resx_region (gs));
798 }
799
800 /* Dump a GIMPLE_EH_DISPATCH tuple on the pretty_printer BUFFER.  */
801
802 static void
803 dump_gimple_eh_dispatch (pretty_printer *buffer, gimple gs, int spc, int flags)
804 {
805   if (flags & TDF_RAW)
806     dump_gimple_fmt (buffer, spc, flags, "%G <%d>", gs,
807                      gimple_eh_dispatch_region (gs));
808   else
809     dump_gimple_fmt (buffer, spc, flags, "eh_dispatch %d",
810                      gimple_eh_dispatch_region (gs));
811 }
812
813 /* Dump a GIMPLE_DEBUG tuple on the pretty_printer BUFFER, SPC spaces
814    of indent.  FLAGS specifies details to show in the dump (see TDF_*
815    in tree-pass.h).  */
816
817 static void
818 dump_gimple_debug (pretty_printer *buffer, gimple gs, int spc, int flags)
819 {
820   switch (gs->gsbase.subcode)
821     {
822     case GIMPLE_DEBUG_BIND:
823       if (flags & TDF_RAW)
824         dump_gimple_fmt (buffer, spc, flags, "%G BIND <%T, %T>", gs,
825                          gimple_debug_bind_get_var (gs),
826                          gimple_debug_bind_get_value (gs));
827       else
828         dump_gimple_fmt (buffer, spc, flags, "# DEBUG %T => %T",
829                          gimple_debug_bind_get_var (gs),
830                          gimple_debug_bind_get_value (gs));
831       break;
832
833     default:
834       gcc_unreachable ();
835     }
836 }
837
838 /* Dump a GIMPLE_OMP_FOR tuple on the pretty_printer BUFFER.  */
839 static void
840 dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
841 {
842   size_t i;
843
844   if (flags & TDF_RAW)
845     {
846       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
847                        gimple_omp_body (gs));
848       dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
849       dump_gimple_fmt (buffer, spc, flags, " >,");
850       for (i = 0; i < gimple_omp_for_collapse (gs); i++)
851         dump_gimple_fmt (buffer, spc, flags,
852                          "%+%T, %T, %T, %s, %T,%n",
853                          gimple_omp_for_index (gs, i),
854                          gimple_omp_for_initial (gs, i),
855                          gimple_omp_for_final (gs, i),
856                          tree_code_name[gimple_omp_for_cond (gs, i)],
857                          gimple_omp_for_incr (gs, i));
858       dump_gimple_fmt (buffer, spc, flags, "PRE_BODY <%S>%->",
859                        gimple_omp_for_pre_body (gs));
860     }
861   else
862     {
863       pp_string (buffer, "#pragma omp for");
864       dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
865       for (i = 0; i < gimple_omp_for_collapse (gs); i++)
866         {
867           if (i)
868             spc += 2;
869           newline_and_indent (buffer, spc);
870           pp_string (buffer, "for (");
871           dump_generic_node (buffer, gimple_omp_for_index (gs, i), spc,
872                              flags, false);
873           pp_string (buffer, " = ");
874           dump_generic_node (buffer, gimple_omp_for_initial (gs, i), spc,
875                              flags, false);
876           pp_string (buffer, "; ");
877
878           dump_generic_node (buffer, gimple_omp_for_index (gs, i), spc,
879                              flags, false);
880           pp_space (buffer);
881           switch (gimple_omp_for_cond (gs, i))
882             {
883             case LT_EXPR:
884               pp_character (buffer, '<');
885               break;
886             case GT_EXPR:
887               pp_character (buffer, '>');
888               break;
889             case LE_EXPR:
890               pp_string (buffer, "<=");
891               break;
892             case GE_EXPR:
893               pp_string (buffer, ">=");
894               break;
895             default:
896               gcc_unreachable ();
897             }
898           pp_space (buffer);
899           dump_generic_node (buffer, gimple_omp_for_final (gs, i), spc,
900                              flags, false);
901           pp_string (buffer, "; ");
902
903           dump_generic_node (buffer, gimple_omp_for_index (gs, i), spc,
904                              flags, false);
905           pp_string (buffer, " = ");
906           dump_generic_node (buffer, gimple_omp_for_incr (gs, i), spc,
907                              flags, false);
908           pp_character (buffer, ')');
909         }
910
911       if (!gimple_seq_empty_p (gimple_omp_body (gs)))
912         {
913           newline_and_indent (buffer, spc + 2);
914           pp_character (buffer, '{');
915           pp_newline (buffer);
916           dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
917           newline_and_indent (buffer, spc + 2);
918           pp_character (buffer, '}');
919         }
920     }
921 }
922
923 /* Dump a GIMPLE_OMP_CONTINUE tuple on the pretty_printer BUFFER.  */
924
925 static void
926 dump_gimple_omp_continue (pretty_printer *buffer, gimple gs, int spc, int flags)
927 {
928   if (flags & TDF_RAW)
929     {
930       dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T>", gs,
931                        gimple_omp_continue_control_def (gs),
932                        gimple_omp_continue_control_use (gs));
933     }
934   else
935     {
936       pp_string (buffer, "#pragma omp continue (");
937       dump_generic_node (buffer, gimple_omp_continue_control_def (gs),
938                          spc, flags, false);
939       pp_character (buffer, ',');
940       pp_space (buffer);
941       dump_generic_node (buffer, gimple_omp_continue_control_use (gs),
942                          spc, flags, false);
943       pp_character (buffer, ')');
944     }
945 }
946
947 /* Dump a GIMPLE_OMP_SINGLE tuple on the pretty_printer BUFFER.  */
948
949 static void
950 dump_gimple_omp_single (pretty_printer *buffer, gimple gs, int spc, int flags)
951 {
952   if (flags & TDF_RAW)
953     {
954       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
955                        gimple_omp_body (gs));
956       dump_omp_clauses (buffer, gimple_omp_single_clauses (gs), spc, flags);
957       dump_gimple_fmt (buffer, spc, flags, " >");
958     }
959   else
960     {
961       pp_string (buffer, "#pragma omp single");
962       dump_omp_clauses (buffer, gimple_omp_single_clauses (gs), spc, flags);
963       if (!gimple_seq_empty_p (gimple_omp_body (gs)))
964         {
965           newline_and_indent (buffer, spc + 2);
966           pp_character (buffer, '{');
967           pp_newline (buffer);
968           dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
969           newline_and_indent (buffer, spc + 2);
970           pp_character (buffer, '}');
971         }
972     }
973 }
974
975 /* Dump a GIMPLE_OMP_SECTIONS tuple on the pretty_printer BUFFER.  */
976
977 static void
978 dump_gimple_omp_sections (pretty_printer *buffer, gimple gs, int spc,
979                           int flags)
980 {
981   if (flags & TDF_RAW)
982     {
983       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
984                        gimple_omp_body (gs));
985       dump_omp_clauses (buffer, gimple_omp_sections_clauses (gs), spc, flags);
986       dump_gimple_fmt (buffer, spc, flags, " >");
987     }
988   else
989     {
990       pp_string (buffer, "#pragma omp sections");
991       if (gimple_omp_sections_control (gs))
992         {
993           pp_string (buffer, " <");
994           dump_generic_node (buffer, gimple_omp_sections_control (gs), spc,
995                              flags, false);
996           pp_character (buffer, '>');
997         }
998       dump_omp_clauses (buffer, gimple_omp_sections_clauses (gs), spc, flags);
999       if (!gimple_seq_empty_p (gimple_omp_body (gs)))
1000         {
1001           newline_and_indent (buffer, spc + 2);
1002           pp_character (buffer, '{');
1003           pp_newline (buffer);
1004           dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
1005           newline_and_indent (buffer, spc + 2);
1006           pp_character (buffer, '}');
1007         }
1008     }
1009 }
1010
1011 /* Dump a GIMPLE_OMP_{MASTER,ORDERED,SECTION} tuple on the pretty_printer
1012    BUFFER.  */
1013
1014 static void
1015 dump_gimple_omp_block (pretty_printer *buffer, gimple gs, int spc, int flags)
1016 {
1017   if (flags & TDF_RAW)
1018     dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S> >", gs,
1019                      gimple_omp_body (gs));
1020   else
1021     {
1022       switch (gimple_code (gs))
1023         {
1024         case GIMPLE_OMP_MASTER:
1025           pp_string (buffer, "#pragma omp master");
1026           break;
1027         case GIMPLE_OMP_ORDERED:
1028           pp_string (buffer, "#pragma omp ordered");
1029           break;
1030         case GIMPLE_OMP_SECTION:
1031           pp_string (buffer, "#pragma omp section");
1032           break;
1033         default:
1034           gcc_unreachable ();
1035         }
1036       if (!gimple_seq_empty_p (gimple_omp_body (gs)))
1037         {
1038           newline_and_indent (buffer, spc + 2);
1039           pp_character (buffer, '{');
1040           pp_newline (buffer);
1041           dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
1042           newline_and_indent (buffer, spc + 2);
1043           pp_character (buffer, '}');
1044         }
1045     }
1046 }
1047
1048 /* Dump a GIMPLE_OMP_CRITICAL tuple on the pretty_printer BUFFER.  */
1049
1050 static void
1051 dump_gimple_omp_critical (pretty_printer *buffer, gimple gs, int spc,
1052                           int flags)
1053 {
1054   if (flags & TDF_RAW)
1055     dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S> >", gs,
1056                      gimple_omp_body (gs));
1057   else
1058     {
1059       pp_string (buffer, "#pragma omp critical");
1060       if (gimple_omp_critical_name (gs))
1061         {
1062           pp_string (buffer, " (");
1063           dump_generic_node (buffer, gimple_omp_critical_name (gs), spc,
1064                              flags, false);
1065           pp_character (buffer, ')');
1066         }
1067       if (!gimple_seq_empty_p (gimple_omp_body (gs)))
1068         {
1069           newline_and_indent (buffer, spc + 2);
1070           pp_character (buffer, '{');
1071           pp_newline (buffer);
1072           dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
1073           newline_and_indent (buffer, spc + 2);
1074           pp_character (buffer, '}');
1075         }
1076     }
1077 }
1078
1079 /* Dump a GIMPLE_OMP_RETURN tuple on the pretty_printer BUFFER.  */
1080
1081 static void
1082 dump_gimple_omp_return (pretty_printer *buffer, gimple gs, int spc, int flags)
1083 {
1084   if (flags & TDF_RAW)
1085     {
1086       dump_gimple_fmt (buffer, spc, flags, "%G <nowait=%d>", gs,
1087                        (int) gimple_omp_return_nowait_p (gs));
1088     }
1089   else
1090     {
1091       pp_string (buffer, "#pragma omp return");
1092       if (gimple_omp_return_nowait_p (gs))
1093         pp_string (buffer, "(nowait)");
1094     }
1095 }
1096
1097 /* Dump a GIMPLE_ASM tuple on the pretty_printer BUFFER, SPC spaces of
1098    indent.  FLAGS specifies details to show in the dump (see TDF_* in
1099    tree-pass.h).  */
1100
1101 static void
1102 dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags)
1103 {
1104   unsigned int i, n, f, fields;
1105
1106   if (flags & TDF_RAW)
1107     {
1108       dump_gimple_fmt (buffer, spc, flags, "%G <%+STRING <%n%s%n>", gs,
1109                        gimple_asm_string (gs));
1110
1111       n = gimple_asm_noutputs (gs);
1112       if (n)
1113         {
1114           newline_and_indent (buffer, spc + 2);
1115           pp_string (buffer, "OUTPUT: ");
1116           for (i = 0; i < n; i++)
1117             {
1118               dump_generic_node (buffer, gimple_asm_output_op (gs, i),
1119                                  spc, flags, false);
1120               if (i < n - 1)
1121                 pp_string (buffer, ", ");
1122             }
1123         }
1124
1125       n = gimple_asm_ninputs (gs);
1126       if (n)
1127         {
1128           newline_and_indent (buffer, spc + 2);
1129           pp_string (buffer, "INPUT: ");
1130           for (i = 0; i < n; i++)
1131             {
1132               dump_generic_node (buffer, gimple_asm_input_op (gs, i),
1133                                  spc, flags, false);
1134               if (i < n - 1)
1135                 pp_string (buffer, ", ");
1136             }
1137         }
1138
1139       n = gimple_asm_nclobbers (gs);
1140       if (n)
1141         {
1142           newline_and_indent (buffer, spc + 2);
1143           pp_string (buffer, "CLOBBER: ");
1144           for (i = 0; i < n; i++)
1145             {
1146               dump_generic_node (buffer, gimple_asm_clobber_op (gs, i),
1147                                  spc, flags, false);
1148               if (i < n - 1)
1149                 pp_string (buffer, ", ");
1150             }
1151         }
1152
1153       n = gimple_asm_nlabels (gs);
1154       if (n)
1155         {
1156           newline_and_indent (buffer, spc + 2);
1157           pp_string (buffer, "LABEL: ");
1158           for (i = 0; i < n; i++)
1159             {
1160               dump_generic_node (buffer, gimple_asm_label_op (gs, i),
1161                                  spc, flags, false);
1162               if (i < n - 1)
1163                 pp_string (buffer, ", ");
1164             }
1165         }
1166
1167       newline_and_indent (buffer, spc);
1168       pp_character (buffer, '>');
1169     }
1170   else
1171     {
1172       pp_string (buffer, "__asm__");
1173       if (gimple_asm_volatile_p (gs))
1174         pp_string (buffer, " __volatile__");
1175       if (gimple_asm_nlabels (gs))
1176         pp_string (buffer, " goto");
1177       pp_string (buffer, "(\"");
1178       pp_string (buffer, gimple_asm_string (gs));
1179       pp_string (buffer, "\"");
1180
1181       if (gimple_asm_nlabels (gs))
1182         fields = 4;
1183       else if (gimple_asm_nclobbers (gs))
1184         fields = 3;
1185       else if (gimple_asm_ninputs (gs))
1186         fields = 2;
1187       else if (gimple_asm_noutputs (gs))
1188         fields = 1;
1189       else
1190         fields = 0;
1191
1192       for (f = 0; f < fields; ++f)
1193         {
1194           pp_string (buffer, " : ");
1195
1196           switch (f)
1197             {
1198             case 0:
1199               n = gimple_asm_noutputs (gs);
1200               for (i = 0; i < n; i++)
1201                 {
1202                   dump_generic_node (buffer, gimple_asm_output_op (gs, i),
1203                                      spc, flags, false);
1204                   if (i < n - 1)
1205                     pp_string (buffer, ", ");
1206                 }
1207               break;
1208
1209             case 1:
1210               n = gimple_asm_ninputs (gs);
1211               for (i = 0; i < n; i++)
1212                 {
1213                   dump_generic_node (buffer, gimple_asm_input_op (gs, i),
1214                                      spc, flags, false);
1215                   if (i < n - 1)
1216                     pp_string (buffer, ", ");
1217                 }
1218               break;
1219
1220             case 2:
1221               n = gimple_asm_nclobbers (gs);
1222               for (i = 0; i < n; i++)
1223                 {
1224                   dump_generic_node (buffer, gimple_asm_clobber_op (gs, i),
1225                                      spc, flags, false);
1226                   if (i < n - 1)
1227                     pp_string (buffer, ", ");
1228                 }
1229               break;
1230
1231             case 3:
1232               n = gimple_asm_nlabels (gs);
1233               for (i = 0; i < n; i++)
1234                 {
1235                   dump_generic_node (buffer, gimple_asm_label_op (gs, i),
1236                                      spc, flags, false);
1237                   if (i < n - 1)
1238                     pp_string (buffer, ", ");
1239                 }
1240               break;
1241
1242             default:
1243               gcc_unreachable ();
1244             }
1245         }
1246
1247       pp_string (buffer, ");");
1248     }
1249 }
1250
1251
1252 /* Dump a PHI node PHI.  BUFFER, SPC and FLAGS are as in
1253    dump_gimple_stmt.  */
1254
1255 static void
1256 dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
1257 {
1258   size_t i;
1259
1260   if (flags & TDF_RAW)
1261       dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", phi,
1262                        gimple_phi_result (phi));
1263   else
1264     {
1265       dump_generic_node (buffer, gimple_phi_result (phi), spc, flags, false);
1266       pp_string (buffer, " = PHI <");
1267     }
1268   for (i = 0; i < gimple_phi_num_args (phi); i++)
1269     {
1270       if ((flags & TDF_LINENO) && gimple_phi_arg_has_location (phi, i))
1271         {
1272           expanded_location xloc;
1273
1274           xloc = expand_location (gimple_phi_arg_location (phi, i));
1275           pp_character (buffer, '[');
1276           if (xloc.file)
1277             {
1278               pp_string (buffer, xloc.file);
1279               pp_string (buffer, " : ");
1280             }
1281           pp_decimal_int (buffer, xloc.line);
1282           pp_string (buffer, ":");
1283           pp_decimal_int (buffer, xloc.column);
1284           pp_string (buffer, "] ");
1285         }
1286       dump_generic_node (buffer, gimple_phi_arg_def (phi, i), spc, flags,
1287                          false);
1288       pp_character (buffer, '(');
1289       pp_decimal_int (buffer, gimple_phi_arg_edge (phi, i)->src->index);
1290       pp_character (buffer, ')');
1291       if (i < gimple_phi_num_args (phi) - 1)
1292         pp_string (buffer, ", ");
1293     }
1294   pp_character (buffer, '>');
1295 }
1296
1297
1298 /* Dump a GIMPLE_OMP_PARALLEL tuple on the pretty_printer BUFFER, SPC spaces
1299    of indent.  FLAGS specifies details to show in the dump (see TDF_* in
1300    tree-pass.h).  */
1301
1302 static void
1303 dump_gimple_omp_parallel (pretty_printer *buffer, gimple gs, int spc,
1304                           int flags)
1305 {
1306   if (flags & TDF_RAW)
1307     {
1308       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
1309                        gimple_omp_body (gs));
1310       dump_omp_clauses (buffer, gimple_omp_parallel_clauses (gs), spc, flags);
1311       dump_gimple_fmt (buffer, spc, flags, " >, %T, %T%n>",
1312                        gimple_omp_parallel_child_fn (gs),
1313                        gimple_omp_parallel_data_arg (gs));
1314     }
1315   else
1316     {
1317       gimple_seq body;
1318       pp_string (buffer, "#pragma omp parallel");
1319       dump_omp_clauses (buffer, gimple_omp_parallel_clauses (gs), spc, flags);
1320       if (gimple_omp_parallel_child_fn (gs))
1321         {
1322           pp_string (buffer, " [child fn: ");
1323           dump_generic_node (buffer, gimple_omp_parallel_child_fn (gs),
1324                              spc, flags, false);
1325           pp_string (buffer, " (");
1326           if (gimple_omp_parallel_data_arg (gs))
1327             dump_generic_node (buffer, gimple_omp_parallel_data_arg (gs),
1328                                spc, flags, false);
1329           else
1330             pp_string (buffer, "???");
1331           pp_string (buffer, ")]");
1332         }
1333       body = gimple_omp_body (gs);
1334       if (body && gimple_code (gimple_seq_first_stmt (body)) != GIMPLE_BIND)
1335         {
1336           newline_and_indent (buffer, spc + 2);
1337           pp_character (buffer, '{');
1338           pp_newline (buffer);
1339           dump_gimple_seq (buffer, body, spc + 4, flags);
1340           newline_and_indent (buffer, spc + 2);
1341           pp_character (buffer, '}');
1342         }
1343       else if (body)
1344         {
1345           pp_newline (buffer);
1346           dump_gimple_seq (buffer, body, spc + 2, flags);
1347         }
1348     }
1349 }
1350
1351
1352 /* Dump a GIMPLE_OMP_TASK tuple on the pretty_printer BUFFER, SPC spaces
1353    of indent.  FLAGS specifies details to show in the dump (see TDF_* in
1354    tree-pass.h).  */
1355
1356 static void
1357 dump_gimple_omp_task (pretty_printer *buffer, gimple gs, int spc,
1358                       int flags)
1359 {
1360   if (flags & TDF_RAW)
1361     {
1362       dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
1363                        gimple_omp_body (gs));
1364       dump_omp_clauses (buffer, gimple_omp_task_clauses (gs), spc, flags);
1365       dump_gimple_fmt (buffer, spc, flags, " >, %T, %T, %T, %T, %T%n>",
1366                        gimple_omp_task_child_fn (gs),
1367                        gimple_omp_task_data_arg (gs),
1368                        gimple_omp_task_copy_fn (gs),
1369                        gimple_omp_task_arg_size (gs),
1370                        gimple_omp_task_arg_size (gs));
1371     }
1372   else
1373     {
1374       gimple_seq body;
1375       pp_string (buffer, "#pragma omp task");
1376       dump_omp_clauses (buffer, gimple_omp_task_clauses (gs), spc, flags);
1377       if (gimple_omp_task_child_fn (gs))
1378         {
1379           pp_string (buffer, " [child fn: ");
1380           dump_generic_node (buffer, gimple_omp_task_child_fn (gs),
1381                              spc, flags, false);
1382           pp_string (buffer, " (");
1383           if (gimple_omp_task_data_arg (gs))
1384             dump_generic_node (buffer, gimple_omp_task_data_arg (gs),
1385                                spc, flags, false);
1386           else
1387             pp_string (buffer, "???");
1388           pp_string (buffer, ")]");
1389         }
1390       body = gimple_omp_body (gs);
1391       if (body && gimple_code (gimple_seq_first_stmt (body)) != GIMPLE_BIND)
1392         {
1393           newline_and_indent (buffer, spc + 2);
1394           pp_character (buffer, '{');
1395           pp_newline (buffer);
1396           dump_gimple_seq (buffer, body, spc + 4, flags);
1397           newline_and_indent (buffer, spc + 2);
1398           pp_character (buffer, '}');
1399         }
1400       else if (body)
1401         {
1402           pp_newline (buffer);
1403           dump_gimple_seq (buffer, body, spc + 2, flags);
1404         }
1405     }
1406 }
1407
1408
1409 /* Dump a GIMPLE_OMP_ATOMIC_LOAD tuple on the pretty_printer BUFFER, SPC
1410    spaces of indent.  FLAGS specifies details to show in the dump (see TDF_*
1411    in tree-pass.h).  */
1412
1413 static void
1414 dump_gimple_omp_atomic_load (pretty_printer *buffer, gimple gs, int spc,
1415                              int flags)
1416 {
1417   if (flags & TDF_RAW)
1418     {
1419       dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T>", gs,
1420                        gimple_omp_atomic_load_lhs (gs),
1421                        gimple_omp_atomic_load_rhs (gs));
1422     }
1423   else
1424     {
1425       pp_string (buffer, "#pragma omp atomic_load");
1426       newline_and_indent (buffer, spc + 2);
1427       dump_generic_node (buffer, gimple_omp_atomic_load_lhs (gs),
1428                          spc, flags, false);
1429       pp_space (buffer);
1430       pp_character (buffer, '=');
1431       pp_space (buffer);
1432       pp_character (buffer, '*');
1433       dump_generic_node (buffer, gimple_omp_atomic_load_rhs (gs),
1434                          spc, flags, false);
1435     }
1436 }
1437
1438 /* Dump a GIMPLE_OMP_ATOMIC_STORE tuple on the pretty_printer BUFFER, SPC
1439    spaces of indent.  FLAGS specifies details to show in the dump (see TDF_*
1440    in tree-pass.h).  */
1441
1442 static void
1443 dump_gimple_omp_atomic_store (pretty_printer *buffer, gimple gs, int spc,
1444                              int flags)
1445 {
1446   if (flags & TDF_RAW)
1447     {
1448       dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs,
1449                        gimple_omp_atomic_store_val (gs));
1450     }
1451   else
1452     {
1453       pp_string (buffer, "#pragma omp atomic_store (");
1454       dump_generic_node (buffer, gimple_omp_atomic_store_val (gs),
1455                          spc, flags, false);
1456       pp_character (buffer, ')');
1457     }
1458 }
1459
1460
1461 /* Dump all the memory operands for statement GS.  BUFFER, SPC and
1462    FLAGS are as in dump_gimple_stmt.  */
1463
1464 static void
1465 dump_gimple_mem_ops (pretty_printer *buffer, gimple gs, int spc, int flags)
1466 {
1467   tree vdef = gimple_vdef (gs);
1468   tree vuse = gimple_vuse (gs);
1469
1470   if (!ssa_operands_active () || !gimple_references_memory_p (gs))
1471     return;
1472
1473   if (vdef != NULL_TREE)
1474     {
1475       pp_string (buffer, "# ");
1476       dump_generic_node (buffer, vdef, spc + 2, flags, false);
1477       pp_string (buffer, " = VDEF <");
1478       dump_generic_node (buffer, vuse, spc + 2, flags, false);
1479       pp_character (buffer, '>');
1480       newline_and_indent (buffer, spc);
1481     }
1482   else if (vuse != NULL_TREE)
1483     {
1484       pp_string (buffer, "# VUSE <");
1485       dump_generic_node (buffer, vuse, spc + 2, flags, false);
1486       pp_character (buffer, '>');
1487       newline_and_indent (buffer, spc);
1488     }
1489 }
1490
1491
1492 /* Dump the gimple statement GS on the pretty printer BUFFER, SPC
1493    spaces of indent.  FLAGS specifies details to show in the dump (see
1494    TDF_* in tree-pass.h).  */
1495
1496 void
1497 dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
1498 {
1499   if (!gs)
1500     return;
1501
1502   if (flags & TDF_STMTADDR)
1503     pp_printf (buffer, "<&%p> ", (void *) gs);
1504
1505   if ((flags & TDF_LINENO) && gimple_has_location (gs))
1506     {
1507       expanded_location xloc = expand_location (gimple_location (gs));
1508       pp_character (buffer, '[');
1509       if (xloc.file)
1510         {
1511           pp_string (buffer, xloc.file);
1512           pp_string (buffer, " : ");
1513         }
1514       pp_decimal_int (buffer, xloc.line);
1515       pp_string (buffer, ":");
1516       pp_decimal_int (buffer, xloc.column);
1517       pp_string (buffer, "] ");
1518     }
1519
1520   if (flags & TDF_EH)
1521     {
1522       int lp_nr = lookup_stmt_eh_lp (gs);
1523       if (lp_nr > 0)
1524         pp_printf (buffer, "[LP %d] ", lp_nr);
1525       else if (lp_nr < 0)
1526         pp_printf (buffer, "[MNT %d] ", -lp_nr);
1527     }
1528
1529   if ((flags & (TDF_VOPS|TDF_MEMSYMS))
1530       && gimple_has_mem_ops (gs))
1531     dump_gimple_mem_ops (buffer, gs, spc, flags);
1532
1533   switch (gimple_code (gs))
1534     {
1535     case GIMPLE_ASM:
1536       dump_gimple_asm (buffer, gs, spc, flags);
1537       break;
1538
1539     case GIMPLE_ASSIGN:
1540       dump_gimple_assign (buffer, gs, spc, flags);
1541       break;
1542
1543     case GIMPLE_BIND:
1544       dump_gimple_bind (buffer, gs, spc, flags);
1545       break;
1546
1547     case GIMPLE_CALL:
1548       dump_gimple_call (buffer, gs, spc, flags);
1549       break;
1550
1551     case GIMPLE_COND:
1552       dump_gimple_cond (buffer, gs, spc, flags);
1553       break;
1554
1555     case GIMPLE_LABEL:
1556       dump_gimple_label (buffer, gs, spc, flags);
1557       break;
1558
1559     case GIMPLE_GOTO:
1560       dump_gimple_goto (buffer, gs, spc, flags);
1561       break;
1562
1563     case GIMPLE_NOP:
1564       pp_string (buffer, "GIMPLE_NOP");
1565       break;
1566
1567     case GIMPLE_RETURN:
1568       dump_gimple_return (buffer, gs, spc, flags);
1569       break;
1570
1571     case GIMPLE_SWITCH:
1572       dump_gimple_switch (buffer, gs, spc, flags);
1573       break;
1574
1575     case GIMPLE_TRY:
1576       dump_gimple_try (buffer, gs, spc, flags);
1577       break;
1578
1579     case GIMPLE_PHI:
1580       dump_gimple_phi (buffer, gs, spc, flags);
1581       break;
1582
1583     case GIMPLE_OMP_PARALLEL:
1584       dump_gimple_omp_parallel (buffer, gs, spc, flags);
1585       break;
1586
1587     case GIMPLE_OMP_TASK:
1588       dump_gimple_omp_task (buffer, gs, spc, flags);
1589       break;
1590
1591     case GIMPLE_OMP_ATOMIC_LOAD:
1592       dump_gimple_omp_atomic_load (buffer, gs, spc, flags);
1593
1594       break;
1595
1596     case GIMPLE_OMP_ATOMIC_STORE:
1597       dump_gimple_omp_atomic_store (buffer, gs, spc, flags);
1598       break;
1599
1600     case GIMPLE_OMP_FOR:
1601       dump_gimple_omp_for (buffer, gs, spc, flags);
1602       break;
1603
1604     case GIMPLE_OMP_CONTINUE:
1605       dump_gimple_omp_continue (buffer, gs, spc, flags);
1606       break;
1607
1608     case GIMPLE_OMP_SINGLE:
1609       dump_gimple_omp_single (buffer, gs, spc, flags);
1610       break;
1611
1612     case GIMPLE_OMP_RETURN:
1613       dump_gimple_omp_return (buffer, gs, spc, flags);
1614       break;
1615
1616     case GIMPLE_OMP_SECTIONS:
1617       dump_gimple_omp_sections (buffer, gs, spc, flags);
1618       break;
1619
1620     case GIMPLE_OMP_SECTIONS_SWITCH:
1621       pp_string (buffer, "GIMPLE_SECTIONS_SWITCH");
1622       break;
1623
1624     case GIMPLE_OMP_MASTER:
1625     case GIMPLE_OMP_ORDERED:
1626     case GIMPLE_OMP_SECTION:
1627       dump_gimple_omp_block (buffer, gs, spc, flags);
1628       break;
1629
1630     case GIMPLE_OMP_CRITICAL:
1631       dump_gimple_omp_critical (buffer, gs, spc, flags);
1632       break;
1633
1634     case GIMPLE_CATCH:
1635       dump_gimple_catch (buffer, gs, spc, flags);
1636       break;
1637
1638     case GIMPLE_EH_FILTER:
1639       dump_gimple_eh_filter (buffer, gs, spc, flags);
1640       break;
1641
1642     case GIMPLE_EH_MUST_NOT_THROW:
1643       dump_gimple_eh_must_not_throw (buffer, gs, spc, flags);
1644       break;
1645
1646     case GIMPLE_RESX:
1647       dump_gimple_resx (buffer, gs, spc, flags);
1648       break;
1649
1650     case GIMPLE_EH_DISPATCH:
1651       dump_gimple_eh_dispatch (buffer, gs, spc, flags);
1652       break;
1653
1654     case GIMPLE_DEBUG:
1655       dump_gimple_debug (buffer, gs, spc, flags);
1656       break;
1657
1658     case GIMPLE_PREDICT:
1659       pp_string (buffer, "// predicted ");
1660       if (gimple_predict_outcome (gs))
1661         pp_string (buffer, "likely by ");
1662       else
1663         pp_string (buffer, "unlikely by ");
1664       pp_string (buffer, predictor_name (gimple_predict_predictor (gs)));
1665       pp_string (buffer, " predictor.");
1666       break;
1667
1668     default:
1669       GIMPLE_NIY;
1670     }
1671
1672   /* If we're building a diagnostic, the formatted text will be
1673      written into BUFFER's stream by the caller; otherwise, write it
1674      now.  */
1675   if (!(flags & TDF_DIAGNOSTIC))
1676     pp_write_text_to_stream (buffer);
1677 }
1678
1679
1680 /* Dumps header of basic block BB to buffer BUFFER indented by INDENT
1681    spaces and details described by flags.  */
1682
1683 static void
1684 dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
1685 {
1686   edge e;
1687   gimple stmt;
1688   edge_iterator ei;
1689
1690   if (flags & TDF_BLOCKS)
1691     {
1692       INDENT (indent);
1693       pp_string (buffer, "# BLOCK ");
1694       pp_decimal_int (buffer, bb->index);
1695       if (bb->frequency)
1696         {
1697           pp_string (buffer, " freq:");
1698           pp_decimal_int (buffer, bb->frequency);
1699         }
1700       if (bb->count)
1701         {
1702           pp_string (buffer, " count:");
1703           pp_widest_integer (buffer, bb->count);
1704         }
1705
1706       if (flags & TDF_LINENO)
1707         {
1708           gimple_stmt_iterator gsi;
1709
1710           for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1711             if (!is_gimple_debug (gsi_stmt (gsi))
1712                 && get_lineno (gsi_stmt (gsi)) != UNKNOWN_LOCATION)
1713               {
1714                 pp_string (buffer, ", starting at line ");
1715                 pp_decimal_int (buffer, get_lineno (gsi_stmt (gsi)));
1716                 break;
1717               }
1718
1719           if (bb->discriminator)
1720             {
1721               pp_string (buffer, ", discriminator ");
1722               pp_decimal_int (buffer, bb->discriminator);
1723             }
1724         }
1725       newline_and_indent (buffer, indent);
1726
1727       pp_string (buffer, "# PRED:");
1728       pp_write_text_to_stream (buffer);
1729       FOR_EACH_EDGE (e, ei, bb->preds)
1730         if (flags & TDF_SLIM)
1731           {
1732             pp_character (buffer, ' ');
1733             if (e->src == ENTRY_BLOCK_PTR)
1734               pp_string (buffer, "ENTRY");
1735             else
1736               pp_decimal_int (buffer, e->src->index);
1737           }
1738         else
1739           dump_edge_info (buffer->buffer->stream, e, 0);
1740       pp_newline (buffer);
1741     }
1742   else
1743     {
1744       stmt = first_stmt (bb);
1745       if (!stmt || gimple_code (stmt) != GIMPLE_LABEL)
1746         {
1747           INDENT (indent - 2);
1748           pp_string (buffer, "<bb ");
1749           pp_decimal_int (buffer, bb->index);
1750           pp_string (buffer, ">:");
1751           pp_newline (buffer);
1752         }
1753     }
1754   pp_write_text_to_stream (buffer);
1755   check_bb_profile (bb, buffer->buffer->stream);
1756 }
1757
1758
1759 /* Dumps end of basic block BB to buffer BUFFER indented by INDENT
1760    spaces.  */
1761
1762 static void
1763 dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
1764 {
1765   edge e;
1766   edge_iterator ei;
1767
1768   INDENT (indent);
1769   pp_string (buffer, "# SUCC:");
1770   pp_write_text_to_stream (buffer);
1771   FOR_EACH_EDGE (e, ei, bb->succs)
1772     if (flags & TDF_SLIM)
1773       {
1774         pp_character (buffer, ' ');
1775         if (e->dest == EXIT_BLOCK_PTR)
1776           pp_string (buffer, "EXIT");
1777         else
1778           pp_decimal_int (buffer, e->dest->index);
1779       }
1780     else
1781       dump_edge_info (buffer->buffer->stream, e, 1);
1782   pp_newline (buffer);
1783 }
1784
1785
1786 /* Dump PHI nodes of basic block BB to BUFFER with details described
1787    by FLAGS and indented by INDENT spaces.  */
1788
1789 static void
1790 dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
1791 {
1792   gimple_stmt_iterator i;
1793
1794   for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
1795     {
1796       gimple phi = gsi_stmt (i);
1797       if (is_gimple_reg (gimple_phi_result (phi)) || (flags & TDF_VOPS))
1798         {
1799           INDENT (indent);
1800           pp_string (buffer, "# ");
1801           dump_gimple_phi (buffer, phi, indent, flags);
1802           pp_newline (buffer);
1803         }
1804     }
1805 }
1806
1807
1808 /* Dump jump to basic block BB that is represented implicitly in the cfg
1809    to BUFFER.  */
1810
1811 static void
1812 pp_cfg_jump (pretty_printer *buffer, basic_block bb)
1813 {
1814   gimple stmt;
1815
1816   stmt = first_stmt (bb);
1817
1818   pp_string (buffer, "goto <bb ");
1819   pp_decimal_int (buffer, bb->index);
1820   pp_character (buffer, '>');
1821   if (stmt && gimple_code (stmt) == GIMPLE_LABEL)
1822     {
1823       pp_string (buffer, " (");
1824       dump_generic_node (buffer, gimple_label_label (stmt), 0, 0, false);
1825       pp_character (buffer, ')');
1826       pp_semicolon (buffer);
1827     }
1828   else
1829     pp_semicolon (buffer);
1830 }
1831
1832
1833 /* Dump edges represented implicitly in basic block BB to BUFFER, indented
1834    by INDENT spaces, with details given by FLAGS.  */
1835
1836 static void
1837 dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
1838                      int flags)
1839 {
1840   edge e;
1841   edge_iterator ei;
1842   gimple stmt;
1843
1844   stmt = last_stmt (bb);
1845
1846   if (stmt && gimple_code (stmt) == GIMPLE_COND)
1847     {
1848       edge true_edge, false_edge;
1849
1850       /* When we are emitting the code or changing CFG, it is possible that
1851          the edges are not yet created.  When we are using debug_bb in such
1852          a situation, we do not want it to crash.  */
1853       if (EDGE_COUNT (bb->succs) != 2)
1854         return;
1855       extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
1856
1857       INDENT (indent + 2);
1858       pp_cfg_jump (buffer, true_edge->dest);
1859       newline_and_indent (buffer, indent);
1860       pp_string (buffer, "else");
1861       newline_and_indent (buffer, indent + 2);
1862       pp_cfg_jump (buffer, false_edge->dest);
1863       pp_newline (buffer);
1864       return;
1865     }
1866
1867   /* If there is a fallthru edge, we may need to add an artificial
1868      goto to the dump.  */
1869   FOR_EACH_EDGE (e, ei, bb->succs)
1870     if (e->flags & EDGE_FALLTHRU)
1871       break;
1872
1873   if (e && e->dest != bb->next_bb)
1874     {
1875       INDENT (indent);
1876
1877       if ((flags & TDF_LINENO)
1878           && e->goto_locus != UNKNOWN_LOCATION
1879           )
1880         {
1881           expanded_location goto_xloc;
1882           goto_xloc = expand_location (e->goto_locus);
1883           pp_character (buffer, '[');
1884           if (goto_xloc.file)
1885             {
1886               pp_string (buffer, goto_xloc.file);
1887               pp_string (buffer, " : ");
1888             }
1889           pp_decimal_int (buffer, goto_xloc.line);
1890           pp_string (buffer, " : ");
1891           pp_decimal_int (buffer, goto_xloc.column);
1892           pp_string (buffer, "] ");
1893         }
1894
1895       pp_cfg_jump (buffer, e->dest);
1896       pp_newline (buffer);
1897     }
1898 }
1899
1900
1901 /* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
1902    indented by INDENT spaces.  */
1903
1904 static void
1905 gimple_dump_bb_buff (pretty_printer *buffer, basic_block bb, int indent,
1906                      int flags)
1907 {
1908   gimple_stmt_iterator gsi;
1909   gimple stmt;
1910   int label_indent = indent - 2;
1911
1912   if (label_indent < 0)
1913     label_indent = 0;
1914
1915   dump_bb_header (buffer, bb, indent, flags);
1916   dump_phi_nodes (buffer, bb, indent, flags);
1917
1918   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1919     {
1920       int curr_indent;
1921
1922       stmt = gsi_stmt (gsi);
1923
1924       curr_indent = gimple_code (stmt) == GIMPLE_LABEL ? label_indent : indent;
1925
1926       INDENT (curr_indent);
1927       dump_gimple_stmt (buffer, stmt, curr_indent, flags);
1928       pp_newline (buffer);
1929       dump_histograms_for_stmt (cfun, buffer->buffer->stream, stmt);
1930     }
1931
1932   dump_implicit_edges (buffer, bb, indent, flags);
1933
1934   if (flags & TDF_BLOCKS)
1935     dump_bb_end (buffer, bb, indent, flags);
1936 }
1937
1938
1939 /* Dumps basic block BB to FILE with details described by FLAGS and
1940    indented by INDENT spaces.  */
1941
1942 void
1943 gimple_dump_bb (basic_block bb, FILE *file, int indent, int flags)
1944 {
1945   maybe_init_pretty_print (file);
1946   gimple_dump_bb_buff (&buffer, bb, indent, flags);
1947   pp_flush (&buffer);
1948 }