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