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