]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/print-rtl.c
[6/6] Preprocessor forced macro location
[thirdparty/gcc.git] / gcc / print-rtl.c
CommitLineData
5e6908ea 1/* Print RTL for GCC.
85ec4feb 2 Copyright (C) 1987-2018 Free Software Foundation, Inc.
e1a79915 3
1322177d 4This file is part of GCC.
e1a79915 5
1322177d
LB
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
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
1322177d 9version.
e1a79915 10
1322177d
LB
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.
e1a79915
RS
15
16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
e1a79915 19
45c8116d
ZW
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
e1a79915 25#include "config.h"
45c8116d
ZW
26#endif
27
670ee920 28#include "system.h"
4977bab6
ZW
29#include "coretypes.h"
30#include "tm.h"
e1a79915 31#include "rtl.h"
738cc472 32
45c8116d
ZW
33/* These headers all define things which are not available in
34 generator programs. */
35#ifndef GENERATOR_FILE
40e23961 36#include "alias.h"
738cc472 37#include "tree.h"
3995f3a2 38#include "basic-block.h"
d8a2d370 39#include "print-tree.h"
b707b450 40#include "flags.h"
60393bbc 41#include "predict.h"
60393bbc 42#include "function.h"
e144a2b3 43#include "cfg.h"
e881bb1b 44#include "basic-block.h"
55b34b5f 45#include "diagnostic.h"
cf835838 46#include "tree-pretty-print.h"
a78a26f1 47#include "alloc-pool.h"
b5b8b0ac 48#include "cselib.h"
7ee2468b 49#include "dumpfile.h" /* for dump_flags */
2867fa7c 50#include "dwarf2out.h"
013a8899 51#include "pretty-print.h"
45c8116d 52#endif
cf99a734 53
013a8899 54#include "print-rtl.h"
00439aef 55#include "rtl-iter.h"
013a8899 56
c349e40b
SC
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. */
47c10e9b 60const char *print_rtx_head = "";
c349e40b 61
e90afde6
JM
62#ifdef GENERATOR_FILE
63/* These are defined from the .opt file when not used in generator
64 programs. */
65
9dbe7947
JH
66/* Nonzero means suppress output of instruction numbers
67 in debugging dumps.
b707b450 68 This must be defined here so that programs like gencodes can be linked. */
9ec36da5 69int flag_dump_unnumbered = 0;
b707b450 70
2aa7c49b
AO
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;
e90afde6 75#endif
2aa7c49b 76
36cd856f
DM
77/* Constructor for rtx_writer. */
78
00439aef
DM
79rtx_writer::rtx_writer (FILE *outf, int ind, bool simple, bool compact,
80 rtx_reuse_manager *reuse_manager)
36cd856f 81: m_outfile (outf), m_sawclose (0), m_indent (ind),
00439aef
DM
82 m_in_call_function_usage (false), m_simple (simple), m_compact (compact),
83 m_rtx_reuse_manager (reuse_manager)
36cd856f
DM
84{
85}
75b7557d 86
00439aef
DM
87#ifndef GENERATOR_FILE
88
89/* rtx_reuse_manager's ctor. */
90
91rtx_reuse_manager::rtx_reuse_manager ()
92: m_next_id (0)
93{
00439aef
DM
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{
8f9b31f7 161 return bitmap_bit_p (m_defs_seen, reuse_id);
00439aef
DM
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{
8f9b31f7 169 bitmap_set_bit (m_defs_seen, reuse_id);
00439aef
DM
170}
171
172#endif /* #ifndef GENERATOR_FILE */
173
45c8116d 174#ifndef GENERATOR_FILE
998d7deb 175void
f7d504c2 176print_mem_expr (FILE *outfile, const_tree expr)
998d7deb 177{
55b34b5f 178 fputc (' ', outfile);
831b9ef8 179 print_generic_expr (outfile, CONST_CAST_TREE (expr), dump_flags);
998d7deb 180}
91914e56 181#endif
84bc717b
RS
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}
998d7deb 199
acda0629
DM
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
36cd856f
DM
206void
207rtx_writer::print_rtx_operand_code_0 (const_rtx in_rtx ATTRIBUTE_UNUSED,
208 int idx ATTRIBUTE_UNUSED)
acda0629
DM
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)
36cd856f 215 fprintf (m_outfile, " [flags %#x]", flags);
acda0629
DM
216 tree decl = SYMBOL_REF_DECL (in_rtx);
217 if (decl)
36cd856f 218 print_node_brief (m_outfile, "", decl, dump_flags);
acda0629
DM
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)
36cd856f 227 fprintf (m_outfile, " #");
acda0629 228 else
36cd856f
DM
229 fprintf (m_outfile, " %d", NOTE_EH_HANDLER (in_rtx));
230 m_sawclose = 1;
acda0629
DM
231 break;
232
233 case NOTE_INSN_BLOCK_BEG:
234 case NOTE_INSN_BLOCK_END:
36cd856f
DM
235 dump_addr (m_outfile, " ", NOTE_BLOCK (in_rtx));
236 m_sawclose = 1;
acda0629
DM
237 break;
238
239 case NOTE_INSN_BASIC_BLOCK:
240 {
241 basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
242 if (bb != 0)
36cd856f 243 fprintf (m_outfile, " [bb %d]", bb->index);
acda0629
DM
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)
36cd856f 252 fprintf (m_outfile, " (\"%s\")", label);
acda0629 253 else
36cd856f 254 fprintf (m_outfile, " \"\"");
acda0629
DM
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)
36cd856f 262 fprintf (m_outfile, " [bb %d]", bb->index);
acda0629
DM
263 break;
264 }
265
266 case NOTE_INSN_VAR_LOCATION:
36cd856f 267 fputc (' ', m_outfile);
acda0629
DM
268 print_rtx (NOTE_VAR_LOCATION (in_rtx));
269 break;
270
271 case NOTE_INSN_CFI:
36cd856f
DM
272 fputc ('\n', m_outfile);
273 output_cfi_directive (m_outfile, NOTE_CFI (in_rtx));
274 fputc ('\t', m_outfile);
acda0629
DM
275 break;
276
96a95ac1 277 case NOTE_INSN_BEGIN_STMT:
58006663 278 case NOTE_INSN_INLINE_ENTRY:
96a95ac1
AO
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
acda0629
DM
288 default:
289 break;
290 }
291 }
7810c4eb 292 else if (idx == 7 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL
36cd856f 293 && !m_compact)
acda0629
DM
294 {
295 /* Output the JUMP_LABEL reference. */
36cd856f 296 fprintf (m_outfile, "\n%s%*s -> ", print_rtx_head, m_indent * 2, "");
acda0629 297 if (GET_CODE (JUMP_LABEL (in_rtx)) == RETURN)
36cd856f 298 fprintf (m_outfile, "return");
acda0629 299 else if (GET_CODE (JUMP_LABEL (in_rtx)) == SIMPLE_RETURN)
36cd856f 300 fprintf (m_outfile, "simple_return");
acda0629 301 else
36cd856f 302 fprintf (m_outfile, "%d", INSN_UID (JUMP_LABEL (in_rtx)));
acda0629
DM
303 }
304 else if (idx == 0 && GET_CODE (in_rtx) == VALUE)
305 {
306 cselib_val *val = CSELIB_VAL_PTR (in_rtx);
307
36cd856f
DM
308 fprintf (m_outfile, " %u:%u", val->uid, val->hash);
309 dump_addr (m_outfile, " @", in_rtx);
310 dump_addr (m_outfile, "/", (void*)val);
acda0629
DM
311 }
312 else if (idx == 0 && GET_CODE (in_rtx) == DEBUG_EXPR)
313 {
36cd856f 314 fprintf (m_outfile, " D#%i",
acda0629
DM
315 DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (in_rtx)));
316 }
317 else if (idx == 0 && GET_CODE (in_rtx) == ENTRY_VALUE)
318 {
36cd856f
DM
319 m_indent += 2;
320 if (!m_sawclose)
321 fprintf (m_outfile, " ");
acda0629 322 print_rtx (ENTRY_VALUE_EXP (in_rtx));
36cd856f 323 m_indent -= 2;
acda0629
DM
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
36cd856f
DM
332void
333rtx_writer::print_rtx_operand_code_e (const_rtx in_rtx, int idx)
acda0629 334{
36cd856f 335 m_indent += 2;
acda0629
DM
336 if (idx == 6 && INSN_P (in_rtx))
337 /* Put REG_NOTES on their own line. */
36cd856f
DM
338 fprintf (m_outfile, "\n%s%*s",
339 print_rtx_head, m_indent * 2, "");
340 if (!m_sawclose)
341 fprintf (m_outfile, " ");
acda0629
DM
342 if (idx == 7 && CALL_P (in_rtx))
343 {
36cd856f 344 m_in_call_function_usage = true;
acda0629 345 print_rtx (XEXP (in_rtx, idx));
36cd856f 346 m_in_call_function_usage = false;
acda0629
DM
347 }
348 else
349 print_rtx (XEXP (in_rtx, idx));
36cd856f 350 m_indent -= 2;
acda0629
DM
351}
352
353/* Subroutine of print_rtx_operand for handling codes 'E' and 'V'. */
354
36cd856f
DM
355void
356rtx_writer::print_rtx_operand_codes_E_and_V (const_rtx in_rtx, int idx)
acda0629 357{
36cd856f
DM
358 m_indent += 2;
359 if (m_sawclose)
acda0629 360 {
36cd856f
DM
361 fprintf (m_outfile, "\n%s%*s",
362 print_rtx_head, m_indent * 2, "");
363 m_sawclose = 0;
acda0629 364 }
36cd856f 365 fputs (" [", m_outfile);
01512446 366 if (XVEC (in_rtx, idx) != NULL)
acda0629 367 {
36cd856f 368 m_indent += 2;
acda0629 369 if (XVECLEN (in_rtx, idx))
36cd856f 370 m_sawclose = 1;
acda0629
DM
371
372 for (int j = 0; j < XVECLEN (in_rtx, idx); j++)
2045ae1d
AS
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 }
acda0629 387
36cd856f 388 m_indent -= 2;
acda0629 389 }
36cd856f
DM
390 if (m_sawclose)
391 fprintf (m_outfile, "\n%s%*s", print_rtx_head, m_indent * 2, "");
acda0629 392
36cd856f
DM
393 fputs ("]", m_outfile);
394 m_sawclose = 1;
395 m_indent -= 2;
acda0629
DM
396}
397
398/* Subroutine of print_rtx_operand for handling code 'i'. */
399
36cd856f
DM
400void
401rtx_writer::print_rtx_operand_code_i (const_rtx in_rtx, int idx)
acda0629
DM
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);
87bd1536
EB
414 fprintf (m_outfile, " \"%s\":%i:%i", xloc.file, xloc.line,
415 xloc.column);
acda0629
DM
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)
36cd856f 423 fprintf (m_outfile, " %s:%i",
acda0629
DM
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)
36cd856f 432 fprintf (m_outfile, " %s:%i",
acda0629
DM
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)
36cd856f 443 fprintf (m_outfile, " %d", XINT (in_rtx, idx));
acda0629
DM
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)
36cd856f 450 fprintf (m_outfile, " %s", unspecv_strings[XINT (in_rtx, 1)]);
acda0629
DM
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)
36cd856f 458 fprintf (m_outfile, " %s", unspec_strings[XINT (in_rtx, 1)]);
acda0629
DM
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
7810c4eb 466 /* Don't print INSN_CODEs in compact mode. */
36cd856f 467 if (m_compact && is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, idx))
7810c4eb 468 {
36cd856f 469 m_sawclose = 0;
7810c4eb
DM
470 return;
471 }
472
acda0629
DM
473 if (flag_dump_unnumbered
474 && (is_insn || NOTE_P (in_rtx)))
36cd856f 475 fputc ('#', m_outfile);
acda0629 476 else
36cd856f 477 fprintf (m_outfile, " %d", value);
acda0629
DM
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)
36cd856f
DM
482 fprintf (m_outfile, " {%s}", name);
483 m_sawclose = 0;
acda0629
DM
484 }
485}
486
487/* Subroutine of print_rtx_operand for handling code 'r'. */
488
36cd856f
DM
489void
490rtx_writer::print_rtx_operand_code_r (const_rtx in_rtx)
acda0629
DM
491{
492 int is_insn = INSN_P (in_rtx);
493 unsigned int regno = REGNO (in_rtx);
494
495#ifndef GENERATOR_FILE
7810c4eb
DM
496 /* For hard registers and virtuals, always print the
497 regno, except in compact mode. */
36cd856f
DM
498 if (regno <= LAST_VIRTUAL_REGISTER && !m_compact)
499 fprintf (m_outfile, " %d", regno);
acda0629 500 if (regno < FIRST_PSEUDO_REGISTER)
36cd856f 501 fprintf (m_outfile, " %s", reg_names[regno]);
acda0629
DM
502 else if (regno <= LAST_VIRTUAL_REGISTER)
503 {
504 if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
36cd856f 505 fprintf (m_outfile, " virtual-incoming-args");
acda0629 506 else if (regno == VIRTUAL_STACK_VARS_REGNUM)
36cd856f 507 fprintf (m_outfile, " virtual-stack-vars");
acda0629 508 else if (regno == VIRTUAL_STACK_DYNAMIC_REGNUM)
36cd856f 509 fprintf (m_outfile, " virtual-stack-dynamic");
acda0629 510 else if (regno == VIRTUAL_OUTGOING_ARGS_REGNUM)
36cd856f 511 fprintf (m_outfile, " virtual-outgoing-args");
acda0629 512 else if (regno == VIRTUAL_CFA_REGNUM)
36cd856f 513 fprintf (m_outfile, " virtual-cfa");
acda0629 514 else if (regno == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
36cd856f 515 fprintf (m_outfile, " virtual-preferred-stack-boundary");
acda0629 516 else
36cd856f 517 fprintf (m_outfile, " virtual-reg-%d", regno-FIRST_VIRTUAL_REGISTER);
acda0629
DM
518 }
519 else
520#endif
521 if (flag_dump_unnumbered && is_insn)
36cd856f
DM
522 fputc ('#', m_outfile);
523 else if (m_compact)
983496fe 524 {
596762ee
DM
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>". */
983496fe 528 gcc_assert (regno > LAST_VIRTUAL_REGISTER);
596762ee 529 fprintf (m_outfile, " <%d>", regno - (LAST_VIRTUAL_REGISTER + 1));
983496fe 530 }
acda0629 531 else
36cd856f 532 fprintf (m_outfile, " %d", regno);
acda0629
DM
533
534#ifndef GENERATOR_FILE
535 if (REG_ATTRS (in_rtx))
536 {
36cd856f 537 fputs (" [", m_outfile);
acda0629 538 if (regno != ORIGINAL_REGNO (in_rtx))
36cd856f 539 fprintf (m_outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
acda0629 540 if (REG_EXPR (in_rtx))
36cd856f 541 print_mem_expr (m_outfile, REG_EXPR (in_rtx));
acda0629 542
84bc717b
RS
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 }
36cd856f 548 fputs (" ]", m_outfile);
acda0629
DM
549 }
550 if (regno != ORIGINAL_REGNO (in_rtx))
36cd856f 551 fprintf (m_outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
acda0629
DM
552#endif
553}
554
555/* Subroutine of print_rtx_operand for handling code 'u'. */
556
36cd856f
DM
557void
558rtx_writer::print_rtx_operand_code_u (const_rtx in_rtx, int idx)
acda0629 559{
7574cfd4
DM
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)
7810c4eb
DM
562 return;
563
acda0629
DM
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)
36cd856f 575 fprintf (m_outfile, " [# deleted]");
acda0629 576 else
36cd856f
DM
577 fprintf (m_outfile, " [%d deleted]", INSN_UID (sub));
578 m_sawclose = 0;
acda0629
DM
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))))
36cd856f 593 fputs (" #", m_outfile);
acda0629 594 else
36cd856f 595 fprintf (m_outfile, " %d", INSN_UID (sub));
acda0629
DM
596 }
597 else
36cd856f
DM
598 fputs (" 0", m_outfile);
599 m_sawclose = 0;
acda0629
DM
600}
601
602/* Subroutine of print_rtx. Print operand IDX of IN_RTX. */
603
36cd856f
DM
604void
605rtx_writer::print_rtx_operand (const_rtx in_rtx, int idx)
acda0629
DM
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)
51b86113 623 fputs (" (nil)", m_outfile);
acda0629 624 else
36cd856f
DM
625 fprintf (m_outfile, " (\"%s\")", str);
626 m_sawclose = 1;
acda0629
DM
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':
36cd856f
DM
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 "]",
acda0629
DM
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
91914e56
RS
655 case 'p':
656 fprintf (m_outfile, " ");
657 print_poly_int (m_outfile, SUBREG_BYTE (in_rtx));
658 break;
659
acda0629
DM
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':
36cd856f
DM
667 fprintf (m_outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, idx)));
668 m_sawclose = 0;
acda0629
DM
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)
36cd856f 678 print_mem_expr (m_outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx));
acda0629 679 else if (idx == 0 && GET_CODE (in_rtx) == DEBUG_PARAMETER_REF)
36cd856f 680 print_mem_expr (m_outfile, DEBUG_PARAMETER_REF_DECL (in_rtx));
acda0629 681 else
36cd856f 682 dump_addr (m_outfile, " ", XTREE (in_rtx, idx));
acda0629
DM
683#endif
684 break;
685
686 case '*':
36cd856f
DM
687 fputs (" Unknown", m_outfile);
688 m_sawclose = 0;
acda0629
DM
689 break;
690
691 case 'B':
7810c4eb 692 /* Don't print basic block ids in compact mode. */
36cd856f 693 if (m_compact)
7810c4eb 694 break;
acda0629
DM
695#ifndef GENERATOR_FILE
696 if (XBBDEF (in_rtx, idx))
36cd856f 697 fprintf (m_outfile, " %i", XBBDEF (in_rtx, idx)->index);
acda0629
DM
698#endif
699 break;
700
701 default:
702 gcc_unreachable ();
703 }
704}
705
b5fbe716
DM
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
36cd856f 743/* Print IN_RTX onto m_outfile. This is the recursive part of printing. */
e1a79915 744
36cd856f
DM
745void
746rtx_writer::print_rtx (const_rtx in_rtx)
e1a79915 747{
acda0629 748 int idx = 0;
e1a79915 749
36cd856f 750 if (m_sawclose)
e1a79915 751 {
36cd856f
DM
752 if (m_simple)
753 fputc (' ', m_outfile);
75b7557d 754 else
36cd856f
DM
755 fprintf (m_outfile, "\n%s%*s", print_rtx_head, m_indent * 2, "");
756 m_sawclose = 0;
e1a79915
RS
757 }
758
759 if (in_rtx == 0)
760 {
36cd856f
DM
761 fputs ("(nil)", m_outfile);
762 m_sawclose = 1;
e1a79915
RS
763 return;
764 }
5e74f966
RK
765 else if (GET_CODE (in_rtx) > NUM_RTX_CODE)
766 {
36cd856f
DM
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;
5e74f966
RK
770 return;
771 }
e1a79915 772
00439aef
DM
773 fputc ('(', m_outfile);
774
a27a5de9 775 /* Print name of expression code. */
7810c4eb 776
00439aef
DM
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
7810c4eb
DM
801 /* In compact mode, prefix the code of insns with "c",
802 giving "cinsn", "cnote" etc. */
36cd856f 803 if (m_compact && is_a <const rtx_insn *, const struct rtx_def> (in_rtx))
7810c4eb
DM
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)
00439aef 809 fprintf (m_outfile, "clabel");
7810c4eb 810 else
00439aef 811 fprintf (m_outfile, "c%s", GET_RTX_NAME (code));
7810c4eb 812 }
36cd856f 813 else if (m_simple && CONST_INT_P (in_rtx))
00439aef 814 ; /* no code. */
735a0e33 815 else
00439aef 816 fprintf (m_outfile, "%s", GET_RTX_NAME (GET_CODE (in_rtx)));
6a4d6760 817
36cd856f 818 if (! m_simple)
a27a5de9
SB
819 {
820 if (RTX_FLAG (in_rtx, in_struct))
36cd856f 821 fputs ("/s", m_outfile);
75b7557d 822
a27a5de9 823 if (RTX_FLAG (in_rtx, volatil))
36cd856f 824 fputs ("/v", m_outfile);
6a4d6760 825
a27a5de9 826 if (RTX_FLAG (in_rtx, unchanging))
36cd856f 827 fputs ("/u", m_outfile);
6a4d6760 828
a27a5de9 829 if (RTX_FLAG (in_rtx, frame_related))
36cd856f 830 fputs ("/f", m_outfile);
6a4d6760 831
a27a5de9 832 if (RTX_FLAG (in_rtx, jump))
36cd856f 833 fputs ("/j", m_outfile);
6a4d6760 834
a27a5de9 835 if (RTX_FLAG (in_rtx, call))
36cd856f 836 fputs ("/c", m_outfile);
75b7557d 837
a27a5de9 838 if (RTX_FLAG (in_rtx, return_val))
36cd856f 839 fputs ("/i", m_outfile);
6de9cd9a 840
a27a5de9
SB
841 /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */
842 if ((GET_CODE (in_rtx) == EXPR_LIST
e5af9ddd
RS
843 || GET_CODE (in_rtx) == INSN_LIST
844 || GET_CODE (in_rtx) == INT_LIST)
4def6060 845 && (int)GET_MODE (in_rtx) < REG_NOTE_MAX
36cd856f
DM
846 && !m_in_call_function_usage)
847 fprintf (m_outfile, ":%s",
a27a5de9 848 GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
52c5701b 849
a27a5de9
SB
850 /* For other rtl, print the mode if it's not VOID. */
851 else if (GET_MODE (in_rtx) != VOIDmode)
36cd856f 852 fprintf (m_outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
b5b8b0ac
AO
853
854#ifndef GENERATOR_FILE
a27a5de9
SB
855 if (GET_CODE (in_rtx) == VAR_LOCATION)
856 {
857 if (TREE_CODE (PAT_VAR_LOCATION_DECL (in_rtx)) == STRING_CST)
36cd856f 858 fputs (" <debug string placeholder>", m_outfile);
a27a5de9 859 else
36cd856f
DM
860 print_mem_expr (m_outfile, PAT_VAR_LOCATION_DECL (in_rtx));
861 fputc (' ', m_outfile);
a27a5de9
SB
862 print_rtx (PAT_VAR_LOCATION_LOC (in_rtx));
863 if (PAT_VAR_LOCATION_STATUS (in_rtx)
864 == VAR_INIT_STATUS_UNINITIALIZED)
36cd856f
DM
865 fprintf (m_outfile, " [uninit]");
866 m_sawclose = 1;
acda0629 867 idx = GET_RTX_LENGTH (VAR_LOCATION);
735a0e33 868 }
a27a5de9 869#endif
e1a79915
RS
870 }
871
69bd00e6 872#ifndef GENERATOR_FILE
48175537 873 if (CONST_DOUBLE_AS_FLOAT_P (in_rtx))
acda0629 874 idx = 5;
69bd00e6
RH
875#endif
876
7574cfd4
DM
877 /* For insns, print the INSN_UID. */
878 if (INSN_CHAIN_CODE_P (GET_CODE (in_rtx)))
25109109
RS
879 {
880 if (flag_dump_unnumbered)
36cd856f 881 fprintf (m_outfile, " #");
25109109 882 else
36cd856f 883 fprintf (m_outfile, " %d", INSN_UID (in_rtx));
25109109 884 }
ed8921dc 885
b5fbe716
DM
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
735a0e33
UD
894 /* Get the format string and skip the first elements if we have handled
895 them already. */
b5fbe716
DM
896
897 for (; idx < limit; idx++)
acda0629 898 print_rtx_operand (in_rtx, idx);
e1a79915 899
be1bb652
RH
900 switch (GET_CODE (in_rtx))
901 {
6ebd2ef4 902#ifndef GENERATOR_FILE
be1bb652 903 case MEM:
6ca5d1f6 904 if (__builtin_expect (final_insns_dump_p, false))
36cd856f 905 fprintf (m_outfile, " [");
6ca5d1f6 906 else
36cd856f 907 fprintf (m_outfile, " [" HOST_WIDE_INT_PRINT_DEC,
6ca5d1f6 908 (HOST_WIDE_INT) MEM_ALIAS_SET (in_rtx));
998d7deb
RH
909
910 if (MEM_EXPR (in_rtx))
36cd856f 911 print_mem_expr (m_outfile, MEM_EXPR (in_rtx));
9ccf7d92 912 else
36cd856f 913 fputc (' ', m_outfile);
738cc472 914
527210c4 915 if (MEM_OFFSET_KNOWN_P (in_rtx))
d05d7551
RS
916 {
917 fprintf (m_outfile, "+");
918 print_poly_int (m_outfile, MEM_OFFSET (in_rtx));
919 }
738cc472 920
f5541398 921 if (MEM_SIZE_KNOWN_P (in_rtx))
d05d7551
RS
922 {
923 fprintf (m_outfile, " S");
924 print_poly_int (m_outfile, MEM_SIZE (in_rtx));
925 }
738cc472
RK
926
927 if (MEM_ALIGN (in_rtx) != 1)
36cd856f 928 fprintf (m_outfile, " A%u", MEM_ALIGN (in_rtx));
738cc472 929
09e881c9 930 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (in_rtx)))
36cd856f 931 fprintf (m_outfile, " AS%u", MEM_ADDR_SPACE (in_rtx));
09e881c9 932
36cd856f 933 fputc (']', m_outfile);
be1bb652 934 break;
5a0a1a66 935
be1bb652
RH
936 case CONST_DOUBLE:
937 if (FLOAT_MODE_P (GET_MODE (in_rtx)))
938 {
4fdbcfb2 939 char s[60];
b216cd4a 940
da6eec72
RH
941 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
942 sizeof (s), 0, 1);
36cd856f 943 fprintf (m_outfile, " %s", s);
69bd00e6 944
da6eec72
RH
945 real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
946 sizeof (s), 0, 1);
36cd856f 947 fprintf (m_outfile, " [%s]", s);
be1bb652
RH
948 }
949 break;
807e902e
KZ
950
951 case CONST_WIDE_INT:
36cd856f
DM
952 fprintf (m_outfile, " ");
953 cwi_output_hex (m_outfile, in_rtx);
807e902e 954 break;
0c12fc9b
RS
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;
800d5c9e
RH
966#endif
967
be1bb652 968 case CODE_LABEL:
36cd856f
DM
969 if (!m_compact)
970 fprintf (m_outfile, " [%d uses]", LABEL_NUSES (in_rtx));
0dc36574
ZW
971 switch (LABEL_KIND (in_rtx))
972 {
973 case LABEL_NORMAL: break;
36cd856f
DM
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;
e16acfcd 977 default: gcc_unreachable ();
0dc36574 978 }
be1bb652
RH
979 break;
980
be1bb652
RH
981 default:
982 break;
8cd0faaf 983 }
c3c63936 984
36cd856f
DM
985 fputc (')', m_outfile);
986 m_sawclose = 1;
e1a79915
RS
987}
988
677aa9b4
DM
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
1d79197a
RK
998/* Print an rtx on the current line of FILE. Initially indent IND
999 characters. */
1000
1001void
f7d504c2 1002print_inline_rtx (FILE *outf, const_rtx x, int ind)
1d79197a 1003{
00439aef 1004 rtx_writer w (outf, ind, false, false, NULL);
36cd856f 1005 w.print_rtx (x);
1d79197a
RK
1006}
1007
e1a79915
RS
1008/* Call this function from the debugger to see what X looks like. */
1009
24e47c76 1010DEBUG_FUNCTION void
f7d504c2 1011debug_rtx (const_rtx x)
e1a79915 1012{
00439aef 1013 rtx_writer w (stderr, 0, false, false, NULL);
36cd856f 1014 w.print_rtx (x);
e1a79915
RS
1015 fprintf (stderr, "\n");
1016}
1017
7b3b6ae4
LC
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
19a30b71
AH
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
716f003f
DE
1052/* Count of rtx's to print with debug_rtx_list.
1053 This global exists because gdb user defined commands have no arguments. */
1054
24e47c76 1055DEBUG_VARIABLE int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */
716f003f
DE
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
f719babc
DM
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). */
716f003f 1063
24e47c76 1064DEBUG_FUNCTION void
f719babc 1065debug_rtx_list (const rtx_insn *x, int n)
716f003f
DE
1066{
1067 int i,count;
f719babc 1068 const rtx_insn *insn;
716f003f
DE
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))
7f11f1f9
AS
1083 {
1084 debug_rtx (insn);
1085 fprintf (stderr, "\n");
1086 }
716f003f
DE
1087}
1088
f719babc
DM
1089/* Call this function to print an rtx_insn list from START to END
1090 inclusive. */
4c85a96d 1091
24e47c76 1092DEBUG_FUNCTION void
f719babc 1093debug_rtx_range (const rtx_insn *start, const rtx_insn *end)
4c85a96d
RH
1094{
1095 while (1)
1096 {
1097 debug_rtx (start);
7f11f1f9 1098 fprintf (stderr, "\n");
4c85a96d
RH
1099 if (!start || start == end)
1100 break;
1101 start = NEXT_INSN (start);
1102 }
1103}
1104
f719babc 1105/* Call this function to search an rtx_insn list to find one with insn uid UID,
716f003f
DE
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
e67d1102 1109DEBUG_FUNCTION const rtx_insn *
f719babc 1110debug_rtx_find (const rtx_insn *x, int uid)
716f003f
DE
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
e1a79915 1126/* External entry point for printing a chain of insns
36cd856f 1127 starting with RTX_FIRST.
e1a79915
RS
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
36cd856f 1133rtx_writer::print_rtl (const_rtx rtx_first)
e1a79915 1134{
f719babc 1135 const rtx_insn *tmp_rtx;
9dbe7947 1136
e1a79915 1137 if (rtx_first == 0)
c349e40b 1138 {
36cd856f
DM
1139 fputs (print_rtx_head, m_outfile);
1140 fputs ("(nil)\n", m_outfile);
c349e40b 1141 }
e1a79915
RS
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:
39718607 1150 case JUMP_TABLE_DATA:
e1a79915 1151 case BARRIER:
f719babc
DM
1152 for (tmp_rtx = as_a <const rtx_insn *> (rtx_first);
1153 tmp_rtx != 0;
1154 tmp_rtx = NEXT_INSN (tmp_rtx))
9dbe7947 1155 {
36cd856f 1156 fputs (print_rtx_head, m_outfile);
9dbe7947 1157 print_rtx (tmp_rtx);
36cd856f 1158 fprintf (m_outfile, "\n");
9dbe7947 1159 }
e1a79915
RS
1160 break;
1161
1162 default:
36cd856f 1163 fputs (print_rtx_head, m_outfile);
e1a79915
RS
1164 print_rtx (rtx_first);
1165 }
1166}
3e28fe44 1167
36cd856f
DM
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{
00439aef 1177 rtx_writer w (outf, 0, false, false, NULL);
36cd856f
DM
1178 w.print_rtl (rtx_first);
1179}
1180
3e28fe44 1181/* Like print_rtx, except specify a file. */
b707b450 1182/* Return nonzero if we actually printed anything. */
3e28fe44 1183
b707b450 1184int
f7d504c2 1185print_rtl_single (FILE *outf, const_rtx x)
3e28fe44 1186{
00439aef 1187 rtx_writer w (outf, 0, false, false, NULL);
36cd856f 1188 return w.print_rtl_single_with_indent (x, 0);
df92c640
SB
1189}
1190
36cd856f 1191/* Like print_rtl_single, except specify an indentation. */
df92c640
SB
1192
1193int
36cd856f 1194rtx_writer::print_rtl_single_with_indent (const_rtx x, int ind)
df92c640 1195{
df92c640
SB
1196 char *s_indent = (char *) alloca ((size_t) ind + 1);
1197 memset ((void *) s_indent, ' ', (size_t) ind);
1198 s_indent[ind] = '\0';
36cd856f
DM
1199 fputs (s_indent, m_outfile);
1200 fputs (print_rtx_head, m_outfile);
df92c640 1201
36cd856f
DM
1202 int old_indent = m_indent;
1203 m_indent = ind;
1204 m_sawclose = 0;
297e9b46 1205 print_rtx (x);
36cd856f
DM
1206 putc ('\n', m_outfile);
1207 m_indent = old_indent;
297e9b46 1208 return 1;
3e28fe44 1209}
75b7557d
MH
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
f7d504c2 1216print_simple_rtl (FILE *outf, const_rtx x)
75b7557d 1217{
00439aef 1218 rtx_writer w (outf, 0, true, false, NULL);
36cd856f 1219 w.print_rtl (x);
75b7557d 1220}
013a8899 1221
e4dbabfe
TS
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
013a8899
JL
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:
d5e2c91a 1368 st[0] = "~";
013a8899
JL
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
0c12fc9b
RS
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
013a8899
JL
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:
04a121a7 1687 pp_printf (pp, "L%d", INSN_UID (label_ref_label (x)));
013a8899
JL
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);
91914e56
RS
1710 pp_printf (pp, "#");
1711 pp_wide_integer (pp, SUBREG_BYTE (x));
013a8899
JL
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:
8df47bdf 1759 case CLOBBER_HIGH:
013a8899
JL
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 {
96a95ac1
AO
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
58006663
AO
1897 case NOTE_INSN_INLINE_ENTRY:
1898 pp_string (pp, "debug inline entry marker");
1899 break;
1900
96a95ac1
AO
1901 default:
1902 gcc_unreachable ();
1903 }
1904 break;
1905 }
1906
013a8899 1907 const char *name = "?";
050dcb6a 1908 char idbuf[32];
013a8899
JL
1909
1910 if (DECL_P (INSN_VAR_LOCATION_DECL (x)))
1911 {
1912 tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (x));
013a8899
JL
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:
013a8899
JL
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