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