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