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