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