]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/print-rtl.c
Update copyright years.
[thirdparty/gcc.git] / gcc / print-rtl.c
CommitLineData
bccafa26 1/* Print RTL for GCC.
f1717362 2 Copyright (C) 1987-2016 Free Software Foundation, Inc.
0b8a940f 3
f12b58b3 4This file is part of GCC.
0b8a940f 5
f12b58b3 6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8c4c00c1 8Software Foundation; either version 3, or (at your option) any later
f12b58b3 9version.
0b8a940f 10
f12b58b3 11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
0b8a940f 15
16You should have received a copy of the GNU General Public License
8c4c00c1 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
0b8a940f 19
690ff52f 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
0b8a940f 25#include "config.h"
690ff52f 26#endif
27
405711de 28#include "system.h"
805e22b2 29#include "coretypes.h"
30#include "tm.h"
0b8a940f 31#include "rtl.h"
96216d37 32
690ff52f 33/* These headers all define things which are not available in
34 generator programs. */
35#ifndef GENERATOR_FILE
b20a8bb4 36#include "alias.h"
96216d37 37#include "tree.h"
397881d3 38#include "cfg.h"
9ed99284 39#include "print-tree.h"
fd63ca43 40#include "flags.h"
94ea8568 41#include "predict.h"
94ea8568 42#include "function.h"
71caadc0 43#include "basic-block.h"
3a443843 44#include "diagnostic.h"
ce084dfc 45#include "tree-pretty-print.h"
f7d27fdc 46#include "alloc-pool.h"
9845d120 47#include "cselib.h"
b9ed1410 48#include "dumpfile.h" /* for dump_flags */
d53ccf7b 49#include "dwarf2out.h"
397881d3 50#include "pretty-print.h"
690ff52f 51#endif
2cc0ea94 52
397881d3 53#include "print-rtl.h"
54
0b8a940f 55static FILE *outfile;
56
0b8a940f 57static int sawclose = 0;
58
6a71e6dc 59static int indent;
60
7c3f3cf3 61static bool in_call_function_usage;
62
dd9b9fc5 63static void print_rtx (const_rtx);
e2d60f26 64
af5e5fd0 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. */
52fd6db3 68const char *print_rtx_head = "";
af5e5fd0 69
0f8defe5 70#ifdef GENERATOR_FILE
71/* These are defined from the .opt file when not used in generator
72 programs. */
73
60ad3b0e 74/* Nonzero means suppress output of instruction numbers
75 in debugging dumps.
fd63ca43 76 This must be defined here so that programs like gencodes can be linked. */
9e042f31 77int flag_dump_unnumbered = 0;
fd63ca43 78
0a59e439 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. */
82int flag_dump_unnumbered_links = 0;
0f8defe5 83#endif
0a59e439 84
ad4b6bdf 85/* Nonzero means use simplified format without flags, modes, etc. */
86int flag_simple = 0;
87
690ff52f 88#ifndef GENERATOR_FILE
b10dbbca 89void
dd9b9fc5 90print_mem_expr (FILE *outfile, const_tree expr)
b10dbbca 91{
3a443843 92 fputc (' ', outfile);
00753696 93 print_generic_expr (outfile, CONST_CAST_TREE (expr), dump_flags);
b10dbbca 94}
690ff52f 95#endif
b10dbbca 96
0b8a940f 97/* Print IN_RTX onto OUTFILE. This is the recursive part of printing. */
98
99static void
dd9b9fc5 100print_rtx (const_rtx in_rtx)
0b8a940f 101{
19cb6b50 102 int i = 0;
103 int j;
104 const char *format_ptr;
105 int is_insn;
0b8a940f 106
107 if (sawclose)
108 {
ad4b6bdf 109 if (flag_simple)
110 fputc (' ', outfile);
111 else
9c59a260 112 fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, "");
0b8a940f 113 sawclose = 0;
114 }
115
116 if (in_rtx == 0)
117 {
3eaf50a4 118 fputs ("(nil)", outfile);
0b8a940f 119 sawclose = 1;
120 return;
121 }
9c59a260 122 else if (GET_CODE (in_rtx) > NUM_RTX_CODE)
123 {
434b69b9 124 fprintf (outfile, "(??? bad code %d\n%s%*s)", GET_CODE (in_rtx),
125 print_rtx_head, indent * 2, "");
9c59a260 126 sawclose = 1;
127 return;
128 }
0b8a940f 129
9c59a260 130 is_insn = INSN_P (in_rtx);
3eaf50a4 131
f4b3647a 132 /* Print name of expression code. */
133 if (flag_simple && CONST_INT_P (in_rtx))
134 fputc ('(', outfile);
3eaf50a4 135 else
f4b3647a 136 fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
195731ad 137
f4b3647a 138 if (! flag_simple)
139 {
140 if (RTX_FLAG (in_rtx, in_struct))
141 fputs ("/s", outfile);
ad4b6bdf 142
f4b3647a 143 if (RTX_FLAG (in_rtx, volatil))
144 fputs ("/v", outfile);
195731ad 145
f4b3647a 146 if (RTX_FLAG (in_rtx, unchanging))
147 fputs ("/u", outfile);
195731ad 148
f4b3647a 149 if (RTX_FLAG (in_rtx, frame_related))
150 fputs ("/f", outfile);
195731ad 151
f4b3647a 152 if (RTX_FLAG (in_rtx, jump))
153 fputs ("/j", outfile);
195731ad 154
f4b3647a 155 if (RTX_FLAG (in_rtx, call))
156 fputs ("/c", outfile);
ad4b6bdf 157
f4b3647a 158 if (RTX_FLAG (in_rtx, return_val))
159 fputs ("/i", outfile);
4ee9c684 160
f4b3647a 161 /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */
162 if ((GET_CODE (in_rtx) == EXPR_LIST
9eb946de 163 || GET_CODE (in_rtx) == INSN_LIST
164 || GET_CODE (in_rtx) == INT_LIST)
7c3f3cf3 165 && (int)GET_MODE (in_rtx) < REG_NOTE_MAX
166 && !in_call_function_usage)
f4b3647a 167 fprintf (outfile, ":%s",
168 GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
99caba0f 169
f4b3647a 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)));
9845d120 173
174#ifndef GENERATOR_FILE
f4b3647a 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);
3eaf50a4 188 }
f4b3647a 189#endif
0b8a940f 190 }
191
76834cda 192#ifndef GENERATOR_FILE
78f1962f 193 if (CONST_DOUBLE_AS_FLOAT_P (in_rtx))
76834cda 194 i = 5;
195#endif
196
5cda2bd0 197 if (INSN_CHAIN_CODE_P (GET_CODE (in_rtx)))
a8336256 198 {
199 if (flag_dump_unnumbered)
200 fprintf (outfile, " #");
201 else
202 fprintf (outfile, " %d", INSN_UID (in_rtx));
203 }
5cda2bd0 204
3eaf50a4 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;
3eaf50a4 208 for (; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
0b8a940f 209 switch (*format_ptr++)
210 {
9abd2cd7 211 const char *str;
212
213 case 'T':
214 str = XTMPL (in_rtx, i);
215 goto string;
216
0b8a940f 217 case 'S':
218 case 's':
9abd2cd7 219 str = XSTR (in_rtx, i);
220 string:
221
222 if (str == 0)
f4b3647a 223 fputs (" \"\"", outfile);
0b8a940f 224 else
f4b3647a 225 fprintf (outfile, " (\"%s\")", str);
0b8a940f 226 sawclose = 1;
227 break;
228
a4070a91 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. */
0b8a940f 232 case '0':
7bcffce7 233#ifndef GENERATOR_FILE
4db4d2a2 234 if (i == 1 && GET_CODE (in_rtx) == SYMBOL_REF)
001be062 235 {
236 int flags = SYMBOL_REF_FLAGS (in_rtx);
237 if (flags)
3eb9ad16 238 fprintf (outfile, " [flags %#x]", flags);
001be062 239 tree decl = SYMBOL_REF_DECL (in_rtx);
240 if (decl)
00753696 241 print_node_brief (outfile, "", decl, dump_flags);
001be062 242 }
5cda2bd0 243 else if (i == 3 && NOTE_P (in_rtx))
a4070a91 244 {
ad4583d9 245 switch (NOTE_KIND (in_rtx))
cc102912 246 {
89cfe6e5 247 case NOTE_INSN_EH_REGION_BEG:
248 case NOTE_INSN_EH_REGION_END:
dbbc6ff0 249 if (flag_dump_unnumbered)
250 fprintf (outfile, " #");
251 else
252 fprintf (outfile, " %d", NOTE_EH_HANDLER (in_rtx));
cc102912 253 sawclose = 1;
89cfe6e5 254 break;
255
256 case NOTE_INSN_BLOCK_BEG:
257 case NOTE_INSN_BLOCK_END:
969239ad 258 dump_addr (outfile, " ", NOTE_BLOCK (in_rtx));
a4070a91 259 sawclose = 1;
89cfe6e5 260 break;
261
89cfe6e5 262 case NOTE_INSN_BASIC_BLOCK:
263 {
264 basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
265 if (bb != 0)
b3d6de89 266 fprintf (outfile, " [bb %d]", bb->index);
89cfe6e5 267 break;
268 }
269
74b0991d 270 case NOTE_INSN_DELETED_LABEL:
63f5ad44 271 case NOTE_INSN_DELETED_DEBUG_LABEL:
7bd3dcc4 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 }
74b0991d 279 break;
280
1897b881 281 case NOTE_INSN_SWITCH_TEXT_SECTIONS:
4f18499c 282 {
283 basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
284 if (bb != 0)
285 fprintf (outfile, " [bb %d]", bb->index);
286 break;
287 }
48e1416a 288
5923a5e7 289 case NOTE_INSN_VAR_LOCATION:
4143d08b 290 case NOTE_INSN_CALL_ARG_LOCATION:
9845d120 291 fputc (' ', outfile);
292 print_rtx (NOTE_VAR_LOCATION (in_rtx));
5923a5e7 293 break;
294
d53ccf7b 295 case NOTE_INSN_CFI:
d53ccf7b 296 fputc ('\n', outfile);
297 output_cfi_directive (outfile, NOTE_CFI (in_rtx));
298 fputc ('\t', outfile);
d53ccf7b 299 break;
300
89cfe6e5 301 default:
ad4583d9 302 break;
a4070a91 303 }
304 }
5cda2bd0 305 else if (i == 7 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL)
4115ac36 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");
9cb2517e 311 else if (GET_CODE (JUMP_LABEL (in_rtx)) == SIMPLE_RETURN)
312 fprintf (outfile, "simple_return");
4115ac36 313 else
314 fprintf (outfile, "%d", INSN_UID (JUMP_LABEL (in_rtx)));
315 }
9845d120 316 else if (i == 0 && GET_CODE (in_rtx) == VALUE)
317 {
9845d120 318 cselib_val *val = CSELIB_VAL_PTR (in_rtx);
319
01df1184 320 fprintf (outfile, " %u:%u", val->uid, val->hash);
9845d120 321 dump_addr (outfile, " @", in_rtx);
322 dump_addr (outfile, "/", (void*)val);
688ff29b 323 }
324 else if (i == 0 && GET_CODE (in_rtx) == DEBUG_EXPR)
325 {
23dd51cb 326 fprintf (outfile, " D#%i",
327 DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (in_rtx)));
9845d120 328 }
a5701bde 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 }
7bcffce7 337#endif
0b8a940f 338 break;
339
340 case 'e':
0922b1b8 341 do_e:
0b8a940f 342 indent += 2;
5cda2bd0 343 if (i == 6 && INSN_P (in_rtx))
3a55c112 344 /* Put REG_NOTES on their own line. */
345 fprintf (outfile, "\n%s%*s",
346 print_rtx_head, indent * 2, "");
0b8a940f 347 if (!sawclose)
348 fprintf (outfile, " ");
5cda2bd0 349 if (i == 7 && CALL_P (in_rtx))
7c3f3cf3 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));
0b8a940f 357 indent -= 2;
358 break;
359
360 case 'E':
361 case 'V':
362 indent += 2;
363 if (sawclose)
364 {
232309ab 365 fprintf (outfile, "\n%s%*s",
195731ad 366 print_rtx_head, indent * 2, "");
0b8a940f 367 sawclose = 0;
368 }
68d9a03d 369 fputs (" [", outfile);
0b8a940f 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)
9c59a260 382 fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, "");
0b8a940f 383
68d9a03d 384 fputs ("]", outfile);
0b8a940f 385 sawclose = 1;
386 indent -= 2;
387 break;
388
2d618a37 389 case 'w':
ad4b6bdf 390 if (! flag_simple)
391 fprintf (outfile, " ");
c6946bfc 392 fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, i));
ad4b6bdf 393 if (! flag_simple)
85aa12f7 394 fprintf (outfile, " [" HOST_WIDE_INT_PRINT_HEX "]",
7df7561b 395 (unsigned HOST_WIDE_INT) XWINT (in_rtx, i));
2d618a37 396 break;
397
0b8a940f 398 case 'i':
5cda2bd0 399 if (i == 4 && INSN_P (in_rtx))
13751393 400 {
401#ifndef GENERATOR_FILE
5e9c670f 402 const rtx_insn *in_insn = as_a <const rtx_insn *> (in_rtx);
403
5169661d 404 /* Pretty-print insn locations. Ignore scoping as it is mostly
13751393 405 redundant with line number information and do not print anything
406 when there is no location information available. */
5e9c670f 407 if (INSN_HAS_LOCATION (in_insn))
0e7ae557 408 {
5e9c670f 409 expanded_location xloc = insn_location (in_insn);
0e7ae557 410 fprintf (outfile, " %s:%i", xloc.file, xloc.line);
411 }
1500062c 412#endif
413 }
414 else if (i == 6 && GET_CODE (in_rtx) == ASM_OPERANDS)
415 {
416#ifndef GENERATOR_FILE
c36804c0 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)));
1500062c 421#endif
422 }
423 else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
424 {
425#ifndef GENERATOR_FILE
c36804c0 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)));
13751393 430#endif
431 }
5cda2bd0 432 else if (i == 5 && NOTE_P (in_rtx))
66b6f98b 433 {
434 /* This field is only used for NOTE_INSN_DELETED_LABEL, and
435 other times often contains garbage from INSN->NOTE death. */
63f5ad44 436 if (NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_LABEL
437 || NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_DEBUG_LABEL)
66b6f98b 438 fprintf (outfile, " %d", XINT (in_rtx, i));
439 }
15f255bd 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
66b6f98b 455 else
456 {
19cb6b50 457 int value = XINT (in_rtx, i);
66b6f98b 458 const char *name;
2cc0ea94 459
15183fd2 460 if (flag_dump_unnumbered
461 && (is_insn || NOTE_P (in_rtx)))
66b6f98b 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 }
0b8a940f 472 break;
473
15183fd2 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
0b8a940f 526 /* Print NOTE_INSN names rather than integer codes. */
527
528 case 'n':
ad4583d9 529 fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
0b8a940f 530 sawclose = 0;
531 break;
532
533 case 'u':
534 if (XEXP (in_rtx, i) != NULL)
9e042f31 535 {
67b87c97 536 rtx sub = XEXP (in_rtx, i);
537 enum rtx_code subc = GET_CODE (sub);
538
74b0991d 539 if (GET_CODE (in_rtx) == LABEL_REF)
540 {
541 if (subc == NOTE
ad4583d9 542 && NOTE_KIND (sub) == NOTE_INSN_DELETED_LABEL)
74b0991d 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 }
0922b1b8 555
0a59e439 556 if (flag_dump_unnumbered
0b0771ad 557 || (flag_dump_unnumbered_links && i <= 1
0a59e439 558 && (INSN_P (in_rtx) || NOTE_P (in_rtx)
559 || LABEL_P (in_rtx) || BARRIER_P (in_rtx))))
74b0991d 560 fputs (" #", outfile);
9e042f31 561 else
67b87c97 562 fprintf (outfile, " %d", INSN_UID (sub));
9e042f31 563 }
0b8a940f 564 else
af40d96f 565 fputs (" 0", outfile);
50118dc3 566 sawclose = 0;
567 break;
568
a3426c4c 569 case 't':
969239ad 570#ifndef GENERATOR_FILE
f9c61ef7 571 if (i == 0 && GET_CODE (in_rtx) == DEBUG_IMPLICIT_PTR)
572 print_mem_expr (outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx));
841424cc 573 else if (i == 0 && GET_CODE (in_rtx) == DEBUG_PARAMETER_REF)
574 print_mem_expr (outfile, DEBUG_PARAMETER_REF_DECL (in_rtx));
f9c61ef7 575 else
576 dump_addr (outfile, " ", XTREE (in_rtx, i));
969239ad 577#endif
a3426c4c 578 break;
579
50118dc3 580 case '*':
3eaf50a4 581 fputs (" Unknown", outfile);
0b8a940f 582 sawclose = 0;
583 break;
584
ab87d1bc 585 case 'B':
690ff52f 586#ifndef GENERATOR_FILE
ab87d1bc 587 if (XBBDEF (in_rtx, i))
588 fprintf (outfile, " %i", XBBDEF (in_rtx, i)->index);
690ff52f 589#endif
ab87d1bc 590 break;
591
0b8a940f 592 default:
1fa3a8f6 593 gcc_unreachable ();
0b8a940f 594 }
595
74b0991d 596 switch (GET_CODE (in_rtx))
597 {
52717541 598#ifndef GENERATOR_FILE
74b0991d 599 case MEM:
090bd40b 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));
b10dbbca 605
606 if (MEM_EXPR (in_rtx))
607 print_mem_expr (outfile, MEM_EXPR (in_rtx));
af70b80f 608 else
609 fputc (' ', outfile);
96216d37 610
da443c27 611 if (MEM_OFFSET_KNOWN_P (in_rtx))
612 fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, MEM_OFFSET (in_rtx));
96216d37 613
5b2a69fa 614 if (MEM_SIZE_KNOWN_P (in_rtx))
615 fprintf (outfile, " S" HOST_WIDE_INT_PRINT_DEC, MEM_SIZE (in_rtx));
96216d37 616
617 if (MEM_ALIGN (in_rtx) != 1)
618 fprintf (outfile, " A%u", MEM_ALIGN (in_rtx));
619
bd1a81f7 620 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (in_rtx)))
621 fprintf (outfile, " AS%u", MEM_ADDR_SPACE (in_rtx));
622
96216d37 623 fputc (']', outfile);
74b0991d 624 break;
a1355ed3 625
74b0991d 626 case CONST_DOUBLE:
627 if (FLOAT_MODE_P (GET_MODE (in_rtx)))
628 {
98367734 629 char s[60];
badfe841 630
c7fbc741 631 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
632 sizeof (s), 0, 1);
76834cda 633 fprintf (outfile, " %s", s);
634
c7fbc741 635 real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
636 sizeof (s), 0, 1);
badfe841 637 fprintf (outfile, " [%s]", s);
74b0991d 638 }
639 break;
e913b5cd 640
641 case CONST_WIDE_INT:
c4050ce7 642 fprintf (outfile, " ");
05c25ee6 643 cwi_output_hex (outfile, in_rtx);
e913b5cd 644 break;
56609c6c 645#endif
646
74b0991d 647 case CODE_LABEL:
57404fb9 648 fprintf (outfile, " [%d uses]", LABEL_NUSES (in_rtx));
a7ae1e59 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;
876760f6 655 default: gcc_unreachable ();
a7ae1e59 656 }
74b0991d 657 break;
658
74b0991d 659 default:
660 break;
bfee5366 661 }
57404fb9 662
f4b3647a 663 fputc (')', outfile);
664 sawclose = 1;
0b8a940f 665}
666
6a71e6dc 667/* Print an rtx on the current line of FILE. Initially indent IND
668 characters. */
669
670void
dd9b9fc5 671print_inline_rtx (FILE *outf, const_rtx x, int ind)
6a71e6dc 672{
ad87de1e 673 int oldsaw = sawclose;
674 int oldindent = indent;
675
6a71e6dc 676 sawclose = 0;
677 indent = ind;
678 outfile = outf;
679 print_rtx (x);
ad87de1e 680 sawclose = oldsaw;
681 indent = oldindent;
6a71e6dc 682}
683
0b8a940f 684/* Call this function from the debugger to see what X looks like. */
685
4b987fac 686DEBUG_FUNCTION void
dd9b9fc5 687debug_rtx (const_rtx x)
0b8a940f 688{
689 outfile = stderr;
68d9a03d 690 sawclose = 0;
0b8a940f 691 print_rtx (x);
692 fprintf (stderr, "\n");
693}
694
c7d89805 695/* Dump rtx REF. */
696
697DEBUG_FUNCTION void
698debug (const rtx_def &ref)
699{
700 debug_rtx (&ref);
701}
702
703DEBUG_FUNCTION void
704debug (const rtx_def *ptr)
705{
706 if (ptr)
707 debug (*ptr);
708 else
709 fprintf (stderr, "<nil>\n");
710}
711
1c8c3750 712/* Count of rtx's to print with debug_rtx_list.
713 This global exists because gdb user defined commands have no arguments. */
714
4b987fac 715DEBUG_VARIABLE int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */
1c8c3750 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
831e913e 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). */
1c8c3750 723
4b987fac 724DEBUG_FUNCTION void
831e913e 725debug_rtx_list (const rtx_insn *x, int n)
1c8c3750 726{
727 int i,count;
831e913e 728 const rtx_insn *insn;
1c8c3750 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))
68d9a03d 743 {
744 debug_rtx (insn);
745 fprintf (stderr, "\n");
746 }
1c8c3750 747}
748
831e913e 749/* Call this function to print an rtx_insn list from START to END
750 inclusive. */
40977116 751
4b987fac 752DEBUG_FUNCTION void
831e913e 753debug_rtx_range (const rtx_insn *start, const rtx_insn *end)
40977116 754{
755 while (1)
756 {
757 debug_rtx (start);
68d9a03d 758 fprintf (stderr, "\n");
40977116 759 if (!start || start == end)
760 break;
761 start = NEXT_INSN (start);
762 }
763}
764
831e913e 765/* Call this function to search an rtx_insn list to find one with insn uid UID,
1c8c3750 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
9ed997be 769DEBUG_FUNCTION const rtx_insn *
831e913e 770debug_rtx_find (const rtx_insn *x, int uid)
1c8c3750 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
0b8a940f 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
792void
dd9b9fc5 793print_rtl (FILE *outf, const_rtx rtx_first)
0b8a940f 794{
831e913e 795 const rtx_insn *tmp_rtx;
60ad3b0e 796
0b8a940f 797 outfile = outf;
798 sawclose = 0;
799
800 if (rtx_first == 0)
af5e5fd0 801 {
802 fputs (print_rtx_head, outf);
803 fputs ("(nil)\n", outf);
804 }
0b8a940f 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:
91f71fa3 813 case JUMP_TABLE_DATA:
0b8a940f 814 case BARRIER:
831e913e 815 for (tmp_rtx = as_a <const rtx_insn *> (rtx_first);
816 tmp_rtx != 0;
817 tmp_rtx = NEXT_INSN (tmp_rtx))
60ad3b0e 818 {
819 fputs (print_rtx_head, outfile);
820 print_rtx (tmp_rtx);
821 fprintf (outfile, "\n");
822 }
0b8a940f 823 break;
824
825 default:
195731ad 826 fputs (print_rtx_head, outfile);
0b8a940f 827 print_rtx (rtx_first);
828 }
829}
f34a52ce 830
831/* Like print_rtx, except specify a file. */
fd63ca43 832/* Return nonzero if we actually printed anything. */
f34a52ce 833
fd63ca43 834int
dd9b9fc5 835print_rtl_single (FILE *outf, const_rtx x)
f34a52ce 836{
9631926a 837 return print_rtl_single_with_indent (outf, x, 0);
838}
839
840/* Like print_rtl_single, except specify a file and indentation. */
841
842int
843print_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;
f34a52ce 851 outfile = outf;
852 sawclose = 0;
9631926a 853 fputs (s_indent, outfile);
55420479 854 fputs (print_rtx_head, outfile);
855 print_rtx (x);
856 putc ('\n', outf);
9631926a 857 indent = old_indent;
55420479 858 return 1;
f34a52ce 859}
ad4b6bdf 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
865void
dd9b9fc5 866print_simple_rtl (FILE *outf, const_rtx x)
ad4b6bdf 867{
868 flag_simple = 1;
869 print_rtl (outf, x);
870 flag_simple = 0;
871}
397881d3 872
873#ifndef GENERATOR_FILE
874/* The functions below try to print RTL in a form resembling assembler
875 mnemonics. Because this form is more concise than the "traditional" form
876 of RTL printing in Lisp-style, the form printed by this file is called
877 "slim". RTL dumps in slim format can be obtained by appending the "-slim"
878 option to -fdump-rtl-<pass>. Control flow graph output as a DOT file is
879 always printed in slim form.
880
881 The normal interface to the functionality provided in this pretty-printer
882 is through the dump_*_slim functions to print to a stream, or via the
883 print_*_slim functions to print into a user's pretty-printer.
884
885 It is also possible to obtain a string for a single pattern as a string
886 pointer, via str_pattern_slim, but this usage is discouraged. */
887
888/* For insns we print patterns, and for some patterns we print insns... */
889static void print_insn_with_notes (pretty_printer *, const rtx_insn *);
890
891/* This recognizes rtx'en classified as expressions. These are always
892 represent some action on values or results of other expression, that
893 may be stored in objects representing values. */
894
895static void
896print_exp (pretty_printer *pp, const_rtx x, int verbose)
897{
898 const char *st[4];
899 const char *fun;
900 rtx op[4];
901 int i;
902
903 fun = (char *) 0;
904 for (i = 0; i < 4; i++)
905 {
906 st[i] = (char *) 0;
907 op[i] = NULL_RTX;
908 }
909
910 switch (GET_CODE (x))
911 {
912 case PLUS:
913 op[0] = XEXP (x, 0);
914 if (CONST_INT_P (XEXP (x, 1))
915 && INTVAL (XEXP (x, 1)) < 0)
916 {
917 st[1] = "-";
918 op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
919 }
920 else
921 {
922 st[1] = "+";
923 op[1] = XEXP (x, 1);
924 }
925 break;
926 case LO_SUM:
927 op[0] = XEXP (x, 0);
928 st[1] = "+low(";
929 op[1] = XEXP (x, 1);
930 st[2] = ")";
931 break;
932 case MINUS:
933 op[0] = XEXP (x, 0);
934 st[1] = "-";
935 op[1] = XEXP (x, 1);
936 break;
937 case COMPARE:
938 fun = "cmp";
939 op[0] = XEXP (x, 0);
940 op[1] = XEXP (x, 1);
941 break;
942 case NEG:
943 st[0] = "-";
944 op[0] = XEXP (x, 0);
945 break;
946 case FMA:
947 st[0] = "{";
948 op[0] = XEXP (x, 0);
949 st[1] = "*";
950 op[1] = XEXP (x, 1);
951 st[2] = "+";
952 op[2] = XEXP (x, 2);
953 st[3] = "}";
954 break;
955 case MULT:
956 op[0] = XEXP (x, 0);
957 st[1] = "*";
958 op[1] = XEXP (x, 1);
959 break;
960 case DIV:
961 op[0] = XEXP (x, 0);
962 st[1] = "/";
963 op[1] = XEXP (x, 1);
964 break;
965 case UDIV:
966 fun = "udiv";
967 op[0] = XEXP (x, 0);
968 op[1] = XEXP (x, 1);
969 break;
970 case MOD:
971 op[0] = XEXP (x, 0);
972 st[1] = "%";
973 op[1] = XEXP (x, 1);
974 break;
975 case UMOD:
976 fun = "umod";
977 op[0] = XEXP (x, 0);
978 op[1] = XEXP (x, 1);
979 break;
980 case SMIN:
981 fun = "smin";
982 op[0] = XEXP (x, 0);
983 op[1] = XEXP (x, 1);
984 break;
985 case SMAX:
986 fun = "smax";
987 op[0] = XEXP (x, 0);
988 op[1] = XEXP (x, 1);
989 break;
990 case UMIN:
991 fun = "umin";
992 op[0] = XEXP (x, 0);
993 op[1] = XEXP (x, 1);
994 break;
995 case UMAX:
996 fun = "umax";
997 op[0] = XEXP (x, 0);
998 op[1] = XEXP (x, 1);
999 break;
1000 case NOT:
1001 st[0] = "!";
1002 op[0] = XEXP (x, 0);
1003 break;
1004 case AND:
1005 op[0] = XEXP (x, 0);
1006 st[1] = "&";
1007 op[1] = XEXP (x, 1);
1008 break;
1009 case IOR:
1010 op[0] = XEXP (x, 0);
1011 st[1] = "|";
1012 op[1] = XEXP (x, 1);
1013 break;
1014 case XOR:
1015 op[0] = XEXP (x, 0);
1016 st[1] = "^";
1017 op[1] = XEXP (x, 1);
1018 break;
1019 case ASHIFT:
1020 op[0] = XEXP (x, 0);
1021 st[1] = "<<";
1022 op[1] = XEXP (x, 1);
1023 break;
1024 case LSHIFTRT:
1025 op[0] = XEXP (x, 0);
1026 st[1] = " 0>>";
1027 op[1] = XEXP (x, 1);
1028 break;
1029 case ASHIFTRT:
1030 op[0] = XEXP (x, 0);
1031 st[1] = ">>";
1032 op[1] = XEXP (x, 1);
1033 break;
1034 case ROTATE:
1035 op[0] = XEXP (x, 0);
1036 st[1] = "<-<";
1037 op[1] = XEXP (x, 1);
1038 break;
1039 case ROTATERT:
1040 op[0] = XEXP (x, 0);
1041 st[1] = ">->";
1042 op[1] = XEXP (x, 1);
1043 break;
1044 case NE:
1045 op[0] = XEXP (x, 0);
1046 st[1] = "!=";
1047 op[1] = XEXP (x, 1);
1048 break;
1049 case EQ:
1050 op[0] = XEXP (x, 0);
1051 st[1] = "==";
1052 op[1] = XEXP (x, 1);
1053 break;
1054 case GE:
1055 op[0] = XEXP (x, 0);
1056 st[1] = ">=";
1057 op[1] = XEXP (x, 1);
1058 break;
1059 case GT:
1060 op[0] = XEXP (x, 0);
1061 st[1] = ">";
1062 op[1] = XEXP (x, 1);
1063 break;
1064 case LE:
1065 op[0] = XEXP (x, 0);
1066 st[1] = "<=";
1067 op[1] = XEXP (x, 1);
1068 break;
1069 case LT:
1070 op[0] = XEXP (x, 0);
1071 st[1] = "<";
1072 op[1] = XEXP (x, 1);
1073 break;
1074 case SIGN_EXTRACT:
1075 fun = (verbose) ? "sign_extract" : "sxt";
1076 op[0] = XEXP (x, 0);
1077 op[1] = XEXP (x, 1);
1078 op[2] = XEXP (x, 2);
1079 break;
1080 case ZERO_EXTRACT:
1081 fun = (verbose) ? "zero_extract" : "zxt";
1082 op[0] = XEXP (x, 0);
1083 op[1] = XEXP (x, 1);
1084 op[2] = XEXP (x, 2);
1085 break;
1086 case SIGN_EXTEND:
1087 fun = (verbose) ? "sign_extend" : "sxn";
1088 op[0] = XEXP (x, 0);
1089 break;
1090 case ZERO_EXTEND:
1091 fun = (verbose) ? "zero_extend" : "zxn";
1092 op[0] = XEXP (x, 0);
1093 break;
1094 case FLOAT_EXTEND:
1095 fun = (verbose) ? "float_extend" : "fxn";
1096 op[0] = XEXP (x, 0);
1097 break;
1098 case TRUNCATE:
1099 fun = (verbose) ? "trunc" : "trn";
1100 op[0] = XEXP (x, 0);
1101 break;
1102 case FLOAT_TRUNCATE:
1103 fun = (verbose) ? "float_trunc" : "ftr";
1104 op[0] = XEXP (x, 0);
1105 break;
1106 case FLOAT:
1107 fun = (verbose) ? "float" : "flt";
1108 op[0] = XEXP (x, 0);
1109 break;
1110 case UNSIGNED_FLOAT:
1111 fun = (verbose) ? "uns_float" : "ufl";
1112 op[0] = XEXP (x, 0);
1113 break;
1114 case FIX:
1115 fun = "fix";
1116 op[0] = XEXP (x, 0);
1117 break;
1118 case UNSIGNED_FIX:
1119 fun = (verbose) ? "uns_fix" : "ufx";
1120 op[0] = XEXP (x, 0);
1121 break;
1122 case PRE_DEC:
1123 st[0] = "--";
1124 op[0] = XEXP (x, 0);
1125 break;
1126 case PRE_INC:
1127 st[0] = "++";
1128 op[0] = XEXP (x, 0);
1129 break;
1130 case POST_DEC:
1131 op[0] = XEXP (x, 0);
1132 st[1] = "--";
1133 break;
1134 case POST_INC:
1135 op[0] = XEXP (x, 0);
1136 st[1] = "++";
1137 break;
1138 case PRE_MODIFY:
1139 st[0] = "pre ";
1140 op[0] = XEXP (XEXP (x, 1), 0);
1141 st[1] = "+=";
1142 op[1] = XEXP (XEXP (x, 1), 1);
1143 break;
1144 case POST_MODIFY:
1145 st[0] = "post ";
1146 op[0] = XEXP (XEXP (x, 1), 0);
1147 st[1] = "+=";
1148 op[1] = XEXP (XEXP (x, 1), 1);
1149 break;
1150 case CALL:
1151 st[0] = "call ";
1152 op[0] = XEXP (x, 0);
1153 if (verbose)
1154 {
1155 st[1] = " argc:";
1156 op[1] = XEXP (x, 1);
1157 }
1158 break;
1159 case IF_THEN_ELSE:
1160 st[0] = "{(";
1161 op[0] = XEXP (x, 0);
1162 st[1] = ")?";
1163 op[1] = XEXP (x, 1);
1164 st[2] = ":";
1165 op[2] = XEXP (x, 2);
1166 st[3] = "}";
1167 break;
1168 case TRAP_IF:
1169 fun = "trap_if";
1170 op[0] = TRAP_CONDITION (x);
1171 break;
1172 case PREFETCH:
1173 fun = "prefetch";
1174 op[0] = XEXP (x, 0);
1175 op[1] = XEXP (x, 1);
1176 op[2] = XEXP (x, 2);
1177 break;
1178 case UNSPEC:
1179 case UNSPEC_VOLATILE:
1180 {
1181 pp_string (pp, "unspec");
1182 if (GET_CODE (x) == UNSPEC_VOLATILE)
1183 pp_string (pp, "/v");
1184 pp_left_bracket (pp);
1185 for (i = 0; i < XVECLEN (x, 0); i++)
1186 {
1187 if (i != 0)
1188 pp_comma (pp);
1189 print_pattern (pp, XVECEXP (x, 0, i), verbose);
1190 }
1191 pp_string (pp, "] ");
1192 pp_decimal_int (pp, XINT (x, 1));
1193 }
1194 break;
1195 default:
1196 {
1197 /* Most unhandled codes can be printed as pseudo-functions. */
1198 if (GET_RTX_CLASS (GET_CODE (x)) == RTX_UNARY)
1199 {
1200 fun = GET_RTX_NAME (GET_CODE (x));
1201 op[0] = XEXP (x, 0);
1202 }
1203 else if (GET_RTX_CLASS (GET_CODE (x)) == RTX_COMPARE
1204 || GET_RTX_CLASS (GET_CODE (x)) == RTX_COMM_COMPARE
1205 || GET_RTX_CLASS (GET_CODE (x)) == RTX_BIN_ARITH
1206 || GET_RTX_CLASS (GET_CODE (x)) == RTX_COMM_ARITH)
1207 {
1208 fun = GET_RTX_NAME (GET_CODE (x));
1209 op[0] = XEXP (x, 0);
1210 op[1] = XEXP (x, 1);
1211 }
1212 else if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY)
1213 {
1214 fun = GET_RTX_NAME (GET_CODE (x));
1215 op[0] = XEXP (x, 0);
1216 op[1] = XEXP (x, 1);
1217 op[2] = XEXP (x, 2);
1218 }
1219 else
1220 /* Give up, just print the RTX name. */
1221 st[0] = GET_RTX_NAME (GET_CODE (x));
1222 }
1223 break;
1224 }
1225
1226 /* Print this as a function? */
1227 if (fun)
1228 {
1229 pp_string (pp, fun);
1230 pp_left_paren (pp);
1231 }
1232
1233 for (i = 0; i < 4; i++)
1234 {
1235 if (st[i])
1236 pp_string (pp, st[i]);
1237
1238 if (op[i])
1239 {
1240 if (fun && i != 0)
1241 pp_comma (pp);
1242 print_value (pp, op[i], verbose);
1243 }
1244 }
1245
1246 if (fun)
1247 pp_right_paren (pp);
1248} /* print_exp */
1249
1250/* Prints rtxes, I customarily classified as values. They're constants,
1251 registers, labels, symbols and memory accesses. */
1252
1253void
1254print_value (pretty_printer *pp, const_rtx x, int verbose)
1255{
1256 char tmp[1024];
1257
1258 if (!x)
1259 {
1260 pp_string (pp, "(nil)");
1261 return;
1262 }
1263 switch (GET_CODE (x))
1264 {
1265 case CONST_INT:
1266 pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
1267 (unsigned HOST_WIDE_INT) INTVAL (x));
1268 break;
1269
1270 case CONST_WIDE_INT:
1271 {
1272 const char *sep = "<";
1273 int i;
1274 for (i = CONST_WIDE_INT_NUNITS (x) - 1; i >= 0; i--)
1275 {
1276 pp_string (pp, sep);
1277 sep = ",";
1278 sprintf (tmp, HOST_WIDE_INT_PRINT_HEX,
1279 (unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (x, i));
1280 pp_string (pp, tmp);
1281 }
1282 pp_greater (pp);
1283 }
1284 break;
1285
1286 case CONST_DOUBLE:
1287 if (FLOAT_MODE_P (GET_MODE (x)))
1288 {
1289 real_to_decimal (tmp, CONST_DOUBLE_REAL_VALUE (x),
1290 sizeof (tmp), 0, 1);
1291 pp_string (pp, tmp);
1292 }
1293 else
1294 pp_printf (pp, "<%wx,%wx>",
1295 (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
1296 (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
1297 break;
1298 case CONST_FIXED:
1299 fixed_to_decimal (tmp, CONST_FIXED_VALUE (x), sizeof (tmp));
1300 pp_string (pp, tmp);
1301 break;
1302 case CONST_STRING:
1303 pp_printf (pp, "\"%s\"", XSTR (x, 0));
1304 break;
1305 case SYMBOL_REF:
1306 pp_printf (pp, "`%s'", XSTR (x, 0));
1307 break;
1308 case LABEL_REF:
1309 pp_printf (pp, "L%d", INSN_UID (LABEL_REF_LABEL (x)));
1310 break;
1311 case CONST:
1312 case HIGH:
1313 case STRICT_LOW_PART:
1314 pp_printf (pp, "%s(", GET_RTX_NAME (GET_CODE (x)));
1315 print_value (pp, XEXP (x, 0), verbose);
1316 pp_right_paren (pp);
1317 break;
1318 case REG:
1319 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
1320 {
1321 if (ISDIGIT (reg_names[REGNO (x)][0]))
1322 pp_modulo (pp);
1323 pp_string (pp, reg_names[REGNO (x)]);
1324 }
1325 else
1326 pp_printf (pp, "r%d", REGNO (x));
1327 if (verbose)
1328 pp_printf (pp, ":%s", GET_MODE_NAME (GET_MODE (x)));
1329 break;
1330 case SUBREG:
1331 print_value (pp, SUBREG_REG (x), verbose);
1332 pp_printf (pp, "#%d", SUBREG_BYTE (x));
1333 break;
1334 case SCRATCH:
1335 case CC0:
1336 case PC:
1337 pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
1338 break;
1339 case MEM:
1340 pp_left_bracket (pp);
1341 print_value (pp, XEXP (x, 0), verbose);
1342 pp_right_bracket (pp);
1343 break;
1344 case DEBUG_EXPR:
1345 pp_printf (pp, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
1346 break;
1347 default:
1348 print_exp (pp, x, verbose);
1349 break;
1350 }
1351} /* print_value */
1352
1353/* The next step in insn detalization, its pattern recognition. */
1354
1355void
1356print_pattern (pretty_printer *pp, const_rtx x, int verbose)
1357{
1358 if (! x)
1359 {
1360 pp_string (pp, "(nil)");
1361 return;
1362 }
1363
1364 switch (GET_CODE (x))
1365 {
1366 case SET:
1367 print_value (pp, SET_DEST (x), verbose);
1368 pp_equal (pp);
1369 print_value (pp, SET_SRC (x), verbose);
1370 break;
1371 case RETURN:
1372 case SIMPLE_RETURN:
1373 case EH_RETURN:
1374 pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
1375 break;
1376 case CALL:
1377 print_exp (pp, x, verbose);
1378 break;
1379 case CLOBBER:
1380 case USE:
1381 pp_printf (pp, "%s ", GET_RTX_NAME (GET_CODE (x)));
1382 print_value (pp, XEXP (x, 0), verbose);
1383 break;
1384 case VAR_LOCATION:
1385 pp_string (pp, "loc ");
1386 print_value (pp, PAT_VAR_LOCATION_LOC (x), verbose);
1387 break;
1388 case COND_EXEC:
1389 pp_left_paren (pp);
1390 if (GET_CODE (COND_EXEC_TEST (x)) == NE
1391 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
1392 print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
1393 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
1394 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
1395 {
1396 pp_exclamation (pp);
1397 print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
1398 }
1399 else
1400 print_value (pp, COND_EXEC_TEST (x), verbose);
1401 pp_string (pp, ") ");
1402 print_pattern (pp, COND_EXEC_CODE (x), verbose);
1403 break;
1404 case PARALLEL:
1405 {
1406 int i;
1407
1408 pp_left_brace (pp);
1409 for (i = 0; i < XVECLEN (x, 0); i++)
1410 {
1411 print_pattern (pp, XVECEXP (x, 0, i), verbose);
1412 pp_semicolon (pp);
1413 }
1414 pp_right_brace (pp);
1415 }
1416 break;
1417 case SEQUENCE:
1418 {
1419 const rtx_sequence *seq = as_a <const rtx_sequence *> (x);
1420 pp_string (pp, "sequence{");
1421 if (INSN_P (seq->element (0)))
1422 {
1423 /* Print the sequence insns indented. */
1424 const char * save_print_rtx_head = print_rtx_head;
1425 char indented_print_rtx_head[32];
1426
1427 pp_newline (pp);
1428 gcc_assert (strlen (print_rtx_head) < sizeof (indented_print_rtx_head) - 4);
1429 snprintf (indented_print_rtx_head,
1430 sizeof (indented_print_rtx_head),
1431 "%s ", print_rtx_head);
1432 print_rtx_head = indented_print_rtx_head;
1433 for (int i = 0; i < seq->len (); i++)
1434 print_insn_with_notes (pp, seq->insn (i));
1435 pp_printf (pp, "%s ", save_print_rtx_head);
1436 print_rtx_head = save_print_rtx_head;
1437 }
1438 else
1439 {
1440 for (int i = 0; i < seq->len (); i++)
1441 {
1442 print_pattern (pp, seq->element (i), verbose);
1443 pp_semicolon (pp);
1444 }
1445 }
1446 pp_right_brace (pp);
1447 }
1448 break;
1449 case ASM_INPUT:
1450 pp_printf (pp, "asm {%s}", XSTR (x, 0));
1451 break;
1452 case ADDR_VEC:
1453 for (int i = 0; i < XVECLEN (x, 0); i++)
1454 {
1455 print_value (pp, XVECEXP (x, 0, i), verbose);
1456 pp_semicolon (pp);
1457 }
1458 break;
1459 case ADDR_DIFF_VEC:
1460 for (int i = 0; i < XVECLEN (x, 1); i++)
1461 {
1462 print_value (pp, XVECEXP (x, 1, i), verbose);
1463 pp_semicolon (pp);
1464 }
1465 break;
1466 case TRAP_IF:
1467 pp_string (pp, "trap_if ");
1468 print_value (pp, TRAP_CONDITION (x), verbose);
1469 break;
1470 case UNSPEC:
1471 case UNSPEC_VOLATILE:
1472 /* Fallthru -- leave UNSPECs to print_exp. */
1473 default:
1474 print_value (pp, x, verbose);
1475 }
1476} /* print_pattern */
1477
1478/* This is the main function in slim rtl visualization mechanism.
1479
1480 X is an insn, to be printed into PP.
1481
1482 This function tries to print it properly in human-readable form,
1483 resembling assembler mnemonics (instead of the older Lisp-style
1484 form).
1485
1486 If VERBOSE is TRUE, insns are printed with more complete (but
1487 longer) pattern names and with extra information, and prefixed
1488 with their INSN_UIDs. */
1489
1490void
1491print_insn (pretty_printer *pp, const rtx_insn *x, int verbose)
1492{
1493 if (verbose)
1494 {
1495 /* Blech, pretty-print can't print integers with a specified width. */
1496 char uid_prefix[32];
1497 snprintf (uid_prefix, sizeof uid_prefix, " %4d: ", INSN_UID (x));
1498 pp_string (pp, uid_prefix);
1499 }
1500
1501 switch (GET_CODE (x))
1502 {
1503 case INSN:
1504 print_pattern (pp, PATTERN (x), verbose);
1505 break;
1506
1507 case DEBUG_INSN:
1508 {
1509 const char *name = "?";
1510
1511 if (DECL_P (INSN_VAR_LOCATION_DECL (x)))
1512 {
1513 tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (x));
1514 char idbuf[32];
1515 if (id)
1516 name = IDENTIFIER_POINTER (id);
1517 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x))
1518 == DEBUG_EXPR_DECL)
1519 {
1520 sprintf (idbuf, "D#%i",
1521 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x)));
1522 name = idbuf;
1523 }
1524 else
1525 {
1526 sprintf (idbuf, "D.%i",
1527 DECL_UID (INSN_VAR_LOCATION_DECL (x)));
1528 name = idbuf;
1529 }
1530 }
1531 pp_printf (pp, "debug %s => ", name);
1532 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x)))
1533 pp_string (pp, "optimized away");
1534 else
1535 print_pattern (pp, INSN_VAR_LOCATION_LOC (x), verbose);
1536 }
1537 break;
1538
1539 case JUMP_INSN:
1540 print_pattern (pp, PATTERN (x), verbose);
1541 break;
1542 case CALL_INSN:
1543 if (GET_CODE (PATTERN (x)) == PARALLEL)
1544 print_pattern (pp, XVECEXP (PATTERN (x), 0, 0), verbose);
1545 else
1546 print_pattern (pp, PATTERN (x), verbose);
1547 break;
1548 case CODE_LABEL:
1549 pp_printf (pp, "L%d:", INSN_UID (x));
1550 break;
1551 case JUMP_TABLE_DATA:
1552 pp_string (pp, "jump_table_data{\n");
1553 print_pattern (pp, PATTERN (x), verbose);
1554 pp_right_brace (pp);
1555 break;
1556 case BARRIER:
1557 pp_string (pp, "barrier");
1558 break;
1559 case NOTE:
1560 {
1561 pp_string (pp, GET_NOTE_INSN_NAME (NOTE_KIND (x)));
1562 switch (NOTE_KIND (x))
1563 {
1564 case NOTE_INSN_EH_REGION_BEG:
1565 case NOTE_INSN_EH_REGION_END:
1566 pp_printf (pp, " %d", NOTE_EH_HANDLER (x));
1567 break;
1568
1569 case NOTE_INSN_BLOCK_BEG:
1570 case NOTE_INSN_BLOCK_END:
1571 pp_printf (pp, " %d", BLOCK_NUMBER (NOTE_BLOCK (x)));
1572 break;
1573
1574 case NOTE_INSN_BASIC_BLOCK:
1575 pp_printf (pp, " %d", NOTE_BASIC_BLOCK (x)->index);
1576 break;
1577
1578 case NOTE_INSN_DELETED_LABEL:
1579 case NOTE_INSN_DELETED_DEBUG_LABEL:
1580 {
1581 const char *label = NOTE_DELETED_LABEL_NAME (x);
1582 if (label == NULL)
1583 label = "";
1584 pp_printf (pp, " (\"%s\")", label);
1585 }
1586 break;
1587
1588 case NOTE_INSN_VAR_LOCATION:
1589 case NOTE_INSN_CALL_ARG_LOCATION:
1590 pp_left_brace (pp);
1591 print_pattern (pp, NOTE_VAR_LOCATION (x), verbose);
1592 pp_right_brace (pp);
1593 break;
1594
1595 default:
1596 break;
1597 }
1598 break;
1599 }
1600 default:
1601 gcc_unreachable ();
1602 }
1603} /* print_insn */
1604
1605/* Pretty-print a slim dump of X (an insn) to PP, including any register
1606 note attached to the instruction. */
1607
1608static void
1609print_insn_with_notes (pretty_printer *pp, const rtx_insn *x)
1610{
1611 pp_string (pp, print_rtx_head);
1612 print_insn (pp, x, 1);
1613 pp_newline (pp);
1614 if (INSN_P (x) && REG_NOTES (x))
1615 for (rtx note = REG_NOTES (x); note; note = XEXP (note, 1))
1616 {
1617 pp_printf (pp, "%s %s ", print_rtx_head,
1618 GET_REG_NOTE_NAME (REG_NOTE_KIND (note)));
1619 if (GET_CODE (note) == INT_LIST)
1620 pp_printf (pp, "%d", XINT (note, 0));
1621 else
1622 print_pattern (pp, XEXP (note, 0), 1);
1623 pp_newline (pp);
1624 }
1625}
1626
1627/* Print X, an RTL value node, to file F in slim format. Include
1628 additional information if VERBOSE is nonzero.
1629
1630 Value nodes are constants, registers, labels, symbols and
1631 memory. */
1632
1633void
1634dump_value_slim (FILE *f, const_rtx x, int verbose)
1635{
1636 pretty_printer rtl_slim_pp;
1637 rtl_slim_pp.buffer->stream = f;
1638 print_value (&rtl_slim_pp, x, verbose);
1639 pp_flush (&rtl_slim_pp);
1640}
1641
1642/* Emit a slim dump of X (an insn) to the file F, including any register
1643 note attached to the instruction. */
1644void
1645dump_insn_slim (FILE *f, const rtx_insn *x)
1646{
1647 pretty_printer rtl_slim_pp;
1648 rtl_slim_pp.buffer->stream = f;
1649 print_insn_with_notes (&rtl_slim_pp, x);
1650 pp_flush (&rtl_slim_pp);
1651}
1652
1653/* Same as above, but stop at LAST or when COUNT == 0.
1654 If COUNT < 0 it will stop only at LAST or NULL rtx. */
1655
1656void
1657dump_rtl_slim (FILE *f, const rtx_insn *first, const rtx_insn *last,
1658 int count, int flags ATTRIBUTE_UNUSED)
1659{
1660 const rtx_insn *insn, *tail;
1661 pretty_printer rtl_slim_pp;
1662 rtl_slim_pp.buffer->stream = f;
1663
1664 tail = last ? NEXT_INSN (last) : NULL;
1665 for (insn = first;
1666 (insn != NULL) && (insn != tail) && (count != 0);
1667 insn = NEXT_INSN (insn))
1668 {
1669 print_insn_with_notes (&rtl_slim_pp, insn);
1670 if (count > 0)
1671 count--;
1672 }
1673
1674 pp_flush (&rtl_slim_pp);
1675}
1676
1677/* Dumps basic block BB to pretty-printer PP in slim form and without and
1678 no indentation, for use as a label of a DOT graph record-node. */
1679
1680void
1681rtl_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
1682{
1683 rtx_insn *insn;
1684 bool first = true;
1685
1686 /* TODO: inter-bb stuff. */
1687 FOR_BB_INSNS (bb, insn)
1688 {
1689 if (! first)
1690 {
1691 pp_bar (pp);
1692 pp_write_text_to_stream (pp);
1693 }
1694 first = false;
1695 print_insn_with_notes (pp, insn);
1696 pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true);
1697 }
1698}
1699
1700/* Pretty-print pattern X of some insn in non-verbose mode.
1701 Return a string pointer to the pretty-printer buffer.
1702
1703 This function is only exported exists only to accommodate some older users
1704 of the slim RTL pretty printers. Please do not use it for new code. */
1705
1706const char *
1707str_pattern_slim (const_rtx x)
1708{
1709 pretty_printer rtl_slim_pp;
1710 print_pattern (&rtl_slim_pp, x, 0);
1711 return ggc_strdup (pp_formatted_text (&rtl_slim_pp));
1712}
1713
1714/* Emit a slim dump of X (an insn) to stderr. */
1715extern void debug_insn_slim (const rtx_insn *);
1716DEBUG_FUNCTION void
1717debug_insn_slim (const rtx_insn *x)
1718{
1719 dump_insn_slim (stderr, x);
1720}
1721
1722/* Same as above, but using dump_rtl_slim. */
1723extern void debug_rtl_slim (FILE *, const rtx_insn *, const rtx_insn *,
1724 int, int);
1725DEBUG_FUNCTION void
1726debug_rtl_slim (const rtx_insn *first, const rtx_insn *last, int count,
1727 int flags)
1728{
1729 dump_rtl_slim (stderr, first, last, count, flags);
1730}
1731
1732extern void debug_bb_slim (basic_block);
1733DEBUG_FUNCTION void
1734debug_bb_slim (basic_block bb)
1735{
1736 dump_bb (stderr, bb, 0, TDF_SLIM | TDF_BLOCKS);
1737}
1738
1739extern void debug_bb_n_slim (int);
1740DEBUG_FUNCTION void
1741debug_bb_n_slim (int n)
1742{
1743 basic_block bb = BASIC_BLOCK_FOR_FN (cfun, n);
1744 debug_bb_slim (bb);
1745}
1746
1747#endif