Fix use-after-scope error.
[platform/upstream/gcc.git] / gcc / print-rtl.c
1 /* Print RTL for GCC.
2    Copyright (C) 1987-2017 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 /* This file is compiled twice: once for the generator programs,
21    once for the compiler.  */
22 #ifdef GENERATOR_FILE
23 #include "bconfig.h"
24 #else
25 #include "config.h"
26 #endif
27
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "rtl.h"
32
33 /* These headers all define things which are not available in
34    generator programs.  */
35 #ifndef GENERATOR_FILE
36 #include "alias.h"
37 #include "tree.h"
38 #include "basic-block.h"
39 #include "cfg.h"
40 #include "print-tree.h"
41 #include "flags.h"
42 #include "predict.h"
43 #include "function.h"
44 #include "basic-block.h"
45 #include "diagnostic.h"
46 #include "tree-pretty-print.h"
47 #include "alloc-pool.h"
48 #include "cselib.h"
49 #include "dumpfile.h"   /* for dump_flags */
50 #include "dwarf2out.h"
51 #include "pretty-print.h"
52 #endif
53
54 #include "print-rtl.h"
55 #include "rtl-iter.h"
56
57 /* String printed at beginning of each RTL when it is dumped.
58    This string is set to ASM_COMMENT_START when the RTL is dumped in
59    the assembly output file.  */
60 const char *print_rtx_head = "";
61
62 #ifdef GENERATOR_FILE
63 /* These are defined from the .opt file when not used in generator
64    programs.  */
65
66 /* Nonzero means suppress output of instruction numbers
67    in debugging dumps.
68    This must be defined here so that programs like gencodes can be linked.  */
69 int flag_dump_unnumbered = 0;
70
71 /* Nonzero means suppress output of instruction numbers for previous
72    and next insns in debugging dumps.
73    This must be defined here so that programs like gencodes can be linked.  */
74 int flag_dump_unnumbered_links = 0;
75 #endif
76
77 /* Constructor for rtx_writer.  */
78
79 rtx_writer::rtx_writer (FILE *outf, int ind, bool simple, bool compact,
80                         rtx_reuse_manager *reuse_manager)
81 : m_outfile (outf), m_sawclose (0), m_indent (ind),
82   m_in_call_function_usage (false), m_simple (simple), m_compact (compact),
83   m_rtx_reuse_manager (reuse_manager)
84 {
85 }
86
87 #ifndef GENERATOR_FILE
88
89 /* rtx_reuse_manager's ctor.  */
90
91 rtx_reuse_manager::rtx_reuse_manager ()
92 : m_next_id (0)
93 {
94 }
95
96 /* Determine if X is of a kind suitable for dumping via reuse_rtx.  */
97
98 static bool
99 uses_rtx_reuse_p (const_rtx x)
100 {
101   if (x == NULL)
102     return false;
103
104   switch (GET_CODE (x))
105     {
106     case DEBUG_EXPR:
107     case VALUE:
108     case SCRATCH:
109       return true;
110
111     /* We don't use reuse_rtx for consts.  */
112     CASE_CONST_UNIQUE:
113     default:
114       return false;
115     }
116 }
117
118 /* Traverse X and its descendents, determining if we see any rtx more than
119    once.  Any rtx suitable for "reuse_rtx" that is seen more than once is
120    assigned an ID.  */
121
122 void
123 rtx_reuse_manager::preprocess (const_rtx x)
124 {
125   subrtx_iterator::array_type array;
126   FOR_EACH_SUBRTX (iter, array, x, NONCONST)
127     if (uses_rtx_reuse_p (*iter))
128       {
129         if (int *count = m_rtx_occurrence_count.get (*iter))
130           {
131             if (*(count++) == 1)
132               m_rtx_reuse_ids.put (*iter, m_next_id++);
133           }
134         else
135           m_rtx_occurrence_count.put (*iter, 1);
136       }
137 }
138
139 /* Return true iff X has been assigned a reuse ID.  If it has,
140    and OUT is non-NULL, then write the reuse ID to *OUT.  */
141
142 bool
143 rtx_reuse_manager::has_reuse_id (const_rtx x, int *out)
144 {
145   int *id = m_rtx_reuse_ids.get (x);
146   if (id)
147     {
148       if (out)
149         *out = *id;
150       return true;
151     }
152   else
153     return false;
154 }
155
156 /* Determine if set_seen_def has been called for the given reuse ID.  */
157
158 bool
159 rtx_reuse_manager::seen_def_p (int reuse_id)
160 {
161   return bitmap_bit_p (m_defs_seen, reuse_id);
162 }
163
164 /* Record that the definition of the given reuse ID has been seen.  */
165
166 void
167 rtx_reuse_manager::set_seen_def (int reuse_id)
168 {
169   bitmap_set_bit (m_defs_seen, reuse_id);
170 }
171
172 #endif /* #ifndef GENERATOR_FILE */
173
174 #ifndef GENERATOR_FILE
175 void
176 print_mem_expr (FILE *outfile, const_tree expr)
177 {
178   fputc (' ', outfile);
179   print_generic_expr (outfile, CONST_CAST_TREE (expr), dump_flags);
180 }
181 #endif
182
183 /* Subroutine of print_rtx_operand for handling code '0'.
184    0 indicates a field for internal use that should not be printed.
185    However there are various special cases, such as the third field
186    of a NOTE, where it indicates that the field has several different
187    valid contents.  */
188
189 void
190 rtx_writer::print_rtx_operand_code_0 (const_rtx in_rtx ATTRIBUTE_UNUSED,
191                                       int idx ATTRIBUTE_UNUSED)
192 {
193 #ifndef GENERATOR_FILE
194   if (idx == 1 && GET_CODE (in_rtx) == SYMBOL_REF)
195     {
196       int flags = SYMBOL_REF_FLAGS (in_rtx);
197       if (flags)
198         fprintf (m_outfile, " [flags %#x]", flags);
199       tree decl = SYMBOL_REF_DECL (in_rtx);
200       if (decl)
201         print_node_brief (m_outfile, "", decl, dump_flags);
202     }
203   else if (idx == 3 && NOTE_P (in_rtx))
204     {
205       switch (NOTE_KIND (in_rtx))
206         {
207         case NOTE_INSN_EH_REGION_BEG:
208         case NOTE_INSN_EH_REGION_END:
209           if (flag_dump_unnumbered)
210             fprintf (m_outfile, " #");
211           else
212             fprintf (m_outfile, " %d", NOTE_EH_HANDLER (in_rtx));
213           m_sawclose = 1;
214           break;
215
216         case NOTE_INSN_BLOCK_BEG:
217         case NOTE_INSN_BLOCK_END:
218           dump_addr (m_outfile, " ", NOTE_BLOCK (in_rtx));
219           m_sawclose = 1;
220           break;
221
222         case NOTE_INSN_BASIC_BLOCK:
223           {
224             basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
225             if (bb != 0)
226               fprintf (m_outfile, " [bb %d]", bb->index);
227             break;
228           }
229
230         case NOTE_INSN_DELETED_LABEL:
231         case NOTE_INSN_DELETED_DEBUG_LABEL:
232           {
233             const char *label = NOTE_DELETED_LABEL_NAME (in_rtx);
234             if (label)
235               fprintf (m_outfile, " (\"%s\")", label);
236             else
237               fprintf (m_outfile, " \"\"");
238           }
239           break;
240
241         case NOTE_INSN_SWITCH_TEXT_SECTIONS:
242           {
243             basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
244             if (bb != 0)
245               fprintf (m_outfile, " [bb %d]", bb->index);
246             break;
247           }
248
249         case NOTE_INSN_VAR_LOCATION:
250         case NOTE_INSN_CALL_ARG_LOCATION:
251           fputc (' ', m_outfile);
252           print_rtx (NOTE_VAR_LOCATION (in_rtx));
253           break;
254
255         case NOTE_INSN_CFI:
256           fputc ('\n', m_outfile);
257           output_cfi_directive (m_outfile, NOTE_CFI (in_rtx));
258           fputc ('\t', m_outfile);
259           break;
260
261         default:
262           break;
263         }
264     }
265   else if (idx == 7 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL
266            && !m_compact)
267     {
268       /* Output the JUMP_LABEL reference.  */
269       fprintf (m_outfile, "\n%s%*s -> ", print_rtx_head, m_indent * 2, "");
270       if (GET_CODE (JUMP_LABEL (in_rtx)) == RETURN)
271         fprintf (m_outfile, "return");
272       else if (GET_CODE (JUMP_LABEL (in_rtx)) == SIMPLE_RETURN)
273         fprintf (m_outfile, "simple_return");
274       else
275         fprintf (m_outfile, "%d", INSN_UID (JUMP_LABEL (in_rtx)));
276     }
277   else if (idx == 0 && GET_CODE (in_rtx) == VALUE)
278     {
279       cselib_val *val = CSELIB_VAL_PTR (in_rtx);
280
281       fprintf (m_outfile, " %u:%u", val->uid, val->hash);
282       dump_addr (m_outfile, " @", in_rtx);
283       dump_addr (m_outfile, "/", (void*)val);
284     }
285   else if (idx == 0 && GET_CODE (in_rtx) == DEBUG_EXPR)
286     {
287       fprintf (m_outfile, " D#%i",
288                DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (in_rtx)));
289     }
290   else if (idx == 0 && GET_CODE (in_rtx) == ENTRY_VALUE)
291     {
292       m_indent += 2;
293       if (!m_sawclose)
294         fprintf (m_outfile, " ");
295       print_rtx (ENTRY_VALUE_EXP (in_rtx));
296       m_indent -= 2;
297     }
298 #endif
299 }
300
301 /* Subroutine of print_rtx_operand for handling code 'e'.
302    Also called by print_rtx_operand_code_u for handling code 'u'
303    for LABEL_REFs when they don't reference a CODE_LABEL.  */
304
305 void
306 rtx_writer::print_rtx_operand_code_e (const_rtx in_rtx, int idx)
307 {
308   m_indent += 2;
309   if (idx == 6 && INSN_P (in_rtx))
310     /* Put REG_NOTES on their own line.  */
311     fprintf (m_outfile, "\n%s%*s",
312              print_rtx_head, m_indent * 2, "");
313   if (!m_sawclose)
314     fprintf (m_outfile, " ");
315   if (idx == 7 && CALL_P (in_rtx))
316     {
317       m_in_call_function_usage = true;
318       print_rtx (XEXP (in_rtx, idx));
319       m_in_call_function_usage = false;
320     }
321   else
322     print_rtx (XEXP (in_rtx, idx));
323   m_indent -= 2;
324 }
325
326 /* Subroutine of print_rtx_operand for handling codes 'E' and 'V'.  */
327
328 void
329 rtx_writer::print_rtx_operand_codes_E_and_V (const_rtx in_rtx, int idx)
330 {
331   m_indent += 2;
332   if (m_sawclose)
333     {
334       fprintf (m_outfile, "\n%s%*s",
335       print_rtx_head, m_indent * 2, "");
336       m_sawclose = 0;
337     }
338   fputs (" [", m_outfile);
339   if (NULL != XVEC (in_rtx, idx))
340     {
341       m_indent += 2;
342       if (XVECLEN (in_rtx, idx))
343         m_sawclose = 1;
344
345       for (int j = 0; j < XVECLEN (in_rtx, idx); j++)
346         print_rtx (XVECEXP (in_rtx, idx, j));
347
348       m_indent -= 2;
349     }
350   if (m_sawclose)
351     fprintf (m_outfile, "\n%s%*s", print_rtx_head, m_indent * 2, "");
352
353   fputs ("]", m_outfile);
354   m_sawclose = 1;
355   m_indent -= 2;
356 }
357
358 /* Subroutine of print_rtx_operand for handling code 'i'.  */
359
360 void
361 rtx_writer::print_rtx_operand_code_i (const_rtx in_rtx, int idx)
362 {
363   if (idx == 4 && INSN_P (in_rtx))
364     {
365 #ifndef GENERATOR_FILE
366       const rtx_insn *in_insn = as_a <const rtx_insn *> (in_rtx);
367
368       /*  Pretty-print insn locations.  Ignore scoping as it is mostly
369           redundant with line number information and do not print anything
370           when there is no location information available.  */
371       if (INSN_HAS_LOCATION (in_insn))
372         {
373           expanded_location xloc = insn_location (in_insn);
374           fprintf (m_outfile, " \"%s\":%i", xloc.file, xloc.line);
375         }
376 #endif
377     }
378   else if (idx == 6 && GET_CODE (in_rtx) == ASM_OPERANDS)
379     {
380 #ifndef GENERATOR_FILE
381       if (ASM_OPERANDS_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
382         fprintf (m_outfile, " %s:%i",
383                  LOCATION_FILE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
384                  LOCATION_LINE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
385 #endif
386     }
387   else if (idx == 1 && GET_CODE (in_rtx) == ASM_INPUT)
388     {
389 #ifndef GENERATOR_FILE
390       if (ASM_INPUT_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
391         fprintf (m_outfile, " %s:%i",
392                  LOCATION_FILE (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
393                  LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
394 #endif
395     }
396   else if (idx == 5 && NOTE_P (in_rtx))
397     {
398       /* This field is only used for NOTE_INSN_DELETED_LABEL, and
399          other times often contains garbage from INSN->NOTE death.  */
400       if (NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_LABEL
401           || NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_DEBUG_LABEL)
402         fprintf (m_outfile, " %d",  XINT (in_rtx, idx));
403     }
404 #if !defined(GENERATOR_FILE) && NUM_UNSPECV_VALUES > 0
405   else if (idx == 1
406            && GET_CODE (in_rtx) == UNSPEC_VOLATILE
407            && XINT (in_rtx, 1) >= 0
408            && XINT (in_rtx, 1) < NUM_UNSPECV_VALUES)
409     fprintf (m_outfile, " %s", unspecv_strings[XINT (in_rtx, 1)]);
410 #endif
411 #if !defined(GENERATOR_FILE) && NUM_UNSPEC_VALUES > 0
412   else if (idx == 1
413            && (GET_CODE (in_rtx) == UNSPEC
414                || GET_CODE (in_rtx) == UNSPEC_VOLATILE)
415            && XINT (in_rtx, 1) >= 0
416            && XINT (in_rtx, 1) < NUM_UNSPEC_VALUES)
417     fprintf (m_outfile, " %s", unspec_strings[XINT (in_rtx, 1)]);
418 #endif
419   else
420     {
421       int value = XINT (in_rtx, idx);
422       const char *name;
423       int is_insn = INSN_P (in_rtx);
424
425       /* Don't print INSN_CODEs in compact mode.  */
426       if (m_compact && is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, idx))
427         {
428           m_sawclose = 0;
429           return;
430         }
431
432       if (flag_dump_unnumbered
433           && (is_insn || NOTE_P (in_rtx)))
434         fputc ('#', m_outfile);
435       else
436         fprintf (m_outfile, " %d", value);
437
438       if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, idx)
439           && XINT (in_rtx, idx) >= 0
440           && (name = get_insn_name (XINT (in_rtx, idx))) != NULL)
441         fprintf (m_outfile, " {%s}", name);
442       m_sawclose = 0;
443     }
444 }
445
446 /* Subroutine of print_rtx_operand for handling code 'r'.  */
447
448 void
449 rtx_writer::print_rtx_operand_code_r (const_rtx in_rtx)
450 {
451   int is_insn = INSN_P (in_rtx);
452   unsigned int regno = REGNO (in_rtx);
453
454 #ifndef GENERATOR_FILE
455   /* For hard registers and virtuals, always print the
456      regno, except in compact mode.  */
457   if (regno <= LAST_VIRTUAL_REGISTER && !m_compact)
458     fprintf (m_outfile, " %d", regno);
459   if (regno < FIRST_PSEUDO_REGISTER)
460     fprintf (m_outfile, " %s", reg_names[regno]);
461   else if (regno <= LAST_VIRTUAL_REGISTER)
462     {
463       if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
464         fprintf (m_outfile, " virtual-incoming-args");
465       else if (regno == VIRTUAL_STACK_VARS_REGNUM)
466         fprintf (m_outfile, " virtual-stack-vars");
467       else if (regno == VIRTUAL_STACK_DYNAMIC_REGNUM)
468         fprintf (m_outfile, " virtual-stack-dynamic");
469       else if (regno == VIRTUAL_OUTGOING_ARGS_REGNUM)
470         fprintf (m_outfile, " virtual-outgoing-args");
471       else if (regno == VIRTUAL_CFA_REGNUM)
472         fprintf (m_outfile, " virtual-cfa");
473       else if (regno == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
474         fprintf (m_outfile, " virtual-preferred-stack-boundary");
475       else
476         fprintf (m_outfile, " virtual-reg-%d", regno-FIRST_VIRTUAL_REGISTER);
477     }
478   else
479 #endif
480     if (flag_dump_unnumbered && is_insn)
481       fputc ('#', m_outfile);
482     else if (m_compact)
483       {
484         /* In compact mode, print pseudos with '< and '>' wrapping the regno,
485            offseting it by (LAST_VIRTUAL_REGISTER + 1), so that the
486            first non-virtual pseudo is dumped as "<0>".  */
487         gcc_assert (regno > LAST_VIRTUAL_REGISTER);
488         fprintf (m_outfile, " <%d>", regno - (LAST_VIRTUAL_REGISTER + 1));
489       }
490     else
491       fprintf (m_outfile, " %d", regno);
492
493 #ifndef GENERATOR_FILE
494   if (REG_ATTRS (in_rtx))
495     {
496       fputs (" [", m_outfile);
497       if (regno != ORIGINAL_REGNO (in_rtx))
498         fprintf (m_outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
499       if (REG_EXPR (in_rtx))
500         print_mem_expr (m_outfile, REG_EXPR (in_rtx));
501
502       if (REG_OFFSET (in_rtx))
503         fprintf (m_outfile, "+" HOST_WIDE_INT_PRINT_DEC,
504                  REG_OFFSET (in_rtx));
505       fputs (" ]", m_outfile);
506     }
507   if (regno != ORIGINAL_REGNO (in_rtx))
508     fprintf (m_outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
509 #endif
510 }
511
512 /* Subroutine of print_rtx_operand for handling code 'u'.  */
513
514 void
515 rtx_writer::print_rtx_operand_code_u (const_rtx in_rtx, int idx)
516 {
517   /* Don't print insn UIDs for PREV/NEXT_INSN in compact mode.  */
518   if (m_compact && INSN_CHAIN_CODE_P (GET_CODE (in_rtx)) && idx < 2)
519     return;
520
521   if (XEXP (in_rtx, idx) != NULL)
522     {
523       rtx sub = XEXP (in_rtx, idx);
524       enum rtx_code subc = GET_CODE (sub);
525
526       if (GET_CODE (in_rtx) == LABEL_REF)
527         {
528           if (subc == NOTE
529               && NOTE_KIND (sub) == NOTE_INSN_DELETED_LABEL)
530             {
531               if (flag_dump_unnumbered)
532                 fprintf (m_outfile, " [# deleted]");
533               else
534                 fprintf (m_outfile, " [%d deleted]", INSN_UID (sub));
535               m_sawclose = 0;
536               return;
537             }
538
539           if (subc != CODE_LABEL)
540             {
541               print_rtx_operand_code_e (in_rtx, idx);
542               return;
543             }
544         }
545
546       if (flag_dump_unnumbered
547           || (flag_dump_unnumbered_links && idx <= 1
548               && (INSN_P (in_rtx) || NOTE_P (in_rtx)
549                   || LABEL_P (in_rtx) || BARRIER_P (in_rtx))))
550         fputs (" #", m_outfile);
551       else
552         fprintf (m_outfile, " %d", INSN_UID (sub));
553     }
554   else
555     fputs (" 0", m_outfile);
556   m_sawclose = 0;
557 }
558
559 /* Subroutine of print_rtx.   Print operand IDX of IN_RTX.  */
560
561 void
562 rtx_writer::print_rtx_operand (const_rtx in_rtx, int idx)
563 {
564   const char *format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
565
566   switch (format_ptr[idx])
567     {
568       const char *str;
569
570     case 'T':
571       str = XTMPL (in_rtx, idx);
572       goto string;
573
574     case 'S':
575     case 's':
576       str = XSTR (in_rtx, idx);
577     string:
578
579       if (str == 0)
580         fputs (" (nil)", m_outfile);
581       else
582         fprintf (m_outfile, " (\"%s\")", str);
583       m_sawclose = 1;
584       break;
585
586     case '0':
587       print_rtx_operand_code_0 (in_rtx, idx);
588       break;
589
590     case 'e':
591       print_rtx_operand_code_e (in_rtx, idx);
592       break;
593
594     case 'E':
595     case 'V':
596       print_rtx_operand_codes_E_and_V (in_rtx, idx);
597       break;
598
599     case 'w':
600       if (! m_simple)
601         fprintf (m_outfile, " ");
602       fprintf (m_outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, idx));
603       if (! m_simple && !m_compact)
604         fprintf (m_outfile, " [" HOST_WIDE_INT_PRINT_HEX "]",
605                  (unsigned HOST_WIDE_INT) XWINT (in_rtx, idx));
606       break;
607
608     case 'i':
609       print_rtx_operand_code_i (in_rtx, idx);
610       break;
611
612     case 'r':
613       print_rtx_operand_code_r (in_rtx);
614       break;
615
616     /* Print NOTE_INSN names rather than integer codes.  */
617
618     case 'n':
619       fprintf (m_outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, idx)));
620       m_sawclose = 0;
621       break;
622
623     case 'u':
624       print_rtx_operand_code_u (in_rtx, idx);
625       break;
626
627     case 't':
628 #ifndef GENERATOR_FILE
629       if (idx == 0 && GET_CODE (in_rtx) == DEBUG_IMPLICIT_PTR)
630         print_mem_expr (m_outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx));
631       else if (idx == 0 && GET_CODE (in_rtx) == DEBUG_PARAMETER_REF)
632         print_mem_expr (m_outfile, DEBUG_PARAMETER_REF_DECL (in_rtx));
633       else
634         dump_addr (m_outfile, " ", XTREE (in_rtx, idx));
635 #endif
636       break;
637
638     case '*':
639       fputs (" Unknown", m_outfile);
640       m_sawclose = 0;
641       break;
642
643     case 'B':
644       /* Don't print basic block ids in compact mode.  */
645       if (m_compact)
646         break;
647 #ifndef GENERATOR_FILE
648       if (XBBDEF (in_rtx, idx))
649         fprintf (m_outfile, " %i", XBBDEF (in_rtx, idx)->index);
650 #endif
651       break;
652
653     default:
654       gcc_unreachable ();
655     }
656 }
657
658 /* Subroutine of rtx_writer::print_rtx.
659    In compact mode, determine if operand IDX of IN_RTX is interesting
660    to dump, or (if in a trailing position) it can be omitted.  */
661
662 bool
663 rtx_writer::operand_has_default_value_p (const_rtx in_rtx, int idx)
664 {
665   const char *format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
666
667   switch (format_ptr[idx])
668     {
669     case 'e':
670     case 'u':
671       return XEXP (in_rtx, idx) == NULL_RTX;
672
673     case 's':
674       return XSTR (in_rtx, idx) == NULL;
675
676     case '0':
677       switch (GET_CODE (in_rtx))
678         {
679         case JUMP_INSN:
680           /* JUMP_LABELs are always omitted in compact mode, so treat
681              any value here as omittable, so that earlier operands can
682              potentially be omitted also.  */
683           return m_compact;
684
685         default:
686           return false;
687
688         }
689
690     default:
691       return false;
692     }
693 }
694
695 /* Print IN_RTX onto m_outfile.  This is the recursive part of printing.  */
696
697 void
698 rtx_writer::print_rtx (const_rtx in_rtx)
699 {
700   int idx = 0;
701
702   if (m_sawclose)
703     {
704       if (m_simple)
705         fputc (' ', m_outfile);
706       else
707         fprintf (m_outfile, "\n%s%*s", print_rtx_head, m_indent * 2, "");
708       m_sawclose = 0;
709     }
710
711   if (in_rtx == 0)
712     {
713       fputs ("(nil)", m_outfile);
714       m_sawclose = 1;
715       return;
716     }
717   else if (GET_CODE (in_rtx) > NUM_RTX_CODE)
718     {
719        fprintf (m_outfile, "(??? bad code %d\n%s%*s)", GET_CODE (in_rtx),
720                 print_rtx_head, m_indent * 2, "");
721        m_sawclose = 1;
722        return;
723     }
724
725   fputc ('(', m_outfile);
726
727   /* Print name of expression code.  */
728
729   /* Handle reuse.  */
730 #ifndef GENERATOR_FILE
731   if (m_rtx_reuse_manager)
732     {
733       int reuse_id;
734       if (m_rtx_reuse_manager->has_reuse_id (in_rtx, &reuse_id))
735         {
736           /* Have we already seen the defn of this rtx?  */
737           if (m_rtx_reuse_manager->seen_def_p (reuse_id))
738             {
739               fprintf (m_outfile, "reuse_rtx %i)", reuse_id);
740               m_sawclose = 1;
741               return;
742             }
743           else
744             {
745               /* First time we've seen this reused-rtx.  */
746               fprintf (m_outfile, "%i|", reuse_id);
747               m_rtx_reuse_manager->set_seen_def (reuse_id);
748             }
749         }
750     }
751 #endif /* #ifndef GENERATOR_FILE */
752
753   /* In compact mode, prefix the code of insns with "c",
754      giving "cinsn", "cnote" etc.  */
755   if (m_compact && is_a <const rtx_insn *, const struct rtx_def> (in_rtx))
756     {
757       /* "ccode_label" is slightly awkward, so special-case it as
758          just "clabel".  */
759       rtx_code code = GET_CODE (in_rtx);
760       if (code == CODE_LABEL)
761         fprintf (m_outfile, "clabel");
762       else
763         fprintf (m_outfile, "c%s", GET_RTX_NAME (code));
764     }
765   else if (m_simple && CONST_INT_P (in_rtx))
766     ; /* no code.  */
767   else
768     fprintf (m_outfile, "%s", GET_RTX_NAME (GET_CODE (in_rtx)));
769
770   if (! m_simple)
771     {
772       if (RTX_FLAG (in_rtx, in_struct))
773         fputs ("/s", m_outfile);
774
775       if (RTX_FLAG (in_rtx, volatil))
776         fputs ("/v", m_outfile);
777
778       if (RTX_FLAG (in_rtx, unchanging))
779         fputs ("/u", m_outfile);
780
781       if (RTX_FLAG (in_rtx, frame_related))
782         fputs ("/f", m_outfile);
783
784       if (RTX_FLAG (in_rtx, jump))
785         fputs ("/j", m_outfile);
786
787       if (RTX_FLAG (in_rtx, call))
788         fputs ("/c", m_outfile);
789
790       if (RTX_FLAG (in_rtx, return_val))
791         fputs ("/i", m_outfile);
792
793       /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */
794       if ((GET_CODE (in_rtx) == EXPR_LIST
795            || GET_CODE (in_rtx) == INSN_LIST
796            || GET_CODE (in_rtx) == INT_LIST)
797           && (int)GET_MODE (in_rtx) < REG_NOTE_MAX
798           && !m_in_call_function_usage)
799         fprintf (m_outfile, ":%s",
800                  GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
801
802       /* For other rtl, print the mode if it's not VOID.  */
803       else if (GET_MODE (in_rtx) != VOIDmode)
804         fprintf (m_outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
805
806 #ifndef GENERATOR_FILE
807       if (GET_CODE (in_rtx) == VAR_LOCATION)
808         {
809           if (TREE_CODE (PAT_VAR_LOCATION_DECL (in_rtx)) == STRING_CST)
810             fputs (" <debug string placeholder>", m_outfile);
811           else
812             print_mem_expr (m_outfile, PAT_VAR_LOCATION_DECL (in_rtx));
813           fputc (' ', m_outfile);
814           print_rtx (PAT_VAR_LOCATION_LOC (in_rtx));
815           if (PAT_VAR_LOCATION_STATUS (in_rtx)
816               == VAR_INIT_STATUS_UNINITIALIZED)
817             fprintf (m_outfile, " [uninit]");
818           m_sawclose = 1;
819           idx = GET_RTX_LENGTH (VAR_LOCATION);
820         }
821 #endif
822     }
823
824 #ifndef GENERATOR_FILE
825   if (CONST_DOUBLE_AS_FLOAT_P (in_rtx))
826     idx = 5;
827 #endif
828
829   /* For insns, print the INSN_UID.  */
830   if (INSN_CHAIN_CODE_P (GET_CODE (in_rtx)))
831     {
832       if (flag_dump_unnumbered)
833         fprintf (m_outfile, " #");
834       else
835         fprintf (m_outfile, " %d", INSN_UID (in_rtx));
836     }
837
838   /* Determine which is the final operand to print.
839      In compact mode, skip trailing operands that have the default values
840      e.g. trailing "(nil)" values.  */
841   int limit = GET_RTX_LENGTH (GET_CODE (in_rtx));
842   if (m_compact)
843     while (limit > idx && operand_has_default_value_p (in_rtx, limit - 1))
844       limit--;
845
846   /* Get the format string and skip the first elements if we have handled
847      them already.  */
848
849   for (; idx < limit; idx++)
850     print_rtx_operand (in_rtx, idx);
851
852   switch (GET_CODE (in_rtx))
853     {
854 #ifndef GENERATOR_FILE
855     case MEM:
856       if (__builtin_expect (final_insns_dump_p, false))
857         fprintf (m_outfile, " [");
858       else
859         fprintf (m_outfile, " [" HOST_WIDE_INT_PRINT_DEC,
860                  (HOST_WIDE_INT) MEM_ALIAS_SET (in_rtx));
861
862       if (MEM_EXPR (in_rtx))
863         print_mem_expr (m_outfile, MEM_EXPR (in_rtx));
864       else
865         fputc (' ', m_outfile);
866
867       if (MEM_OFFSET_KNOWN_P (in_rtx))
868         fprintf (m_outfile, "+" HOST_WIDE_INT_PRINT_DEC, MEM_OFFSET (in_rtx));
869
870       if (MEM_SIZE_KNOWN_P (in_rtx))
871         fprintf (m_outfile, " S" HOST_WIDE_INT_PRINT_DEC, MEM_SIZE (in_rtx));
872
873       if (MEM_ALIGN (in_rtx) != 1)
874         fprintf (m_outfile, " A%u", MEM_ALIGN (in_rtx));
875
876       if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (in_rtx)))
877         fprintf (m_outfile, " AS%u", MEM_ADDR_SPACE (in_rtx));
878
879       fputc (']', m_outfile);
880       break;
881
882     case CONST_DOUBLE:
883       if (FLOAT_MODE_P (GET_MODE (in_rtx)))
884         {
885           char s[60];
886
887           real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
888                            sizeof (s), 0, 1);
889           fprintf (m_outfile, " %s", s);
890
891           real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
892                                sizeof (s), 0, 1);
893           fprintf (m_outfile, " [%s]", s);
894         }
895       break;
896
897     case CONST_WIDE_INT:
898       fprintf (m_outfile, " ");
899       cwi_output_hex (m_outfile, in_rtx);
900       break;
901 #endif
902
903     case CODE_LABEL:
904       if (!m_compact)
905         fprintf (m_outfile, " [%d uses]", LABEL_NUSES (in_rtx));
906       switch (LABEL_KIND (in_rtx))
907         {
908           case LABEL_NORMAL: break;
909           case LABEL_STATIC_ENTRY: fputs (" [entry]", m_outfile); break;
910           case LABEL_GLOBAL_ENTRY: fputs (" [global entry]", m_outfile); break;
911           case LABEL_WEAK_ENTRY: fputs (" [weak entry]", m_outfile); break;
912           default: gcc_unreachable ();
913         }
914       break;
915
916     default:
917       break;
918     }
919
920   fputc (')', m_outfile);
921   m_sawclose = 1;
922 }
923
924 /* Emit a closing parenthesis and newline.  */
925
926 void
927 rtx_writer::finish_directive ()
928 {
929   fprintf (m_outfile, ")\n");
930   m_sawclose = 0;
931 }
932
933 /* Print an rtx on the current line of FILE.  Initially indent IND
934    characters.  */
935
936 void
937 print_inline_rtx (FILE *outf, const_rtx x, int ind)
938 {
939   rtx_writer w (outf, ind, false, false, NULL);
940   w.print_rtx (x);
941 }
942
943 /* Call this function from the debugger to see what X looks like.  */
944
945 DEBUG_FUNCTION void
946 debug_rtx (const_rtx x)
947 {
948   rtx_writer w (stderr, 0, false, false, NULL);
949   w.print_rtx (x);
950   fprintf (stderr, "\n");
951 }
952
953 /* Dump rtx REF.  */
954
955 DEBUG_FUNCTION void
956 debug (const rtx_def &ref)
957 {
958   debug_rtx (&ref);
959 }
960
961 DEBUG_FUNCTION void
962 debug (const rtx_def *ptr)
963 {
964   if (ptr)
965     debug (*ptr);
966   else
967     fprintf (stderr, "<nil>\n");
968 }
969
970 /* Count of rtx's to print with debug_rtx_list.
971    This global exists because gdb user defined commands have no arguments.  */
972
973 DEBUG_VARIABLE int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */
974
975 /* Call this function to print list from X on.
976
977    N is a count of the rtx's to print. Positive values print from the specified
978    rtx_insn on.  Negative values print a window around the rtx_insn.
979    EG: -5 prints 2 rtx_insn's on either side (in addition to the specified
980    rtx_insn).  */
981
982 DEBUG_FUNCTION void
983 debug_rtx_list (const rtx_insn *x, int n)
984 {
985   int i,count;
986   const rtx_insn *insn;
987
988   count = n == 0 ? 1 : n < 0 ? -n : n;
989
990   /* If we are printing a window, back up to the start.  */
991
992   if (n < 0)
993     for (i = count / 2; i > 0; i--)
994       {
995         if (PREV_INSN (x) == 0)
996           break;
997         x = PREV_INSN (x);
998       }
999
1000   for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
1001     {
1002       debug_rtx (insn);
1003       fprintf (stderr, "\n");
1004     }
1005 }
1006
1007 /* Call this function to print an rtx_insn list from START to END
1008    inclusive.  */
1009
1010 DEBUG_FUNCTION void
1011 debug_rtx_range (const rtx_insn *start, const rtx_insn *end)
1012 {
1013   while (1)
1014     {
1015       debug_rtx (start);
1016       fprintf (stderr, "\n");
1017       if (!start || start == end)
1018         break;
1019       start = NEXT_INSN (start);
1020     }
1021 }
1022
1023 /* Call this function to search an rtx_insn list to find one with insn uid UID,
1024    and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
1025    The found insn is returned to enable further debugging analysis.  */
1026
1027 DEBUG_FUNCTION const rtx_insn *
1028 debug_rtx_find (const rtx_insn *x, int uid)
1029 {
1030   while (x != 0 && INSN_UID (x) != uid)
1031     x = NEXT_INSN (x);
1032   if (x != 0)
1033     {
1034       debug_rtx_list (x, debug_rtx_count);
1035       return x;
1036     }
1037   else
1038     {
1039       fprintf (stderr, "insn uid %d not found\n", uid);
1040       return 0;
1041     }
1042 }
1043
1044 /* External entry point for printing a chain of insns
1045    starting with RTX_FIRST.
1046    A blank line separates insns.
1047
1048    If RTX_FIRST is not an insn, then it alone is printed, with no newline.  */
1049
1050 void
1051 rtx_writer::print_rtl (const_rtx rtx_first)
1052 {
1053   const rtx_insn *tmp_rtx;
1054
1055   if (rtx_first == 0)
1056     {
1057       fputs (print_rtx_head, m_outfile);
1058       fputs ("(nil)\n", m_outfile);
1059     }
1060   else
1061     switch (GET_CODE (rtx_first))
1062       {
1063       case INSN:
1064       case JUMP_INSN:
1065       case CALL_INSN:
1066       case NOTE:
1067       case CODE_LABEL:
1068       case JUMP_TABLE_DATA:
1069       case BARRIER:
1070         for (tmp_rtx = as_a <const rtx_insn *> (rtx_first);
1071              tmp_rtx != 0;
1072              tmp_rtx = NEXT_INSN (tmp_rtx))
1073           {
1074             fputs (print_rtx_head, m_outfile);
1075             print_rtx (tmp_rtx);
1076             fprintf (m_outfile, "\n");
1077           }
1078         break;
1079
1080       default:
1081         fputs (print_rtx_head, m_outfile);
1082         print_rtx (rtx_first);
1083       }
1084 }
1085
1086 /* External entry point for printing a chain of insns
1087    starting with RTX_FIRST onto file OUTF.
1088    A blank line separates insns.
1089
1090    If RTX_FIRST is not an insn, then it alone is printed, with no newline.  */
1091
1092 void
1093 print_rtl (FILE *outf, const_rtx rtx_first)
1094 {
1095   rtx_writer w (outf, 0, false, false, NULL);
1096   w.print_rtl (rtx_first);
1097 }
1098
1099 /* Like print_rtx, except specify a file.  */
1100 /* Return nonzero if we actually printed anything.  */
1101
1102 int
1103 print_rtl_single (FILE *outf, const_rtx x)
1104 {
1105   rtx_writer w (outf, 0, false, false, NULL);
1106   return w.print_rtl_single_with_indent (x, 0);
1107 }
1108
1109 /* Like print_rtl_single, except specify an indentation.  */
1110
1111 int
1112 rtx_writer::print_rtl_single_with_indent (const_rtx x, int ind)
1113 {
1114   char *s_indent = (char *) alloca ((size_t) ind + 1);
1115   memset ((void *) s_indent, ' ', (size_t) ind);
1116   s_indent[ind] = '\0';
1117   fputs (s_indent, m_outfile);
1118   fputs (print_rtx_head, m_outfile);
1119
1120   int old_indent = m_indent;
1121   m_indent = ind;
1122   m_sawclose = 0;
1123   print_rtx (x);
1124   putc ('\n', m_outfile);
1125   m_indent = old_indent;
1126   return 1;
1127 }
1128
1129
1130 /* Like print_rtl except without all the detail; for example,
1131    if RTX is a CONST_INT then print in decimal format.  */
1132
1133 void
1134 print_simple_rtl (FILE *outf, const_rtx x)
1135 {
1136   rtx_writer w (outf, 0, true, false, NULL);
1137   w.print_rtl (x);
1138 }
1139
1140 /* Print the elements of VEC to FILE.  */
1141
1142 void
1143 print_rtx_insn_vec (FILE *file, const vec<rtx_insn *> &vec)
1144 {
1145   fputc('{', file);
1146
1147   unsigned int len = vec.length ();
1148   for (unsigned int i = 0; i < len; i++)
1149     {
1150       print_rtl (file, vec[i]);
1151       if (i < len - 1)
1152         fputs (", ", file);
1153     }
1154
1155   fputc ('}', file);
1156 }
1157
1158 #ifndef GENERATOR_FILE
1159 /* The functions below  try to print RTL in a form resembling assembler
1160    mnemonics.  Because this form is more concise than the "traditional" form
1161    of RTL printing in Lisp-style, the form printed by this file is called
1162    "slim".  RTL dumps in slim format can be obtained by appending the "-slim"
1163    option to -fdump-rtl-<pass>.  Control flow graph output as a DOT file is
1164    always printed in slim form.
1165
1166    The normal interface to the functionality provided in this pretty-printer
1167    is through the dump_*_slim functions to print to a stream, or via the
1168    print_*_slim functions to print into a user's pretty-printer.
1169
1170    It is also possible to obtain a string for a single pattern as a string
1171    pointer, via str_pattern_slim, but this usage is discouraged.  */
1172
1173 /* For insns we print patterns, and for some patterns we print insns...  */
1174 static void print_insn_with_notes (pretty_printer *, const rtx_insn *);
1175
1176 /* This recognizes rtx'en classified as expressions.  These are always
1177    represent some action on values or results of other expression, that
1178    may be stored in objects representing values.  */
1179
1180 static void
1181 print_exp (pretty_printer *pp, const_rtx x, int verbose)
1182 {
1183   const char *st[4];
1184   const char *fun;
1185   rtx op[4];
1186   int i;
1187
1188   fun = (char *) 0;
1189   for (i = 0; i < 4; i++)
1190     {
1191       st[i] = (char *) 0;
1192       op[i] = NULL_RTX;
1193     }
1194
1195   switch (GET_CODE (x))
1196     {
1197     case PLUS:
1198       op[0] = XEXP (x, 0);
1199       if (CONST_INT_P (XEXP (x, 1))
1200           && INTVAL (XEXP (x, 1)) < 0)
1201         {
1202           st[1] = "-";
1203           op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
1204         }
1205       else
1206         {
1207           st[1] = "+";
1208           op[1] = XEXP (x, 1);
1209         }
1210       break;
1211     case LO_SUM:
1212       op[0] = XEXP (x, 0);
1213       st[1] = "+low(";
1214       op[1] = XEXP (x, 1);
1215       st[2] = ")";
1216       break;
1217     case MINUS:
1218       op[0] = XEXP (x, 0);
1219       st[1] = "-";
1220       op[1] = XEXP (x, 1);
1221       break;
1222     case COMPARE:
1223       fun = "cmp";
1224       op[0] = XEXP (x, 0);
1225       op[1] = XEXP (x, 1);
1226       break;
1227     case NEG:
1228       st[0] = "-";
1229       op[0] = XEXP (x, 0);
1230       break;
1231     case FMA:
1232       st[0] = "{";
1233       op[0] = XEXP (x, 0);
1234       st[1] = "*";
1235       op[1] = XEXP (x, 1);
1236       st[2] = "+";
1237       op[2] = XEXP (x, 2);
1238       st[3] = "}";
1239       break;
1240     case MULT:
1241       op[0] = XEXP (x, 0);
1242       st[1] = "*";
1243       op[1] = XEXP (x, 1);
1244       break;
1245     case DIV:
1246       op[0] = XEXP (x, 0);
1247       st[1] = "/";
1248       op[1] = XEXP (x, 1);
1249       break;
1250     case UDIV:
1251       fun = "udiv";
1252       op[0] = XEXP (x, 0);
1253       op[1] = XEXP (x, 1);
1254       break;
1255     case MOD:
1256       op[0] = XEXP (x, 0);
1257       st[1] = "%";
1258       op[1] = XEXP (x, 1);
1259       break;
1260     case UMOD:
1261       fun = "umod";
1262       op[0] = XEXP (x, 0);
1263       op[1] = XEXP (x, 1);
1264       break;
1265     case SMIN:
1266       fun = "smin";
1267       op[0] = XEXP (x, 0);
1268       op[1] = XEXP (x, 1);
1269       break;
1270     case SMAX:
1271       fun = "smax";
1272       op[0] = XEXP (x, 0);
1273       op[1] = XEXP (x, 1);
1274       break;
1275     case UMIN:
1276       fun = "umin";
1277       op[0] = XEXP (x, 0);
1278       op[1] = XEXP (x, 1);
1279       break;
1280     case UMAX:
1281       fun = "umax";
1282       op[0] = XEXP (x, 0);
1283       op[1] = XEXP (x, 1);
1284       break;
1285     case NOT:
1286       st[0] = "~";
1287       op[0] = XEXP (x, 0);
1288       break;
1289     case AND:
1290       op[0] = XEXP (x, 0);
1291       st[1] = "&";
1292       op[1] = XEXP (x, 1);
1293       break;
1294     case IOR:
1295       op[0] = XEXP (x, 0);
1296       st[1] = "|";
1297       op[1] = XEXP (x, 1);
1298       break;
1299     case XOR:
1300       op[0] = XEXP (x, 0);
1301       st[1] = "^";
1302       op[1] = XEXP (x, 1);
1303       break;
1304     case ASHIFT:
1305       op[0] = XEXP (x, 0);
1306       st[1] = "<<";
1307       op[1] = XEXP (x, 1);
1308       break;
1309     case LSHIFTRT:
1310       op[0] = XEXP (x, 0);
1311       st[1] = " 0>>";
1312       op[1] = XEXP (x, 1);
1313       break;
1314     case ASHIFTRT:
1315       op[0] = XEXP (x, 0);
1316       st[1] = ">>";
1317       op[1] = XEXP (x, 1);
1318       break;
1319     case ROTATE:
1320       op[0] = XEXP (x, 0);
1321       st[1] = "<-<";
1322       op[1] = XEXP (x, 1);
1323       break;
1324     case ROTATERT:
1325       op[0] = XEXP (x, 0);
1326       st[1] = ">->";
1327       op[1] = XEXP (x, 1);
1328       break;
1329     case NE:
1330       op[0] = XEXP (x, 0);
1331       st[1] = "!=";
1332       op[1] = XEXP (x, 1);
1333       break;
1334     case EQ:
1335       op[0] = XEXP (x, 0);
1336       st[1] = "==";
1337       op[1] = XEXP (x, 1);
1338       break;
1339     case GE:
1340       op[0] = XEXP (x, 0);
1341       st[1] = ">=";
1342       op[1] = XEXP (x, 1);
1343       break;
1344     case GT:
1345       op[0] = XEXP (x, 0);
1346       st[1] = ">";
1347       op[1] = XEXP (x, 1);
1348       break;
1349     case LE:
1350       op[0] = XEXP (x, 0);
1351       st[1] = "<=";
1352       op[1] = XEXP (x, 1);
1353       break;
1354     case LT:
1355       op[0] = XEXP (x, 0);
1356       st[1] = "<";
1357       op[1] = XEXP (x, 1);
1358       break;
1359     case SIGN_EXTRACT:
1360       fun = (verbose) ? "sign_extract" : "sxt";
1361       op[0] = XEXP (x, 0);
1362       op[1] = XEXP (x, 1);
1363       op[2] = XEXP (x, 2);
1364       break;
1365     case ZERO_EXTRACT:
1366       fun = (verbose) ? "zero_extract" : "zxt";
1367       op[0] = XEXP (x, 0);
1368       op[1] = XEXP (x, 1);
1369       op[2] = XEXP (x, 2);
1370       break;
1371     case SIGN_EXTEND:
1372       fun = (verbose) ? "sign_extend" : "sxn";
1373       op[0] = XEXP (x, 0);
1374       break;
1375     case ZERO_EXTEND:
1376       fun = (verbose) ? "zero_extend" : "zxn";
1377       op[0] = XEXP (x, 0);
1378       break;
1379     case FLOAT_EXTEND:
1380       fun = (verbose) ? "float_extend" : "fxn";
1381       op[0] = XEXP (x, 0);
1382       break;
1383     case TRUNCATE:
1384       fun = (verbose) ? "trunc" : "trn";
1385       op[0] = XEXP (x, 0);
1386       break;
1387     case FLOAT_TRUNCATE:
1388       fun = (verbose) ? "float_trunc" : "ftr";
1389       op[0] = XEXP (x, 0);
1390       break;
1391     case FLOAT:
1392       fun = (verbose) ? "float" : "flt";
1393       op[0] = XEXP (x, 0);
1394       break;
1395     case UNSIGNED_FLOAT:
1396       fun = (verbose) ? "uns_float" : "ufl";
1397       op[0] = XEXP (x, 0);
1398       break;
1399     case FIX:
1400       fun = "fix";
1401       op[0] = XEXP (x, 0);
1402       break;
1403     case UNSIGNED_FIX:
1404       fun = (verbose) ? "uns_fix" : "ufx";
1405       op[0] = XEXP (x, 0);
1406       break;
1407     case PRE_DEC:
1408       st[0] = "--";
1409       op[0] = XEXP (x, 0);
1410       break;
1411     case PRE_INC:
1412       st[0] = "++";
1413       op[0] = XEXP (x, 0);
1414       break;
1415     case POST_DEC:
1416       op[0] = XEXP (x, 0);
1417       st[1] = "--";
1418       break;
1419     case POST_INC:
1420       op[0] = XEXP (x, 0);
1421       st[1] = "++";
1422       break;
1423     case PRE_MODIFY:
1424       st[0] = "pre ";
1425       op[0] = XEXP (XEXP (x, 1), 0);
1426       st[1] = "+=";
1427       op[1] = XEXP (XEXP (x, 1), 1);
1428       break;
1429     case POST_MODIFY:
1430       st[0] = "post ";
1431       op[0] = XEXP (XEXP (x, 1), 0);
1432       st[1] = "+=";
1433       op[1] = XEXP (XEXP (x, 1), 1);
1434       break;
1435     case CALL:
1436       st[0] = "call ";
1437       op[0] = XEXP (x, 0);
1438       if (verbose)
1439         {
1440           st[1] = " argc:";
1441           op[1] = XEXP (x, 1);
1442         }
1443       break;
1444     case IF_THEN_ELSE:
1445       st[0] = "{(";
1446       op[0] = XEXP (x, 0);
1447       st[1] = ")?";
1448       op[1] = XEXP (x, 1);
1449       st[2] = ":";
1450       op[2] = XEXP (x, 2);
1451       st[3] = "}";
1452       break;
1453     case TRAP_IF:
1454       fun = "trap_if";
1455       op[0] = TRAP_CONDITION (x);
1456       break;
1457     case PREFETCH:
1458       fun = "prefetch";
1459       op[0] = XEXP (x, 0);
1460       op[1] = XEXP (x, 1);
1461       op[2] = XEXP (x, 2);
1462       break;
1463     case UNSPEC:
1464     case UNSPEC_VOLATILE:
1465       {
1466         pp_string (pp, "unspec");
1467         if (GET_CODE (x) == UNSPEC_VOLATILE)
1468           pp_string (pp, "/v");
1469         pp_left_bracket (pp);
1470         for (i = 0; i < XVECLEN (x, 0); i++)
1471           {
1472             if (i != 0)
1473               pp_comma (pp);
1474             print_pattern (pp, XVECEXP (x, 0, i), verbose);
1475           }
1476         pp_string (pp, "] ");
1477         pp_decimal_int (pp, XINT (x, 1));
1478       }
1479       break;
1480     default:
1481       {
1482         /* Most unhandled codes can be printed as pseudo-functions.  */
1483         if (GET_RTX_CLASS (GET_CODE (x)) == RTX_UNARY)
1484           {
1485             fun = GET_RTX_NAME (GET_CODE (x));
1486             op[0] = XEXP (x, 0);
1487           }
1488         else if (GET_RTX_CLASS (GET_CODE (x)) == RTX_COMPARE
1489                  || GET_RTX_CLASS (GET_CODE (x)) == RTX_COMM_COMPARE
1490                  || GET_RTX_CLASS (GET_CODE (x)) == RTX_BIN_ARITH
1491                  || GET_RTX_CLASS (GET_CODE (x)) == RTX_COMM_ARITH)
1492           {
1493             fun = GET_RTX_NAME (GET_CODE (x));
1494             op[0] = XEXP (x, 0);
1495             op[1] = XEXP (x, 1);
1496           }
1497         else if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY)
1498           {
1499             fun = GET_RTX_NAME (GET_CODE (x));
1500             op[0] = XEXP (x, 0);
1501             op[1] = XEXP (x, 1);
1502             op[2] = XEXP (x, 2);
1503           }
1504         else
1505           /* Give up, just print the RTX name.  */
1506           st[0] = GET_RTX_NAME (GET_CODE (x));
1507       }
1508       break;
1509     }
1510
1511   /* Print this as a function?  */
1512   if (fun)
1513     {
1514       pp_string (pp, fun);
1515       pp_left_paren (pp);
1516     }
1517
1518   for (i = 0; i < 4; i++)
1519     {
1520       if (st[i])
1521         pp_string (pp, st[i]);
1522
1523       if (op[i])
1524         {
1525           if (fun && i != 0)
1526             pp_comma (pp);
1527           print_value (pp, op[i], verbose);
1528         }
1529     }
1530
1531   if (fun)
1532     pp_right_paren (pp);
1533 }               /* print_exp */
1534
1535 /* Prints rtxes, I customarily classified as values.  They're constants,
1536    registers, labels, symbols and memory accesses.  */
1537
1538 void
1539 print_value (pretty_printer *pp, const_rtx x, int verbose)
1540 {
1541   char tmp[1024];
1542
1543   if (!x)
1544     {
1545       pp_string (pp, "(nil)");
1546       return;
1547     }
1548   switch (GET_CODE (x))
1549     {
1550     case CONST_INT:
1551       pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
1552                  (unsigned HOST_WIDE_INT) INTVAL (x));
1553       break;
1554
1555     case CONST_WIDE_INT:
1556       {
1557         const char *sep = "<";
1558         int i;
1559         for (i = CONST_WIDE_INT_NUNITS (x) - 1; i >= 0; i--)
1560           {
1561             pp_string (pp, sep);
1562             sep = ",";
1563             sprintf (tmp, HOST_WIDE_INT_PRINT_HEX,
1564                      (unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (x, i));
1565             pp_string (pp, tmp);
1566           }
1567         pp_greater (pp);
1568       }
1569       break;
1570
1571     case CONST_DOUBLE:
1572       if (FLOAT_MODE_P (GET_MODE (x)))
1573         {
1574           real_to_decimal (tmp, CONST_DOUBLE_REAL_VALUE (x),
1575                            sizeof (tmp), 0, 1);
1576           pp_string (pp, tmp);
1577         }
1578       else
1579         pp_printf (pp, "<%wx,%wx>",
1580                    (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
1581                    (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
1582       break;
1583     case CONST_FIXED:
1584       fixed_to_decimal (tmp, CONST_FIXED_VALUE (x), sizeof (tmp));
1585       pp_string (pp, tmp);
1586       break;
1587     case CONST_STRING:
1588       pp_printf (pp, "\"%s\"", XSTR (x, 0));
1589       break;
1590     case SYMBOL_REF:
1591       pp_printf (pp, "`%s'", XSTR (x, 0));
1592       break;
1593     case LABEL_REF:
1594       pp_printf (pp, "L%d", INSN_UID (label_ref_label (x)));
1595       break;
1596     case CONST:
1597     case HIGH:
1598     case STRICT_LOW_PART:
1599       pp_printf (pp, "%s(", GET_RTX_NAME (GET_CODE (x)));
1600       print_value (pp, XEXP (x, 0), verbose);
1601       pp_right_paren (pp);
1602       break;
1603     case REG:
1604       if (REGNO (x) < FIRST_PSEUDO_REGISTER)
1605         {
1606           if (ISDIGIT (reg_names[REGNO (x)][0]))
1607             pp_modulo (pp);
1608           pp_string (pp, reg_names[REGNO (x)]);
1609         }
1610       else
1611         pp_printf (pp, "r%d", REGNO (x));
1612       if (verbose)
1613         pp_printf (pp, ":%s", GET_MODE_NAME (GET_MODE (x)));
1614       break;
1615     case SUBREG:
1616       print_value (pp, SUBREG_REG (x), verbose);
1617       pp_printf (pp, "#%d", SUBREG_BYTE (x));
1618       break;
1619     case SCRATCH:
1620     case CC0:
1621     case PC:
1622       pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
1623       break;
1624     case MEM:
1625       pp_left_bracket (pp);
1626       print_value (pp, XEXP (x, 0), verbose);
1627       pp_right_bracket (pp);
1628       break;
1629     case DEBUG_EXPR:
1630       pp_printf (pp, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
1631       break;
1632     default:
1633       print_exp (pp, x, verbose);
1634       break;
1635     }
1636 }                               /* print_value */
1637
1638 /* The next step in insn detalization, its pattern recognition.  */
1639
1640 void
1641 print_pattern (pretty_printer *pp, const_rtx x, int verbose)
1642 {
1643   if (! x)
1644     {
1645       pp_string (pp, "(nil)");
1646       return;
1647     }
1648
1649   switch (GET_CODE (x))
1650     {
1651     case SET:
1652       print_value (pp, SET_DEST (x), verbose);
1653       pp_equal (pp);
1654       print_value (pp, SET_SRC (x), verbose);
1655       break;
1656     case RETURN:
1657     case SIMPLE_RETURN:
1658     case EH_RETURN:
1659       pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
1660       break;
1661     case CALL:
1662       print_exp (pp, x, verbose);
1663       break;
1664     case CLOBBER:
1665     case USE:
1666       pp_printf (pp, "%s ", GET_RTX_NAME (GET_CODE (x)));
1667       print_value (pp, XEXP (x, 0), verbose);
1668       break;
1669     case VAR_LOCATION:
1670       pp_string (pp, "loc ");
1671       print_value (pp, PAT_VAR_LOCATION_LOC (x), verbose);
1672       break;
1673     case COND_EXEC:
1674       pp_left_paren (pp);
1675       if (GET_CODE (COND_EXEC_TEST (x)) == NE
1676           && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
1677         print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
1678       else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
1679                && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
1680         {
1681           pp_exclamation (pp);
1682           print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
1683         }
1684       else
1685         print_value (pp, COND_EXEC_TEST (x), verbose);
1686       pp_string (pp, ") ");
1687       print_pattern (pp, COND_EXEC_CODE (x), verbose);
1688       break;
1689     case PARALLEL:
1690       {
1691         int i;
1692
1693         pp_left_brace (pp);
1694         for (i = 0; i < XVECLEN (x, 0); i++)
1695           {
1696             print_pattern (pp, XVECEXP (x, 0, i), verbose);
1697             pp_semicolon (pp);
1698           }
1699         pp_right_brace (pp);
1700       }
1701       break;
1702     case SEQUENCE:
1703       {
1704         const rtx_sequence *seq = as_a <const rtx_sequence *> (x);
1705         pp_string (pp, "sequence{");
1706         if (INSN_P (seq->element (0)))
1707           {
1708             /* Print the sequence insns indented.  */
1709             const char * save_print_rtx_head = print_rtx_head;
1710             char indented_print_rtx_head[32];
1711
1712             pp_newline (pp);
1713             gcc_assert (strlen (print_rtx_head) < sizeof (indented_print_rtx_head) - 4);
1714             snprintf (indented_print_rtx_head,
1715                       sizeof (indented_print_rtx_head),
1716                       "%s     ", print_rtx_head);
1717             print_rtx_head = indented_print_rtx_head;
1718             for (int i = 0; i < seq->len (); i++)
1719               print_insn_with_notes (pp, seq->insn (i));
1720             pp_printf (pp, "%s      ", save_print_rtx_head);
1721             print_rtx_head = save_print_rtx_head;
1722           }
1723         else
1724           {
1725             for (int i = 0; i < seq->len (); i++)
1726               {
1727                 print_pattern (pp, seq->element (i), verbose);
1728                 pp_semicolon (pp);
1729               }
1730           }
1731         pp_right_brace (pp);
1732       }
1733       break;
1734     case ASM_INPUT:
1735       pp_printf (pp, "asm {%s}", XSTR (x, 0));
1736       break;
1737     case ADDR_VEC:
1738       for (int i = 0; i < XVECLEN (x, 0); i++)
1739         {
1740           print_value (pp, XVECEXP (x, 0, i), verbose);
1741           pp_semicolon (pp);
1742         }
1743       break;
1744     case ADDR_DIFF_VEC:
1745       for (int i = 0; i < XVECLEN (x, 1); i++)
1746         {
1747           print_value (pp, XVECEXP (x, 1, i), verbose);
1748           pp_semicolon (pp);
1749         }
1750       break;
1751     case TRAP_IF:
1752       pp_string (pp, "trap_if ");
1753       print_value (pp, TRAP_CONDITION (x), verbose);
1754       break;
1755     case UNSPEC:
1756     case UNSPEC_VOLATILE:
1757       /* Fallthru -- leave UNSPECs to print_exp.  */
1758     default:
1759       print_value (pp, x, verbose);
1760     }
1761 }                               /* print_pattern */
1762
1763 /* This is the main function in slim rtl visualization mechanism.
1764
1765    X is an insn, to be printed into PP.
1766
1767    This function tries to print it properly in human-readable form,
1768    resembling assembler mnemonics (instead of the older Lisp-style
1769    form).
1770
1771    If VERBOSE is TRUE, insns are printed with more complete (but
1772    longer) pattern names and with extra information, and prefixed
1773    with their INSN_UIDs.  */
1774
1775 void
1776 print_insn (pretty_printer *pp, const rtx_insn *x, int verbose)
1777 {
1778   if (verbose)
1779     {
1780       /* Blech, pretty-print can't print integers with a specified width.  */
1781       char uid_prefix[32];
1782       snprintf (uid_prefix, sizeof uid_prefix, " %4d: ", INSN_UID (x));
1783       pp_string (pp, uid_prefix);
1784     }
1785
1786   switch (GET_CODE (x))
1787     {
1788     case INSN:
1789       print_pattern (pp, PATTERN (x), verbose);
1790       break;
1791
1792     case DEBUG_INSN:
1793       {
1794         const char *name = "?";
1795         char idbuf[32];
1796
1797         if (DECL_P (INSN_VAR_LOCATION_DECL (x)))
1798           {
1799             tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (x));
1800             if (id)
1801               name = IDENTIFIER_POINTER (id);
1802             else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x))
1803                      == DEBUG_EXPR_DECL)
1804               {
1805                 sprintf (idbuf, "D#%i",
1806                          DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x)));
1807                 name = idbuf;
1808               }
1809             else
1810               {
1811                 sprintf (idbuf, "D.%i",
1812                          DECL_UID (INSN_VAR_LOCATION_DECL (x)));
1813                 name = idbuf;
1814               }
1815           }
1816         pp_printf (pp, "debug %s => ", name);
1817         if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x)))
1818           pp_string (pp, "optimized away");
1819         else
1820           print_pattern (pp, INSN_VAR_LOCATION_LOC (x), verbose);
1821       }
1822       break;
1823
1824     case JUMP_INSN:
1825       print_pattern (pp, PATTERN (x), verbose);
1826       break;
1827     case CALL_INSN:
1828       if (GET_CODE (PATTERN (x)) == PARALLEL)
1829         print_pattern (pp, XVECEXP (PATTERN (x), 0, 0), verbose);
1830       else
1831         print_pattern (pp, PATTERN (x), verbose);
1832       break;
1833     case CODE_LABEL:
1834       pp_printf (pp, "L%d:", INSN_UID (x));
1835       break;
1836     case JUMP_TABLE_DATA:
1837       pp_string (pp, "jump_table_data{\n");
1838       print_pattern (pp, PATTERN (x), verbose);
1839       pp_right_brace (pp);
1840       break;
1841     case BARRIER:
1842       pp_string (pp, "barrier");
1843       break;
1844     case NOTE:
1845       {
1846         pp_string (pp, GET_NOTE_INSN_NAME (NOTE_KIND (x)));
1847         switch (NOTE_KIND (x))
1848           {
1849           case NOTE_INSN_EH_REGION_BEG:
1850           case NOTE_INSN_EH_REGION_END:
1851             pp_printf (pp, " %d", NOTE_EH_HANDLER (x));
1852             break;
1853
1854           case NOTE_INSN_BLOCK_BEG:
1855           case NOTE_INSN_BLOCK_END:
1856             pp_printf (pp, " %d", BLOCK_NUMBER (NOTE_BLOCK (x)));
1857             break;
1858
1859           case NOTE_INSN_BASIC_BLOCK:
1860             pp_printf (pp, " %d", NOTE_BASIC_BLOCK (x)->index);
1861             break;
1862
1863           case NOTE_INSN_DELETED_LABEL:
1864           case NOTE_INSN_DELETED_DEBUG_LABEL:
1865             {
1866               const char *label = NOTE_DELETED_LABEL_NAME (x);
1867               if (label == NULL)
1868                 label = "";
1869               pp_printf (pp, " (\"%s\")", label);
1870             }
1871             break;
1872
1873           case NOTE_INSN_VAR_LOCATION:
1874           case NOTE_INSN_CALL_ARG_LOCATION:
1875             pp_left_brace (pp);
1876             print_pattern (pp, NOTE_VAR_LOCATION (x), verbose);
1877             pp_right_brace (pp);
1878             break;
1879
1880           default:
1881             break;
1882           }
1883         break;
1884       }
1885     default:
1886       gcc_unreachable ();
1887     }
1888 }                               /* print_insn */
1889
1890 /* Pretty-print a slim dump of X (an insn) to PP, including any register
1891    note attached to the instruction.  */
1892
1893 static void
1894 print_insn_with_notes (pretty_printer *pp, const rtx_insn *x)
1895 {
1896   pp_string (pp, print_rtx_head);
1897   print_insn (pp, x, 1);
1898   pp_newline (pp);
1899   if (INSN_P (x) && REG_NOTES (x))
1900     for (rtx note = REG_NOTES (x); note; note = XEXP (note, 1))
1901       {
1902         pp_printf (pp, "%s      %s ", print_rtx_head,
1903                    GET_REG_NOTE_NAME (REG_NOTE_KIND (note)));
1904         if (GET_CODE (note) == INT_LIST)
1905           pp_printf (pp, "%d", XINT (note, 0));
1906         else
1907           print_pattern (pp, XEXP (note, 0), 1);
1908         pp_newline (pp);
1909       }
1910 }
1911
1912 /* Print X, an RTL value node, to file F in slim format.  Include
1913    additional information if VERBOSE is nonzero.
1914
1915    Value nodes are constants, registers, labels, symbols and
1916    memory.  */
1917
1918 void
1919 dump_value_slim (FILE *f, const_rtx x, int verbose)
1920 {
1921   pretty_printer rtl_slim_pp;
1922   rtl_slim_pp.buffer->stream = f;
1923   print_value (&rtl_slim_pp, x, verbose);
1924   pp_flush (&rtl_slim_pp);
1925 }
1926
1927 /* Emit a slim dump of X (an insn) to the file F, including any register
1928    note attached to the instruction.  */
1929 void
1930 dump_insn_slim (FILE *f, const rtx_insn *x)
1931 {
1932   pretty_printer rtl_slim_pp;
1933   rtl_slim_pp.buffer->stream = f;
1934   print_insn_with_notes (&rtl_slim_pp, x);
1935   pp_flush (&rtl_slim_pp);
1936 }
1937
1938 /* Same as above, but stop at LAST or when COUNT == 0.
1939    If COUNT < 0 it will stop only at LAST or NULL rtx.  */
1940
1941 void
1942 dump_rtl_slim (FILE *f, const rtx_insn *first, const rtx_insn *last,
1943                int count, int flags ATTRIBUTE_UNUSED)
1944 {
1945   const rtx_insn *insn, *tail;
1946   pretty_printer rtl_slim_pp;
1947   rtl_slim_pp.buffer->stream = f;
1948
1949   tail = last ? NEXT_INSN (last) : NULL;
1950   for (insn = first;
1951        (insn != NULL) && (insn != tail) && (count != 0);
1952        insn = NEXT_INSN (insn))
1953     {
1954       print_insn_with_notes (&rtl_slim_pp, insn);
1955       if (count > 0)
1956         count--;
1957     }
1958
1959   pp_flush (&rtl_slim_pp);
1960 }
1961
1962 /* Dumps basic block BB to pretty-printer PP in slim form and without and
1963    no indentation, for use as a label of a DOT graph record-node.  */
1964
1965 void
1966 rtl_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
1967 {
1968   rtx_insn *insn;
1969   bool first = true;
1970
1971   /* TODO: inter-bb stuff.  */
1972   FOR_BB_INSNS (bb, insn)
1973     {
1974       if (! first)
1975         {
1976           pp_bar (pp);
1977           pp_write_text_to_stream (pp);
1978         }
1979       first = false;
1980       print_insn_with_notes (pp, insn);
1981       pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true);
1982     }
1983 }
1984
1985 /* Pretty-print pattern X of some insn in non-verbose mode.
1986    Return a string pointer to the pretty-printer buffer.
1987
1988    This function is only exported exists only to accommodate some older users
1989    of the slim RTL pretty printers.  Please do not use it for new code.  */
1990
1991 const char *
1992 str_pattern_slim (const_rtx x)
1993 {
1994   pretty_printer rtl_slim_pp;
1995   print_pattern (&rtl_slim_pp, x, 0);
1996   return ggc_strdup (pp_formatted_text (&rtl_slim_pp));
1997 }
1998
1999 /* Emit a slim dump of X (an insn) to stderr.  */
2000 extern void debug_insn_slim (const rtx_insn *);
2001 DEBUG_FUNCTION void
2002 debug_insn_slim (const rtx_insn *x)
2003 {
2004   dump_insn_slim (stderr, x);
2005 }
2006
2007 /* Same as above, but using dump_rtl_slim.  */
2008 extern void debug_rtl_slim (FILE *, const rtx_insn *, const rtx_insn *,
2009                             int, int);
2010 DEBUG_FUNCTION void
2011 debug_rtl_slim (const rtx_insn *first, const rtx_insn *last, int count,
2012                 int flags)
2013 {
2014   dump_rtl_slim (stderr, first, last, count, flags);
2015 }
2016
2017 extern void debug_bb_slim (basic_block);
2018 DEBUG_FUNCTION void
2019 debug_bb_slim (basic_block bb)
2020 {
2021   dump_bb (stderr, bb, 0, TDF_SLIM | TDF_BLOCKS);
2022 }
2023
2024 extern void debug_bb_n_slim (int);
2025 DEBUG_FUNCTION void
2026 debug_bb_n_slim (int n)
2027 {
2028   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, n);
2029   debug_bb_slim (bb);
2030 }
2031
2032 #endif