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