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