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