* es.po: Update.
[official-gcc.git] / gcc / print-rtl.c
blob341ecdfedb84fb500b54c2a49934afda4b62672c
1 /* Print RTL for GCC.
2 Copyright (C) 1987-2016 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
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
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "rtl.h"
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 "cfg.h"
39 #include "print-tree.h"
40 #include "flags.h"
41 #include "predict.h"
42 #include "function.h"
43 #include "basic-block.h"
44 #include "diagnostic.h"
45 #include "tree-pretty-print.h"
46 #include "alloc-pool.h"
47 #include "cselib.h"
48 #include "dumpfile.h" /* for dump_flags */
49 #include "dwarf2out.h"
50 #include "pretty-print.h"
51 #endif
53 #include "print-rtl.h"
55 /* String printed at beginning of each RTL when it is dumped.
56 This string is set to ASM_COMMENT_START when the RTL is dumped in
57 the assembly output file. */
58 const char *print_rtx_head = "";
60 #ifdef GENERATOR_FILE
61 /* These are defined from the .opt file when not used in generator
62 programs. */
64 /* Nonzero means suppress output of instruction numbers
65 in debugging dumps.
66 This must be defined here so that programs like gencodes can be linked. */
67 int flag_dump_unnumbered = 0;
69 /* Nonzero means suppress output of instruction numbers for previous
70 and next insns in debugging dumps.
71 This must be defined here so that programs like gencodes can be linked. */
72 int flag_dump_unnumbered_links = 0;
73 #endif
75 /* Constructor for rtx_writer. */
77 rtx_writer::rtx_writer (FILE *outf, int ind, bool simple, bool compact)
78 : m_outfile (outf), m_sawclose (0), m_indent (ind),
79 m_in_call_function_usage (false), m_simple (simple), m_compact (compact)
83 #ifndef GENERATOR_FILE
84 void
85 print_mem_expr (FILE *outfile, const_tree expr)
87 fputc (' ', outfile);
88 print_generic_expr (outfile, CONST_CAST_TREE (expr), dump_flags);
90 #endif
92 /* Subroutine of print_rtx_operand for handling code '0'.
93 0 indicates a field for internal use that should not be printed.
94 However there are various special cases, such as the third field
95 of a NOTE, where it indicates that the field has several different
96 valid contents. */
98 void
99 rtx_writer::print_rtx_operand_code_0 (const_rtx in_rtx ATTRIBUTE_UNUSED,
100 int idx ATTRIBUTE_UNUSED)
102 #ifndef GENERATOR_FILE
103 if (idx == 1 && GET_CODE (in_rtx) == SYMBOL_REF)
105 int flags = SYMBOL_REF_FLAGS (in_rtx);
106 if (flags)
107 fprintf (m_outfile, " [flags %#x]", flags);
108 tree decl = SYMBOL_REF_DECL (in_rtx);
109 if (decl)
110 print_node_brief (m_outfile, "", decl, dump_flags);
112 else if (idx == 3 && NOTE_P (in_rtx))
114 switch (NOTE_KIND (in_rtx))
116 case NOTE_INSN_EH_REGION_BEG:
117 case NOTE_INSN_EH_REGION_END:
118 if (flag_dump_unnumbered)
119 fprintf (m_outfile, " #");
120 else
121 fprintf (m_outfile, " %d", NOTE_EH_HANDLER (in_rtx));
122 m_sawclose = 1;
123 break;
125 case NOTE_INSN_BLOCK_BEG:
126 case NOTE_INSN_BLOCK_END:
127 dump_addr (m_outfile, " ", NOTE_BLOCK (in_rtx));
128 m_sawclose = 1;
129 break;
131 case NOTE_INSN_BASIC_BLOCK:
133 basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
134 if (bb != 0)
135 fprintf (m_outfile, " [bb %d]", bb->index);
136 break;
139 case NOTE_INSN_DELETED_LABEL:
140 case NOTE_INSN_DELETED_DEBUG_LABEL:
142 const char *label = NOTE_DELETED_LABEL_NAME (in_rtx);
143 if (label)
144 fprintf (m_outfile, " (\"%s\")", label);
145 else
146 fprintf (m_outfile, " \"\"");
148 break;
150 case NOTE_INSN_SWITCH_TEXT_SECTIONS:
152 basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
153 if (bb != 0)
154 fprintf (m_outfile, " [bb %d]", bb->index);
155 break;
158 case NOTE_INSN_VAR_LOCATION:
159 case NOTE_INSN_CALL_ARG_LOCATION:
160 fputc (' ', m_outfile);
161 print_rtx (NOTE_VAR_LOCATION (in_rtx));
162 break;
164 case NOTE_INSN_CFI:
165 fputc ('\n', m_outfile);
166 output_cfi_directive (m_outfile, NOTE_CFI (in_rtx));
167 fputc ('\t', m_outfile);
168 break;
170 default:
171 break;
174 else if (idx == 7 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL
175 && !m_compact)
177 /* Output the JUMP_LABEL reference. */
178 fprintf (m_outfile, "\n%s%*s -> ", print_rtx_head, m_indent * 2, "");
179 if (GET_CODE (JUMP_LABEL (in_rtx)) == RETURN)
180 fprintf (m_outfile, "return");
181 else if (GET_CODE (JUMP_LABEL (in_rtx)) == SIMPLE_RETURN)
182 fprintf (m_outfile, "simple_return");
183 else
184 fprintf (m_outfile, "%d", INSN_UID (JUMP_LABEL (in_rtx)));
186 else if (idx == 0 && GET_CODE (in_rtx) == VALUE)
188 cselib_val *val = CSELIB_VAL_PTR (in_rtx);
190 fprintf (m_outfile, " %u:%u", val->uid, val->hash);
191 dump_addr (m_outfile, " @", in_rtx);
192 dump_addr (m_outfile, "/", (void*)val);
194 else if (idx == 0 && GET_CODE (in_rtx) == DEBUG_EXPR)
196 fprintf (m_outfile, " D#%i",
197 DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (in_rtx)));
199 else if (idx == 0 && GET_CODE (in_rtx) == ENTRY_VALUE)
201 m_indent += 2;
202 if (!m_sawclose)
203 fprintf (m_outfile, " ");
204 print_rtx (ENTRY_VALUE_EXP (in_rtx));
205 m_indent -= 2;
207 #endif
210 /* Subroutine of print_rtx_operand for handling code 'e'.
211 Also called by print_rtx_operand_code_u for handling code 'u'
212 for LABEL_REFs when they don't reference a CODE_LABEL. */
214 void
215 rtx_writer::print_rtx_operand_code_e (const_rtx in_rtx, int idx)
217 m_indent += 2;
218 if (idx == 6 && INSN_P (in_rtx))
219 /* Put REG_NOTES on their own line. */
220 fprintf (m_outfile, "\n%s%*s",
221 print_rtx_head, m_indent * 2, "");
222 if (!m_sawclose)
223 fprintf (m_outfile, " ");
224 if (idx == 7 && CALL_P (in_rtx))
226 m_in_call_function_usage = true;
227 print_rtx (XEXP (in_rtx, idx));
228 m_in_call_function_usage = false;
230 else
231 print_rtx (XEXP (in_rtx, idx));
232 m_indent -= 2;
235 /* Subroutine of print_rtx_operand for handling codes 'E' and 'V'. */
237 void
238 rtx_writer::print_rtx_operand_codes_E_and_V (const_rtx in_rtx, int idx)
240 m_indent += 2;
241 if (m_sawclose)
243 fprintf (m_outfile, "\n%s%*s",
244 print_rtx_head, m_indent * 2, "");
245 m_sawclose = 0;
247 fputs (" [", m_outfile);
248 if (NULL != XVEC (in_rtx, idx))
250 m_indent += 2;
251 if (XVECLEN (in_rtx, idx))
252 m_sawclose = 1;
254 for (int j = 0; j < XVECLEN (in_rtx, idx); j++)
255 print_rtx (XVECEXP (in_rtx, idx, j));
257 m_indent -= 2;
259 if (m_sawclose)
260 fprintf (m_outfile, "\n%s%*s", print_rtx_head, m_indent * 2, "");
262 fputs ("]", m_outfile);
263 m_sawclose = 1;
264 m_indent -= 2;
267 /* Subroutine of print_rtx_operand for handling code 'i'. */
269 void
270 rtx_writer::print_rtx_operand_code_i (const_rtx in_rtx, int idx)
272 if (idx == 4 && INSN_P (in_rtx))
274 #ifndef GENERATOR_FILE
275 const rtx_insn *in_insn = as_a <const rtx_insn *> (in_rtx);
277 /* Pretty-print insn locations. Ignore scoping as it is mostly
278 redundant with line number information and do not print anything
279 when there is no location information available. */
280 if (INSN_HAS_LOCATION (in_insn))
282 expanded_location xloc = insn_location (in_insn);
283 fprintf (m_outfile, " \"%s\":%i", xloc.file, xloc.line);
285 #endif
287 else if (idx == 6 && GET_CODE (in_rtx) == ASM_OPERANDS)
289 #ifndef GENERATOR_FILE
290 if (ASM_OPERANDS_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
291 fprintf (m_outfile, " %s:%i",
292 LOCATION_FILE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
293 LOCATION_LINE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
294 #endif
296 else if (idx == 1 && GET_CODE (in_rtx) == ASM_INPUT)
298 #ifndef GENERATOR_FILE
299 if (ASM_INPUT_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
300 fprintf (m_outfile, " %s:%i",
301 LOCATION_FILE (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
302 LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
303 #endif
305 else if (idx == 5 && NOTE_P (in_rtx))
307 /* This field is only used for NOTE_INSN_DELETED_LABEL, and
308 other times often contains garbage from INSN->NOTE death. */
309 if (NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_LABEL
310 || NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_DEBUG_LABEL)
311 fprintf (m_outfile, " %d", XINT (in_rtx, idx));
313 #if !defined(GENERATOR_FILE) && NUM_UNSPECV_VALUES > 0
314 else if (idx == 1
315 && GET_CODE (in_rtx) == UNSPEC_VOLATILE
316 && XINT (in_rtx, 1) >= 0
317 && XINT (in_rtx, 1) < NUM_UNSPECV_VALUES)
318 fprintf (m_outfile, " %s", unspecv_strings[XINT (in_rtx, 1)]);
319 #endif
320 #if !defined(GENERATOR_FILE) && NUM_UNSPEC_VALUES > 0
321 else if (idx == 1
322 && (GET_CODE (in_rtx) == UNSPEC
323 || GET_CODE (in_rtx) == UNSPEC_VOLATILE)
324 && XINT (in_rtx, 1) >= 0
325 && XINT (in_rtx, 1) < NUM_UNSPEC_VALUES)
326 fprintf (m_outfile, " %s", unspec_strings[XINT (in_rtx, 1)]);
327 #endif
328 else
330 int value = XINT (in_rtx, idx);
331 const char *name;
332 int is_insn = INSN_P (in_rtx);
334 /* Don't print INSN_CODEs in compact mode. */
335 if (m_compact && is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, idx))
337 m_sawclose = 0;
338 return;
341 if (flag_dump_unnumbered
342 && (is_insn || NOTE_P (in_rtx)))
343 fputc ('#', m_outfile);
344 else
345 fprintf (m_outfile, " %d", value);
347 if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, idx)
348 && XINT (in_rtx, idx) >= 0
349 && (name = get_insn_name (XINT (in_rtx, idx))) != NULL)
350 fprintf (m_outfile, " {%s}", name);
351 m_sawclose = 0;
355 /* Subroutine of print_rtx_operand for handling code 'r'. */
357 void
358 rtx_writer::print_rtx_operand_code_r (const_rtx in_rtx)
360 int is_insn = INSN_P (in_rtx);
361 unsigned int regno = REGNO (in_rtx);
363 #ifndef GENERATOR_FILE
364 /* For hard registers and virtuals, always print the
365 regno, except in compact mode. */
366 if (regno <= LAST_VIRTUAL_REGISTER && !m_compact)
367 fprintf (m_outfile, " %d", regno);
368 if (regno < FIRST_PSEUDO_REGISTER)
369 fprintf (m_outfile, " %s", reg_names[regno]);
370 else if (regno <= LAST_VIRTUAL_REGISTER)
372 if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
373 fprintf (m_outfile, " virtual-incoming-args");
374 else if (regno == VIRTUAL_STACK_VARS_REGNUM)
375 fprintf (m_outfile, " virtual-stack-vars");
376 else if (regno == VIRTUAL_STACK_DYNAMIC_REGNUM)
377 fprintf (m_outfile, " virtual-stack-dynamic");
378 else if (regno == VIRTUAL_OUTGOING_ARGS_REGNUM)
379 fprintf (m_outfile, " virtual-outgoing-args");
380 else if (regno == VIRTUAL_CFA_REGNUM)
381 fprintf (m_outfile, " virtual-cfa");
382 else if (regno == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
383 fprintf (m_outfile, " virtual-preferred-stack-boundary");
384 else
385 fprintf (m_outfile, " virtual-reg-%d", regno-FIRST_VIRTUAL_REGISTER);
387 else
388 #endif
389 if (flag_dump_unnumbered && is_insn)
390 fputc ('#', m_outfile);
391 else if (m_compact)
393 /* In compact mode, print pseudos with a '%' sigil following
394 by the regno, offset by (LAST_VIRTUAL_REGISTER + 1), so that the
395 first non-virtual pseudo is dumped as "%0". */
396 gcc_assert (regno > LAST_VIRTUAL_REGISTER);
397 fprintf (m_outfile, " %%%d", regno - (LAST_VIRTUAL_REGISTER + 1));
399 else
400 fprintf (m_outfile, " %d", regno);
402 #ifndef GENERATOR_FILE
403 if (REG_ATTRS (in_rtx))
405 fputs (" [", m_outfile);
406 if (regno != ORIGINAL_REGNO (in_rtx))
407 fprintf (m_outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
408 if (REG_EXPR (in_rtx))
409 print_mem_expr (m_outfile, REG_EXPR (in_rtx));
411 if (REG_OFFSET (in_rtx))
412 fprintf (m_outfile, "+" HOST_WIDE_INT_PRINT_DEC,
413 REG_OFFSET (in_rtx));
414 fputs (" ]", m_outfile);
416 if (regno != ORIGINAL_REGNO (in_rtx))
417 fprintf (m_outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
418 #endif
421 /* Subroutine of print_rtx_operand for handling code 'u'. */
423 void
424 rtx_writer::print_rtx_operand_code_u (const_rtx in_rtx, int idx)
426 /* Don't print insn UIDs for PREV/NEXT_INSN in compact mode. */
427 if (m_compact && INSN_CHAIN_CODE_P (GET_CODE (in_rtx)) && idx < 2)
428 return;
430 if (XEXP (in_rtx, idx) != NULL)
432 rtx sub = XEXP (in_rtx, idx);
433 enum rtx_code subc = GET_CODE (sub);
435 if (GET_CODE (in_rtx) == LABEL_REF)
437 if (subc == NOTE
438 && NOTE_KIND (sub) == NOTE_INSN_DELETED_LABEL)
440 if (flag_dump_unnumbered)
441 fprintf (m_outfile, " [# deleted]");
442 else
443 fprintf (m_outfile, " [%d deleted]", INSN_UID (sub));
444 m_sawclose = 0;
445 return;
448 if (subc != CODE_LABEL)
450 print_rtx_operand_code_e (in_rtx, idx);
451 return;
455 if (flag_dump_unnumbered
456 || (flag_dump_unnumbered_links && idx <= 1
457 && (INSN_P (in_rtx) || NOTE_P (in_rtx)
458 || LABEL_P (in_rtx) || BARRIER_P (in_rtx))))
459 fputs (" #", m_outfile);
460 else
461 fprintf (m_outfile, " %d", INSN_UID (sub));
463 else
464 fputs (" 0", m_outfile);
465 m_sawclose = 0;
468 /* Subroutine of print_rtx. Print operand IDX of IN_RTX. */
470 void
471 rtx_writer::print_rtx_operand (const_rtx in_rtx, int idx)
473 const char *format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
475 switch (format_ptr[idx])
477 const char *str;
479 case 'T':
480 str = XTMPL (in_rtx, idx);
481 goto string;
483 case 'S':
484 case 's':
485 str = XSTR (in_rtx, idx);
486 string:
488 if (str == 0)
489 fputs (" \"\"", m_outfile);
490 else
491 fprintf (m_outfile, " (\"%s\")", str);
492 m_sawclose = 1;
493 break;
495 case '0':
496 print_rtx_operand_code_0 (in_rtx, idx);
497 break;
499 case 'e':
500 print_rtx_operand_code_e (in_rtx, idx);
501 break;
503 case 'E':
504 case 'V':
505 print_rtx_operand_codes_E_and_V (in_rtx, idx);
506 break;
508 case 'w':
509 if (! m_simple)
510 fprintf (m_outfile, " ");
511 fprintf (m_outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, idx));
512 if (! m_simple && !m_compact)
513 fprintf (m_outfile, " [" HOST_WIDE_INT_PRINT_HEX "]",
514 (unsigned HOST_WIDE_INT) XWINT (in_rtx, idx));
515 break;
517 case 'i':
518 print_rtx_operand_code_i (in_rtx, idx);
519 break;
521 case 'r':
522 print_rtx_operand_code_r (in_rtx);
523 break;
525 /* Print NOTE_INSN names rather than integer codes. */
527 case 'n':
528 fprintf (m_outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, idx)));
529 m_sawclose = 0;
530 break;
532 case 'u':
533 print_rtx_operand_code_u (in_rtx, idx);
534 break;
536 case 't':
537 #ifndef GENERATOR_FILE
538 if (idx == 0 && GET_CODE (in_rtx) == DEBUG_IMPLICIT_PTR)
539 print_mem_expr (m_outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx));
540 else if (idx == 0 && GET_CODE (in_rtx) == DEBUG_PARAMETER_REF)
541 print_mem_expr (m_outfile, DEBUG_PARAMETER_REF_DECL (in_rtx));
542 else
543 dump_addr (m_outfile, " ", XTREE (in_rtx, idx));
544 #endif
545 break;
547 case '*':
548 fputs (" Unknown", m_outfile);
549 m_sawclose = 0;
550 break;
552 case 'B':
553 /* Don't print basic block ids in compact mode. */
554 if (m_compact)
555 break;
556 #ifndef GENERATOR_FILE
557 if (XBBDEF (in_rtx, idx))
558 fprintf (m_outfile, " %i", XBBDEF (in_rtx, idx)->index);
559 #endif
560 break;
562 default:
563 gcc_unreachable ();
567 /* Print IN_RTX onto m_outfile. This is the recursive part of printing. */
569 void
570 rtx_writer::print_rtx (const_rtx in_rtx)
572 int idx = 0;
574 if (m_sawclose)
576 if (m_simple)
577 fputc (' ', m_outfile);
578 else
579 fprintf (m_outfile, "\n%s%*s", print_rtx_head, m_indent * 2, "");
580 m_sawclose = 0;
583 if (in_rtx == 0)
585 fputs ("(nil)", m_outfile);
586 m_sawclose = 1;
587 return;
589 else if (GET_CODE (in_rtx) > NUM_RTX_CODE)
591 fprintf (m_outfile, "(??? bad code %d\n%s%*s)", GET_CODE (in_rtx),
592 print_rtx_head, m_indent * 2, "");
593 m_sawclose = 1;
594 return;
597 /* Print name of expression code. */
599 /* In compact mode, prefix the code of insns with "c",
600 giving "cinsn", "cnote" etc. */
601 if (m_compact && is_a <const rtx_insn *, const struct rtx_def> (in_rtx))
603 /* "ccode_label" is slightly awkward, so special-case it as
604 just "clabel". */
605 rtx_code code = GET_CODE (in_rtx);
606 if (code == CODE_LABEL)
607 fprintf (m_outfile, "(clabel");
608 else
609 fprintf (m_outfile, "(c%s", GET_RTX_NAME (code));
611 else if (m_simple && CONST_INT_P (in_rtx))
612 fputc ('(', m_outfile);
613 else
614 fprintf (m_outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
616 if (! m_simple)
618 if (RTX_FLAG (in_rtx, in_struct))
619 fputs ("/s", m_outfile);
621 if (RTX_FLAG (in_rtx, volatil))
622 fputs ("/v", m_outfile);
624 if (RTX_FLAG (in_rtx, unchanging))
625 fputs ("/u", m_outfile);
627 if (RTX_FLAG (in_rtx, frame_related))
628 fputs ("/f", m_outfile);
630 if (RTX_FLAG (in_rtx, jump))
631 fputs ("/j", m_outfile);
633 if (RTX_FLAG (in_rtx, call))
634 fputs ("/c", m_outfile);
636 if (RTX_FLAG (in_rtx, return_val))
637 fputs ("/i", m_outfile);
639 /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */
640 if ((GET_CODE (in_rtx) == EXPR_LIST
641 || GET_CODE (in_rtx) == INSN_LIST
642 || GET_CODE (in_rtx) == INT_LIST)
643 && (int)GET_MODE (in_rtx) < REG_NOTE_MAX
644 && !m_in_call_function_usage)
645 fprintf (m_outfile, ":%s",
646 GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
648 /* For other rtl, print the mode if it's not VOID. */
649 else if (GET_MODE (in_rtx) != VOIDmode)
650 fprintf (m_outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
652 #ifndef GENERATOR_FILE
653 if (GET_CODE (in_rtx) == VAR_LOCATION)
655 if (TREE_CODE (PAT_VAR_LOCATION_DECL (in_rtx)) == STRING_CST)
656 fputs (" <debug string placeholder>", m_outfile);
657 else
658 print_mem_expr (m_outfile, PAT_VAR_LOCATION_DECL (in_rtx));
659 fputc (' ', m_outfile);
660 print_rtx (PAT_VAR_LOCATION_LOC (in_rtx));
661 if (PAT_VAR_LOCATION_STATUS (in_rtx)
662 == VAR_INIT_STATUS_UNINITIALIZED)
663 fprintf (m_outfile, " [uninit]");
664 m_sawclose = 1;
665 idx = GET_RTX_LENGTH (VAR_LOCATION);
667 #endif
670 #ifndef GENERATOR_FILE
671 if (CONST_DOUBLE_AS_FLOAT_P (in_rtx))
672 idx = 5;
673 #endif
675 /* For insns, print the INSN_UID. */
676 if (INSN_CHAIN_CODE_P (GET_CODE (in_rtx)))
678 if (flag_dump_unnumbered)
679 fprintf (m_outfile, " #");
680 else
681 fprintf (m_outfile, " %d", INSN_UID (in_rtx));
684 /* Get the format string and skip the first elements if we have handled
685 them already. */
686 for (; idx < GET_RTX_LENGTH (GET_CODE (in_rtx)); idx++)
687 print_rtx_operand (in_rtx, idx);
689 switch (GET_CODE (in_rtx))
691 #ifndef GENERATOR_FILE
692 case MEM:
693 if (__builtin_expect (final_insns_dump_p, false))
694 fprintf (m_outfile, " [");
695 else
696 fprintf (m_outfile, " [" HOST_WIDE_INT_PRINT_DEC,
697 (HOST_WIDE_INT) MEM_ALIAS_SET (in_rtx));
699 if (MEM_EXPR (in_rtx))
700 print_mem_expr (m_outfile, MEM_EXPR (in_rtx));
701 else
702 fputc (' ', m_outfile);
704 if (MEM_OFFSET_KNOWN_P (in_rtx))
705 fprintf (m_outfile, "+" HOST_WIDE_INT_PRINT_DEC, MEM_OFFSET (in_rtx));
707 if (MEM_SIZE_KNOWN_P (in_rtx))
708 fprintf (m_outfile, " S" HOST_WIDE_INT_PRINT_DEC, MEM_SIZE (in_rtx));
710 if (MEM_ALIGN (in_rtx) != 1)
711 fprintf (m_outfile, " A%u", MEM_ALIGN (in_rtx));
713 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (in_rtx)))
714 fprintf (m_outfile, " AS%u", MEM_ADDR_SPACE (in_rtx));
716 fputc (']', m_outfile);
717 break;
719 case CONST_DOUBLE:
720 if (FLOAT_MODE_P (GET_MODE (in_rtx)))
722 char s[60];
724 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
725 sizeof (s), 0, 1);
726 fprintf (m_outfile, " %s", s);
728 real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
729 sizeof (s), 0, 1);
730 fprintf (m_outfile, " [%s]", s);
732 break;
734 case CONST_WIDE_INT:
735 fprintf (m_outfile, " ");
736 cwi_output_hex (m_outfile, in_rtx);
737 break;
738 #endif
740 case CODE_LABEL:
741 if (!m_compact)
742 fprintf (m_outfile, " [%d uses]", LABEL_NUSES (in_rtx));
743 switch (LABEL_KIND (in_rtx))
745 case LABEL_NORMAL: break;
746 case LABEL_STATIC_ENTRY: fputs (" [entry]", m_outfile); break;
747 case LABEL_GLOBAL_ENTRY: fputs (" [global entry]", m_outfile); break;
748 case LABEL_WEAK_ENTRY: fputs (" [weak entry]", m_outfile); break;
749 default: gcc_unreachable ();
751 break;
753 default:
754 break;
757 fputc (')', m_outfile);
758 m_sawclose = 1;
761 /* Print an rtx on the current line of FILE. Initially indent IND
762 characters. */
764 void
765 print_inline_rtx (FILE *outf, const_rtx x, int ind)
767 rtx_writer w (outf, ind, false, false);
768 w.print_rtx (x);
771 /* Call this function from the debugger to see what X looks like. */
773 DEBUG_FUNCTION void
774 debug_rtx (const_rtx x)
776 rtx_writer w (stderr, 0, false, false);
777 w.print_rtx (x);
778 fprintf (stderr, "\n");
781 /* Dump rtx REF. */
783 DEBUG_FUNCTION void
784 debug (const rtx_def &ref)
786 debug_rtx (&ref);
789 DEBUG_FUNCTION void
790 debug (const rtx_def *ptr)
792 if (ptr)
793 debug (*ptr);
794 else
795 fprintf (stderr, "<nil>\n");
798 /* Count of rtx's to print with debug_rtx_list.
799 This global exists because gdb user defined commands have no arguments. */
801 DEBUG_VARIABLE int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */
803 /* Call this function to print list from X on.
805 N is a count of the rtx's to print. Positive values print from the specified
806 rtx_insn on. Negative values print a window around the rtx_insn.
807 EG: -5 prints 2 rtx_insn's on either side (in addition to the specified
808 rtx_insn). */
810 DEBUG_FUNCTION void
811 debug_rtx_list (const rtx_insn *x, int n)
813 int i,count;
814 const rtx_insn *insn;
816 count = n == 0 ? 1 : n < 0 ? -n : n;
818 /* If we are printing a window, back up to the start. */
820 if (n < 0)
821 for (i = count / 2; i > 0; i--)
823 if (PREV_INSN (x) == 0)
824 break;
825 x = PREV_INSN (x);
828 for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
830 debug_rtx (insn);
831 fprintf (stderr, "\n");
835 /* Call this function to print an rtx_insn list from START to END
836 inclusive. */
838 DEBUG_FUNCTION void
839 debug_rtx_range (const rtx_insn *start, const rtx_insn *end)
841 while (1)
843 debug_rtx (start);
844 fprintf (stderr, "\n");
845 if (!start || start == end)
846 break;
847 start = NEXT_INSN (start);
851 /* Call this function to search an rtx_insn list to find one with insn uid UID,
852 and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
853 The found insn is returned to enable further debugging analysis. */
855 DEBUG_FUNCTION const rtx_insn *
856 debug_rtx_find (const rtx_insn *x, int uid)
858 while (x != 0 && INSN_UID (x) != uid)
859 x = NEXT_INSN (x);
860 if (x != 0)
862 debug_rtx_list (x, debug_rtx_count);
863 return x;
865 else
867 fprintf (stderr, "insn uid %d not found\n", uid);
868 return 0;
872 /* External entry point for printing a chain of insns
873 starting with RTX_FIRST.
874 A blank line separates insns.
876 If RTX_FIRST is not an insn, then it alone is printed, with no newline. */
878 void
879 rtx_writer::print_rtl (const_rtx rtx_first)
881 const rtx_insn *tmp_rtx;
883 if (rtx_first == 0)
885 fputs (print_rtx_head, m_outfile);
886 fputs ("(nil)\n", m_outfile);
888 else
889 switch (GET_CODE (rtx_first))
891 case INSN:
892 case JUMP_INSN:
893 case CALL_INSN:
894 case NOTE:
895 case CODE_LABEL:
896 case JUMP_TABLE_DATA:
897 case BARRIER:
898 for (tmp_rtx = as_a <const rtx_insn *> (rtx_first);
899 tmp_rtx != 0;
900 tmp_rtx = NEXT_INSN (tmp_rtx))
902 fputs (print_rtx_head, m_outfile);
903 print_rtx (tmp_rtx);
904 fprintf (m_outfile, "\n");
906 break;
908 default:
909 fputs (print_rtx_head, m_outfile);
910 print_rtx (rtx_first);
914 /* External entry point for printing a chain of insns
915 starting with RTX_FIRST onto file OUTF.
916 A blank line separates insns.
918 If RTX_FIRST is not an insn, then it alone is printed, with no newline. */
920 void
921 print_rtl (FILE *outf, const_rtx rtx_first)
923 rtx_writer w (outf, 0, false, false);
924 w.print_rtl (rtx_first);
927 /* Like print_rtx, except specify a file. */
928 /* Return nonzero if we actually printed anything. */
931 print_rtl_single (FILE *outf, const_rtx x)
933 rtx_writer w (outf, 0, false, false);
934 return w.print_rtl_single_with_indent (x, 0);
937 /* Like print_rtl_single, except specify an indentation. */
940 rtx_writer::print_rtl_single_with_indent (const_rtx x, int ind)
942 char *s_indent = (char *) alloca ((size_t) ind + 1);
943 memset ((void *) s_indent, ' ', (size_t) ind);
944 s_indent[ind] = '\0';
945 fputs (s_indent, m_outfile);
946 fputs (print_rtx_head, m_outfile);
948 int old_indent = m_indent;
949 m_indent = ind;
950 m_sawclose = 0;
951 print_rtx (x);
952 putc ('\n', m_outfile);
953 m_indent = old_indent;
954 return 1;
958 /* Like print_rtl except without all the detail; for example,
959 if RTX is a CONST_INT then print in decimal format. */
961 void
962 print_simple_rtl (FILE *outf, const_rtx x)
964 rtx_writer w (outf, 0, true, false);
965 w.print_rtl (x);
968 /* Print the elements of VEC to FILE. */
970 void
971 print_rtx_insn_vec (FILE *file, const vec<rtx_insn *> &vec)
973 fputc('{', file);
975 unsigned int len = vec.length ();
976 for (unsigned int i = 0; i < len; i++)
978 print_rtl (file, vec[i]);
979 if (i < len - 1)
980 fputs (", ", file);
983 fputc ('}', file);
986 #ifndef GENERATOR_FILE
987 /* The functions below try to print RTL in a form resembling assembler
988 mnemonics. Because this form is more concise than the "traditional" form
989 of RTL printing in Lisp-style, the form printed by this file is called
990 "slim". RTL dumps in slim format can be obtained by appending the "-slim"
991 option to -fdump-rtl-<pass>. Control flow graph output as a DOT file is
992 always printed in slim form.
994 The normal interface to the functionality provided in this pretty-printer
995 is through the dump_*_slim functions to print to a stream, or via the
996 print_*_slim functions to print into a user's pretty-printer.
998 It is also possible to obtain a string for a single pattern as a string
999 pointer, via str_pattern_slim, but this usage is discouraged. */
1001 /* For insns we print patterns, and for some patterns we print insns... */
1002 static void print_insn_with_notes (pretty_printer *, const rtx_insn *);
1004 /* This recognizes rtx'en classified as expressions. These are always
1005 represent some action on values or results of other expression, that
1006 may be stored in objects representing values. */
1008 static void
1009 print_exp (pretty_printer *pp, const_rtx x, int verbose)
1011 const char *st[4];
1012 const char *fun;
1013 rtx op[4];
1014 int i;
1016 fun = (char *) 0;
1017 for (i = 0; i < 4; i++)
1019 st[i] = (char *) 0;
1020 op[i] = NULL_RTX;
1023 switch (GET_CODE (x))
1025 case PLUS:
1026 op[0] = XEXP (x, 0);
1027 if (CONST_INT_P (XEXP (x, 1))
1028 && INTVAL (XEXP (x, 1)) < 0)
1030 st[1] = "-";
1031 op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
1033 else
1035 st[1] = "+";
1036 op[1] = XEXP (x, 1);
1038 break;
1039 case LO_SUM:
1040 op[0] = XEXP (x, 0);
1041 st[1] = "+low(";
1042 op[1] = XEXP (x, 1);
1043 st[2] = ")";
1044 break;
1045 case MINUS:
1046 op[0] = XEXP (x, 0);
1047 st[1] = "-";
1048 op[1] = XEXP (x, 1);
1049 break;
1050 case COMPARE:
1051 fun = "cmp";
1052 op[0] = XEXP (x, 0);
1053 op[1] = XEXP (x, 1);
1054 break;
1055 case NEG:
1056 st[0] = "-";
1057 op[0] = XEXP (x, 0);
1058 break;
1059 case FMA:
1060 st[0] = "{";
1061 op[0] = XEXP (x, 0);
1062 st[1] = "*";
1063 op[1] = XEXP (x, 1);
1064 st[2] = "+";
1065 op[2] = XEXP (x, 2);
1066 st[3] = "}";
1067 break;
1068 case MULT:
1069 op[0] = XEXP (x, 0);
1070 st[1] = "*";
1071 op[1] = XEXP (x, 1);
1072 break;
1073 case DIV:
1074 op[0] = XEXP (x, 0);
1075 st[1] = "/";
1076 op[1] = XEXP (x, 1);
1077 break;
1078 case UDIV:
1079 fun = "udiv";
1080 op[0] = XEXP (x, 0);
1081 op[1] = XEXP (x, 1);
1082 break;
1083 case MOD:
1084 op[0] = XEXP (x, 0);
1085 st[1] = "%";
1086 op[1] = XEXP (x, 1);
1087 break;
1088 case UMOD:
1089 fun = "umod";
1090 op[0] = XEXP (x, 0);
1091 op[1] = XEXP (x, 1);
1092 break;
1093 case SMIN:
1094 fun = "smin";
1095 op[0] = XEXP (x, 0);
1096 op[1] = XEXP (x, 1);
1097 break;
1098 case SMAX:
1099 fun = "smax";
1100 op[0] = XEXP (x, 0);
1101 op[1] = XEXP (x, 1);
1102 break;
1103 case UMIN:
1104 fun = "umin";
1105 op[0] = XEXP (x, 0);
1106 op[1] = XEXP (x, 1);
1107 break;
1108 case UMAX:
1109 fun = "umax";
1110 op[0] = XEXP (x, 0);
1111 op[1] = XEXP (x, 1);
1112 break;
1113 case NOT:
1114 st[0] = "!";
1115 op[0] = XEXP (x, 0);
1116 break;
1117 case AND:
1118 op[0] = XEXP (x, 0);
1119 st[1] = "&";
1120 op[1] = XEXP (x, 1);
1121 break;
1122 case IOR:
1123 op[0] = XEXP (x, 0);
1124 st[1] = "|";
1125 op[1] = XEXP (x, 1);
1126 break;
1127 case XOR:
1128 op[0] = XEXP (x, 0);
1129 st[1] = "^";
1130 op[1] = XEXP (x, 1);
1131 break;
1132 case ASHIFT:
1133 op[0] = XEXP (x, 0);
1134 st[1] = "<<";
1135 op[1] = XEXP (x, 1);
1136 break;
1137 case LSHIFTRT:
1138 op[0] = XEXP (x, 0);
1139 st[1] = " 0>>";
1140 op[1] = XEXP (x, 1);
1141 break;
1142 case ASHIFTRT:
1143 op[0] = XEXP (x, 0);
1144 st[1] = ">>";
1145 op[1] = XEXP (x, 1);
1146 break;
1147 case ROTATE:
1148 op[0] = XEXP (x, 0);
1149 st[1] = "<-<";
1150 op[1] = XEXP (x, 1);
1151 break;
1152 case ROTATERT:
1153 op[0] = XEXP (x, 0);
1154 st[1] = ">->";
1155 op[1] = XEXP (x, 1);
1156 break;
1157 case NE:
1158 op[0] = XEXP (x, 0);
1159 st[1] = "!=";
1160 op[1] = XEXP (x, 1);
1161 break;
1162 case EQ:
1163 op[0] = XEXP (x, 0);
1164 st[1] = "==";
1165 op[1] = XEXP (x, 1);
1166 break;
1167 case GE:
1168 op[0] = XEXP (x, 0);
1169 st[1] = ">=";
1170 op[1] = XEXP (x, 1);
1171 break;
1172 case GT:
1173 op[0] = XEXP (x, 0);
1174 st[1] = ">";
1175 op[1] = XEXP (x, 1);
1176 break;
1177 case LE:
1178 op[0] = XEXP (x, 0);
1179 st[1] = "<=";
1180 op[1] = XEXP (x, 1);
1181 break;
1182 case LT:
1183 op[0] = XEXP (x, 0);
1184 st[1] = "<";
1185 op[1] = XEXP (x, 1);
1186 break;
1187 case SIGN_EXTRACT:
1188 fun = (verbose) ? "sign_extract" : "sxt";
1189 op[0] = XEXP (x, 0);
1190 op[1] = XEXP (x, 1);
1191 op[2] = XEXP (x, 2);
1192 break;
1193 case ZERO_EXTRACT:
1194 fun = (verbose) ? "zero_extract" : "zxt";
1195 op[0] = XEXP (x, 0);
1196 op[1] = XEXP (x, 1);
1197 op[2] = XEXP (x, 2);
1198 break;
1199 case SIGN_EXTEND:
1200 fun = (verbose) ? "sign_extend" : "sxn";
1201 op[0] = XEXP (x, 0);
1202 break;
1203 case ZERO_EXTEND:
1204 fun = (verbose) ? "zero_extend" : "zxn";
1205 op[0] = XEXP (x, 0);
1206 break;
1207 case FLOAT_EXTEND:
1208 fun = (verbose) ? "float_extend" : "fxn";
1209 op[0] = XEXP (x, 0);
1210 break;
1211 case TRUNCATE:
1212 fun = (verbose) ? "trunc" : "trn";
1213 op[0] = XEXP (x, 0);
1214 break;
1215 case FLOAT_TRUNCATE:
1216 fun = (verbose) ? "float_trunc" : "ftr";
1217 op[0] = XEXP (x, 0);
1218 break;
1219 case FLOAT:
1220 fun = (verbose) ? "float" : "flt";
1221 op[0] = XEXP (x, 0);
1222 break;
1223 case UNSIGNED_FLOAT:
1224 fun = (verbose) ? "uns_float" : "ufl";
1225 op[0] = XEXP (x, 0);
1226 break;
1227 case FIX:
1228 fun = "fix";
1229 op[0] = XEXP (x, 0);
1230 break;
1231 case UNSIGNED_FIX:
1232 fun = (verbose) ? "uns_fix" : "ufx";
1233 op[0] = XEXP (x, 0);
1234 break;
1235 case PRE_DEC:
1236 st[0] = "--";
1237 op[0] = XEXP (x, 0);
1238 break;
1239 case PRE_INC:
1240 st[0] = "++";
1241 op[0] = XEXP (x, 0);
1242 break;
1243 case POST_DEC:
1244 op[0] = XEXP (x, 0);
1245 st[1] = "--";
1246 break;
1247 case POST_INC:
1248 op[0] = XEXP (x, 0);
1249 st[1] = "++";
1250 break;
1251 case PRE_MODIFY:
1252 st[0] = "pre ";
1253 op[0] = XEXP (XEXP (x, 1), 0);
1254 st[1] = "+=";
1255 op[1] = XEXP (XEXP (x, 1), 1);
1256 break;
1257 case POST_MODIFY:
1258 st[0] = "post ";
1259 op[0] = XEXP (XEXP (x, 1), 0);
1260 st[1] = "+=";
1261 op[1] = XEXP (XEXP (x, 1), 1);
1262 break;
1263 case CALL:
1264 st[0] = "call ";
1265 op[0] = XEXP (x, 0);
1266 if (verbose)
1268 st[1] = " argc:";
1269 op[1] = XEXP (x, 1);
1271 break;
1272 case IF_THEN_ELSE:
1273 st[0] = "{(";
1274 op[0] = XEXP (x, 0);
1275 st[1] = ")?";
1276 op[1] = XEXP (x, 1);
1277 st[2] = ":";
1278 op[2] = XEXP (x, 2);
1279 st[3] = "}";
1280 break;
1281 case TRAP_IF:
1282 fun = "trap_if";
1283 op[0] = TRAP_CONDITION (x);
1284 break;
1285 case PREFETCH:
1286 fun = "prefetch";
1287 op[0] = XEXP (x, 0);
1288 op[1] = XEXP (x, 1);
1289 op[2] = XEXP (x, 2);
1290 break;
1291 case UNSPEC:
1292 case UNSPEC_VOLATILE:
1294 pp_string (pp, "unspec");
1295 if (GET_CODE (x) == UNSPEC_VOLATILE)
1296 pp_string (pp, "/v");
1297 pp_left_bracket (pp);
1298 for (i = 0; i < XVECLEN (x, 0); i++)
1300 if (i != 0)
1301 pp_comma (pp);
1302 print_pattern (pp, XVECEXP (x, 0, i), verbose);
1304 pp_string (pp, "] ");
1305 pp_decimal_int (pp, XINT (x, 1));
1307 break;
1308 default:
1310 /* Most unhandled codes can be printed as pseudo-functions. */
1311 if (GET_RTX_CLASS (GET_CODE (x)) == RTX_UNARY)
1313 fun = GET_RTX_NAME (GET_CODE (x));
1314 op[0] = XEXP (x, 0);
1316 else if (GET_RTX_CLASS (GET_CODE (x)) == RTX_COMPARE
1317 || GET_RTX_CLASS (GET_CODE (x)) == RTX_COMM_COMPARE
1318 || GET_RTX_CLASS (GET_CODE (x)) == RTX_BIN_ARITH
1319 || GET_RTX_CLASS (GET_CODE (x)) == RTX_COMM_ARITH)
1321 fun = GET_RTX_NAME (GET_CODE (x));
1322 op[0] = XEXP (x, 0);
1323 op[1] = XEXP (x, 1);
1325 else if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY)
1327 fun = GET_RTX_NAME (GET_CODE (x));
1328 op[0] = XEXP (x, 0);
1329 op[1] = XEXP (x, 1);
1330 op[2] = XEXP (x, 2);
1332 else
1333 /* Give up, just print the RTX name. */
1334 st[0] = GET_RTX_NAME (GET_CODE (x));
1336 break;
1339 /* Print this as a function? */
1340 if (fun)
1342 pp_string (pp, fun);
1343 pp_left_paren (pp);
1346 for (i = 0; i < 4; i++)
1348 if (st[i])
1349 pp_string (pp, st[i]);
1351 if (op[i])
1353 if (fun && i != 0)
1354 pp_comma (pp);
1355 print_value (pp, op[i], verbose);
1359 if (fun)
1360 pp_right_paren (pp);
1361 } /* print_exp */
1363 /* Prints rtxes, I customarily classified as values. They're constants,
1364 registers, labels, symbols and memory accesses. */
1366 void
1367 print_value (pretty_printer *pp, const_rtx x, int verbose)
1369 char tmp[1024];
1371 if (!x)
1373 pp_string (pp, "(nil)");
1374 return;
1376 switch (GET_CODE (x))
1378 case CONST_INT:
1379 pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
1380 (unsigned HOST_WIDE_INT) INTVAL (x));
1381 break;
1383 case CONST_WIDE_INT:
1385 const char *sep = "<";
1386 int i;
1387 for (i = CONST_WIDE_INT_NUNITS (x) - 1; i >= 0; i--)
1389 pp_string (pp, sep);
1390 sep = ",";
1391 sprintf (tmp, HOST_WIDE_INT_PRINT_HEX,
1392 (unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (x, i));
1393 pp_string (pp, tmp);
1395 pp_greater (pp);
1397 break;
1399 case CONST_DOUBLE:
1400 if (FLOAT_MODE_P (GET_MODE (x)))
1402 real_to_decimal (tmp, CONST_DOUBLE_REAL_VALUE (x),
1403 sizeof (tmp), 0, 1);
1404 pp_string (pp, tmp);
1406 else
1407 pp_printf (pp, "<%wx,%wx>",
1408 (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
1409 (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
1410 break;
1411 case CONST_FIXED:
1412 fixed_to_decimal (tmp, CONST_FIXED_VALUE (x), sizeof (tmp));
1413 pp_string (pp, tmp);
1414 break;
1415 case CONST_STRING:
1416 pp_printf (pp, "\"%s\"", XSTR (x, 0));
1417 break;
1418 case SYMBOL_REF:
1419 pp_printf (pp, "`%s'", XSTR (x, 0));
1420 break;
1421 case LABEL_REF:
1422 pp_printf (pp, "L%d", INSN_UID (label_ref_label (x)));
1423 break;
1424 case CONST:
1425 case HIGH:
1426 case STRICT_LOW_PART:
1427 pp_printf (pp, "%s(", GET_RTX_NAME (GET_CODE (x)));
1428 print_value (pp, XEXP (x, 0), verbose);
1429 pp_right_paren (pp);
1430 break;
1431 case REG:
1432 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
1434 if (ISDIGIT (reg_names[REGNO (x)][0]))
1435 pp_modulo (pp);
1436 pp_string (pp, reg_names[REGNO (x)]);
1438 else
1439 pp_printf (pp, "r%d", REGNO (x));
1440 if (verbose)
1441 pp_printf (pp, ":%s", GET_MODE_NAME (GET_MODE (x)));
1442 break;
1443 case SUBREG:
1444 print_value (pp, SUBREG_REG (x), verbose);
1445 pp_printf (pp, "#%d", SUBREG_BYTE (x));
1446 break;
1447 case SCRATCH:
1448 case CC0:
1449 case PC:
1450 pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
1451 break;
1452 case MEM:
1453 pp_left_bracket (pp);
1454 print_value (pp, XEXP (x, 0), verbose);
1455 pp_right_bracket (pp);
1456 break;
1457 case DEBUG_EXPR:
1458 pp_printf (pp, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
1459 break;
1460 default:
1461 print_exp (pp, x, verbose);
1462 break;
1464 } /* print_value */
1466 /* The next step in insn detalization, its pattern recognition. */
1468 void
1469 print_pattern (pretty_printer *pp, const_rtx x, int verbose)
1471 if (! x)
1473 pp_string (pp, "(nil)");
1474 return;
1477 switch (GET_CODE (x))
1479 case SET:
1480 print_value (pp, SET_DEST (x), verbose);
1481 pp_equal (pp);
1482 print_value (pp, SET_SRC (x), verbose);
1483 break;
1484 case RETURN:
1485 case SIMPLE_RETURN:
1486 case EH_RETURN:
1487 pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
1488 break;
1489 case CALL:
1490 print_exp (pp, x, verbose);
1491 break;
1492 case CLOBBER:
1493 case USE:
1494 pp_printf (pp, "%s ", GET_RTX_NAME (GET_CODE (x)));
1495 print_value (pp, XEXP (x, 0), verbose);
1496 break;
1497 case VAR_LOCATION:
1498 pp_string (pp, "loc ");
1499 print_value (pp, PAT_VAR_LOCATION_LOC (x), verbose);
1500 break;
1501 case COND_EXEC:
1502 pp_left_paren (pp);
1503 if (GET_CODE (COND_EXEC_TEST (x)) == NE
1504 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
1505 print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
1506 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
1507 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
1509 pp_exclamation (pp);
1510 print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
1512 else
1513 print_value (pp, COND_EXEC_TEST (x), verbose);
1514 pp_string (pp, ") ");
1515 print_pattern (pp, COND_EXEC_CODE (x), verbose);
1516 break;
1517 case PARALLEL:
1519 int i;
1521 pp_left_brace (pp);
1522 for (i = 0; i < XVECLEN (x, 0); i++)
1524 print_pattern (pp, XVECEXP (x, 0, i), verbose);
1525 pp_semicolon (pp);
1527 pp_right_brace (pp);
1529 break;
1530 case SEQUENCE:
1532 const rtx_sequence *seq = as_a <const rtx_sequence *> (x);
1533 pp_string (pp, "sequence{");
1534 if (INSN_P (seq->element (0)))
1536 /* Print the sequence insns indented. */
1537 const char * save_print_rtx_head = print_rtx_head;
1538 char indented_print_rtx_head[32];
1540 pp_newline (pp);
1541 gcc_assert (strlen (print_rtx_head) < sizeof (indented_print_rtx_head) - 4);
1542 snprintf (indented_print_rtx_head,
1543 sizeof (indented_print_rtx_head),
1544 "%s ", print_rtx_head);
1545 print_rtx_head = indented_print_rtx_head;
1546 for (int i = 0; i < seq->len (); i++)
1547 print_insn_with_notes (pp, seq->insn (i));
1548 pp_printf (pp, "%s ", save_print_rtx_head);
1549 print_rtx_head = save_print_rtx_head;
1551 else
1553 for (int i = 0; i < seq->len (); i++)
1555 print_pattern (pp, seq->element (i), verbose);
1556 pp_semicolon (pp);
1559 pp_right_brace (pp);
1561 break;
1562 case ASM_INPUT:
1563 pp_printf (pp, "asm {%s}", XSTR (x, 0));
1564 break;
1565 case ADDR_VEC:
1566 for (int i = 0; i < XVECLEN (x, 0); i++)
1568 print_value (pp, XVECEXP (x, 0, i), verbose);
1569 pp_semicolon (pp);
1571 break;
1572 case ADDR_DIFF_VEC:
1573 for (int i = 0; i < XVECLEN (x, 1); i++)
1575 print_value (pp, XVECEXP (x, 1, i), verbose);
1576 pp_semicolon (pp);
1578 break;
1579 case TRAP_IF:
1580 pp_string (pp, "trap_if ");
1581 print_value (pp, TRAP_CONDITION (x), verbose);
1582 break;
1583 case UNSPEC:
1584 case UNSPEC_VOLATILE:
1585 /* Fallthru -- leave UNSPECs to print_exp. */
1586 default:
1587 print_value (pp, x, verbose);
1589 } /* print_pattern */
1591 /* This is the main function in slim rtl visualization mechanism.
1593 X is an insn, to be printed into PP.
1595 This function tries to print it properly in human-readable form,
1596 resembling assembler mnemonics (instead of the older Lisp-style
1597 form).
1599 If VERBOSE is TRUE, insns are printed with more complete (but
1600 longer) pattern names and with extra information, and prefixed
1601 with their INSN_UIDs. */
1603 void
1604 print_insn (pretty_printer *pp, const rtx_insn *x, int verbose)
1606 if (verbose)
1608 /* Blech, pretty-print can't print integers with a specified width. */
1609 char uid_prefix[32];
1610 snprintf (uid_prefix, sizeof uid_prefix, " %4d: ", INSN_UID (x));
1611 pp_string (pp, uid_prefix);
1614 switch (GET_CODE (x))
1616 case INSN:
1617 print_pattern (pp, PATTERN (x), verbose);
1618 break;
1620 case DEBUG_INSN:
1622 const char *name = "?";
1624 if (DECL_P (INSN_VAR_LOCATION_DECL (x)))
1626 tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (x));
1627 char idbuf[32];
1628 if (id)
1629 name = IDENTIFIER_POINTER (id);
1630 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x))
1631 == DEBUG_EXPR_DECL)
1633 sprintf (idbuf, "D#%i",
1634 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x)));
1635 name = idbuf;
1637 else
1639 sprintf (idbuf, "D.%i",
1640 DECL_UID (INSN_VAR_LOCATION_DECL (x)));
1641 name = idbuf;
1644 pp_printf (pp, "debug %s => ", name);
1645 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x)))
1646 pp_string (pp, "optimized away");
1647 else
1648 print_pattern (pp, INSN_VAR_LOCATION_LOC (x), verbose);
1650 break;
1652 case JUMP_INSN:
1653 print_pattern (pp, PATTERN (x), verbose);
1654 break;
1655 case CALL_INSN:
1656 if (GET_CODE (PATTERN (x)) == PARALLEL)
1657 print_pattern (pp, XVECEXP (PATTERN (x), 0, 0), verbose);
1658 else
1659 print_pattern (pp, PATTERN (x), verbose);
1660 break;
1661 case CODE_LABEL:
1662 pp_printf (pp, "L%d:", INSN_UID (x));
1663 break;
1664 case JUMP_TABLE_DATA:
1665 pp_string (pp, "jump_table_data{\n");
1666 print_pattern (pp, PATTERN (x), verbose);
1667 pp_right_brace (pp);
1668 break;
1669 case BARRIER:
1670 pp_string (pp, "barrier");
1671 break;
1672 case NOTE:
1674 pp_string (pp, GET_NOTE_INSN_NAME (NOTE_KIND (x)));
1675 switch (NOTE_KIND (x))
1677 case NOTE_INSN_EH_REGION_BEG:
1678 case NOTE_INSN_EH_REGION_END:
1679 pp_printf (pp, " %d", NOTE_EH_HANDLER (x));
1680 break;
1682 case NOTE_INSN_BLOCK_BEG:
1683 case NOTE_INSN_BLOCK_END:
1684 pp_printf (pp, " %d", BLOCK_NUMBER (NOTE_BLOCK (x)));
1685 break;
1687 case NOTE_INSN_BASIC_BLOCK:
1688 pp_printf (pp, " %d", NOTE_BASIC_BLOCK (x)->index);
1689 break;
1691 case NOTE_INSN_DELETED_LABEL:
1692 case NOTE_INSN_DELETED_DEBUG_LABEL:
1694 const char *label = NOTE_DELETED_LABEL_NAME (x);
1695 if (label == NULL)
1696 label = "";
1697 pp_printf (pp, " (\"%s\")", label);
1699 break;
1701 case NOTE_INSN_VAR_LOCATION:
1702 case NOTE_INSN_CALL_ARG_LOCATION:
1703 pp_left_brace (pp);
1704 print_pattern (pp, NOTE_VAR_LOCATION (x), verbose);
1705 pp_right_brace (pp);
1706 break;
1708 default:
1709 break;
1711 break;
1713 default:
1714 gcc_unreachable ();
1716 } /* print_insn */
1718 /* Pretty-print a slim dump of X (an insn) to PP, including any register
1719 note attached to the instruction. */
1721 static void
1722 print_insn_with_notes (pretty_printer *pp, const rtx_insn *x)
1724 pp_string (pp, print_rtx_head);
1725 print_insn (pp, x, 1);
1726 pp_newline (pp);
1727 if (INSN_P (x) && REG_NOTES (x))
1728 for (rtx note = REG_NOTES (x); note; note = XEXP (note, 1))
1730 pp_printf (pp, "%s %s ", print_rtx_head,
1731 GET_REG_NOTE_NAME (REG_NOTE_KIND (note)));
1732 if (GET_CODE (note) == INT_LIST)
1733 pp_printf (pp, "%d", XINT (note, 0));
1734 else
1735 print_pattern (pp, XEXP (note, 0), 1);
1736 pp_newline (pp);
1740 /* Print X, an RTL value node, to file F in slim format. Include
1741 additional information if VERBOSE is nonzero.
1743 Value nodes are constants, registers, labels, symbols and
1744 memory. */
1746 void
1747 dump_value_slim (FILE *f, const_rtx x, int verbose)
1749 pretty_printer rtl_slim_pp;
1750 rtl_slim_pp.buffer->stream = f;
1751 print_value (&rtl_slim_pp, x, verbose);
1752 pp_flush (&rtl_slim_pp);
1755 /* Emit a slim dump of X (an insn) to the file F, including any register
1756 note attached to the instruction. */
1757 void
1758 dump_insn_slim (FILE *f, const rtx_insn *x)
1760 pretty_printer rtl_slim_pp;
1761 rtl_slim_pp.buffer->stream = f;
1762 print_insn_with_notes (&rtl_slim_pp, x);
1763 pp_flush (&rtl_slim_pp);
1766 /* Same as above, but stop at LAST or when COUNT == 0.
1767 If COUNT < 0 it will stop only at LAST or NULL rtx. */
1769 void
1770 dump_rtl_slim (FILE *f, const rtx_insn *first, const rtx_insn *last,
1771 int count, int flags ATTRIBUTE_UNUSED)
1773 const rtx_insn *insn, *tail;
1774 pretty_printer rtl_slim_pp;
1775 rtl_slim_pp.buffer->stream = f;
1777 tail = last ? NEXT_INSN (last) : NULL;
1778 for (insn = first;
1779 (insn != NULL) && (insn != tail) && (count != 0);
1780 insn = NEXT_INSN (insn))
1782 print_insn_with_notes (&rtl_slim_pp, insn);
1783 if (count > 0)
1784 count--;
1787 pp_flush (&rtl_slim_pp);
1790 /* Dumps basic block BB to pretty-printer PP in slim form and without and
1791 no indentation, for use as a label of a DOT graph record-node. */
1793 void
1794 rtl_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
1796 rtx_insn *insn;
1797 bool first = true;
1799 /* TODO: inter-bb stuff. */
1800 FOR_BB_INSNS (bb, insn)
1802 if (! first)
1804 pp_bar (pp);
1805 pp_write_text_to_stream (pp);
1807 first = false;
1808 print_insn_with_notes (pp, insn);
1809 pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true);
1813 /* Pretty-print pattern X of some insn in non-verbose mode.
1814 Return a string pointer to the pretty-printer buffer.
1816 This function is only exported exists only to accommodate some older users
1817 of the slim RTL pretty printers. Please do not use it for new code. */
1819 const char *
1820 str_pattern_slim (const_rtx x)
1822 pretty_printer rtl_slim_pp;
1823 print_pattern (&rtl_slim_pp, x, 0);
1824 return ggc_strdup (pp_formatted_text (&rtl_slim_pp));
1827 /* Emit a slim dump of X (an insn) to stderr. */
1828 extern void debug_insn_slim (const rtx_insn *);
1829 DEBUG_FUNCTION void
1830 debug_insn_slim (const rtx_insn *x)
1832 dump_insn_slim (stderr, x);
1835 /* Same as above, but using dump_rtl_slim. */
1836 extern void debug_rtl_slim (FILE *, const rtx_insn *, const rtx_insn *,
1837 int, int);
1838 DEBUG_FUNCTION void
1839 debug_rtl_slim (const rtx_insn *first, const rtx_insn *last, int count,
1840 int flags)
1842 dump_rtl_slim (stderr, first, last, count, flags);
1845 extern void debug_bb_slim (basic_block);
1846 DEBUG_FUNCTION void
1847 debug_bb_slim (basic_block bb)
1849 dump_bb (stderr, bb, 0, TDF_SLIM | TDF_BLOCKS);
1852 extern void debug_bb_n_slim (int);
1853 DEBUG_FUNCTION void
1854 debug_bb_n_slim (int n)
1856 basic_block bb = BASIC_BLOCK_FOR_FN (cfun, n);
1857 debug_bb_slim (bb);
1860 #endif