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