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