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