1/* Print RTL for GCC. 2 Copyright (C) 1987-2015 Free Software Foundation, Inc. 3 4This file is part of GCC. 5 6GCC is free software; you can redistribute it and/or modify it under 7the terms of the GNU General Public License as published by the Free 8Software Foundation; either version 3, or (at your option) any later 9version. 10 11GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12WARRANTY; without even the implied warranty of MERCHANTABILITY or 13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14for more details. 15 16You should have received a copy of the GNU General Public License 17along 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 "hash-set.h" 37#include "machmode.h" 38#include "vec.h" 39#include "double-int.h" 40#include "input.h" 41#include "alias.h" 42#include "symtab.h" 43#include "wide-int.h" 44#include "inchash.h" 45#include "tree.h" 46#include "print-tree.h" 47#include "flags.h" 48#include "hard-reg-set.h" 49#include "predict.h" 50#include "input.h" 51#include "function.h" 52#include "basic-block.h" 53#include "diagnostic.h" 54#include "tree-pretty-print.h" 55#include "cselib.h" 56#include "dumpfile.h" /* for dump_flags */ 57#include "dwarf2out.h" 58#endif 59 60static FILE *outfile; 61 62static int sawclose = 0; 63 64static int indent; 65 66static bool in_call_function_usage; 67 68static void print_rtx (const_rtx); 69 70/* String printed at beginning of each RTL when it is dumped. 71 This string is set to ASM_COMMENT_START when the RTL is dumped in 72 the assembly output file. */ 73const char *print_rtx_head = ""; 74 75#ifdef GENERATOR_FILE 76/* These are defined from the .opt file when not used in generator 77 programs. */ 78 79/* Nonzero means suppress output of instruction numbers 80 in debugging dumps. 81 This must be defined here so that programs like gencodes can be linked. */ 82int flag_dump_unnumbered = 0; 83 84/* Nonzero means suppress output of instruction numbers for previous 85 and next insns in debugging dumps. 86 This must be defined here so that programs like gencodes can be linked. */ 87int flag_dump_unnumbered_links = 0; 88#endif 89 90/* Nonzero means use simplified format without flags, modes, etc. */ 91int flag_simple = 0; 92 93#ifndef GENERATOR_FILE 94void 95print_mem_expr (FILE *outfile, const_tree expr) 96{ 97 fputc (' ', outfile); 98 print_generic_expr (outfile, CONST_CAST_TREE (expr), dump_flags); 99} 100#endif 101 102/* Print IN_RTX onto OUTFILE. This is the recursive part of printing. */ 103 104static void 105print_rtx (const_rtx in_rtx) 106{ 107 int i = 0; 108 int j; 109 const char *format_ptr; 110 int is_insn; 111 112 if (sawclose) 113 { 114 if (flag_simple) 115 fputc (' ', outfile); 116 else 117 fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, ""); 118 sawclose = 0; 119 } 120 121 if (in_rtx == 0) 122 { 123 fputs ("(nil)", outfile); 124 sawclose = 1; 125 return; 126 } 127 else if (GET_CODE (in_rtx) > NUM_RTX_CODE) 128 { 129 fprintf (outfile, "(??? bad code %d\n%s%*s)", GET_CODE (in_rtx), 130 print_rtx_head, indent * 2, ""); 131 sawclose = 1; 132 return; 133 } 134 135 is_insn = INSN_P (in_rtx); 136 137 /* Print name of expression code. */ 138 if (flag_simple && CONST_INT_P (in_rtx)) 139 fputc ('(', outfile); 140 else 141 fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx))); 142 143 if (! flag_simple) 144 { 145 if (RTX_FLAG (in_rtx, in_struct)) 146 fputs ("/s", outfile); 147 148 if (RTX_FLAG (in_rtx, volatil)) 149 fputs ("/v", outfile); 150 151 if (RTX_FLAG (in_rtx, unchanging)) 152 fputs ("/u", outfile); 153 154 if (RTX_FLAG (in_rtx, frame_related)) 155 fputs ("/f", outfile); 156 157 if (RTX_FLAG (in_rtx, jump)) 158 fputs ("/j", outfile); 159 160 if (RTX_FLAG (in_rtx, call)) 161 fputs ("/c", outfile); 162 163 if (RTX_FLAG (in_rtx, return_val)) 164 fputs ("/i", outfile); 165 166 /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */ 167 if ((GET_CODE (in_rtx) == EXPR_LIST 168 || GET_CODE (in_rtx) == INSN_LIST 169 || GET_CODE (in_rtx) == INT_LIST) 170 && (int)GET_MODE (in_rtx) < REG_NOTE_MAX 171 && !in_call_function_usage) 172 fprintf (outfile, ":%s", 173 GET_REG_NOTE_NAME (GET_MODE (in_rtx))); 174 175 /* For other rtl, print the mode if it's not VOID. */ 176 else if (GET_MODE (in_rtx) != VOIDmode) 177 fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx))); 178 179#ifndef GENERATOR_FILE 180 if (GET_CODE (in_rtx) == VAR_LOCATION) 181 { 182 if (TREE_CODE (PAT_VAR_LOCATION_DECL (in_rtx)) == STRING_CST) 183 fputs (" <debug string placeholder>", outfile); 184 else 185 print_mem_expr (outfile, PAT_VAR_LOCATION_DECL (in_rtx)); 186 fputc (' ', outfile); 187 print_rtx (PAT_VAR_LOCATION_LOC (in_rtx)); 188 if (PAT_VAR_LOCATION_STATUS (in_rtx) 189 == VAR_INIT_STATUS_UNINITIALIZED) 190 fprintf (outfile, " [uninit]"); 191 sawclose = 1; 192 i = GET_RTX_LENGTH (VAR_LOCATION); 193 } 194#endif 195 } 196 197#ifndef GENERATOR_FILE 198 if (CONST_DOUBLE_AS_FLOAT_P (in_rtx)) 199 i = 5; 200#endif 201 202 if (INSN_CHAIN_CODE_P (GET_CODE (in_rtx))) 203 { 204 if (flag_dump_unnumbered) 205 fprintf (outfile, " #"); 206 else 207 fprintf (outfile, " %d", INSN_UID (in_rtx)); 208 } 209 210 /* Get the format string and skip the first elements if we have handled 211 them already. */ 212 format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)) + i; 213 for (; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++) 214 switch (*format_ptr++) 215 { 216 const char *str; 217 218 case 'T': 219 str = XTMPL (in_rtx, i); 220 goto string; 221 222 case 'S': 223 case 's': 224 str = XSTR (in_rtx, i); 225 string: 226 227 if (str == 0) 228 fputs (" \"\"", outfile); 229 else 230 fprintf (outfile, " (\"%s\")", str); 231 sawclose = 1; 232 break; 233 234 /* 0 indicates a field for internal use that should not be printed. 235 An exception is the third field of a NOTE, where it indicates 236 that the field has several different valid contents. */ 237 case '0': 238#ifndef GENERATOR_FILE 239 if (i == 1 && GET_CODE (in_rtx) == SYMBOL_REF) 240 { 241 int flags = SYMBOL_REF_FLAGS (in_rtx); 242 if (flags) 243 fprintf (outfile, " [flags %#x]", flags); 244 tree decl = SYMBOL_REF_DECL (in_rtx); 245 if (decl) 246 print_node_brief (outfile, "", decl, dump_flags); 247 } 248 else if (i == 3 && NOTE_P (in_rtx)) 249 { 250 switch (NOTE_KIND (in_rtx)) 251 { 252 case NOTE_INSN_EH_REGION_BEG: 253 case NOTE_INSN_EH_REGION_END: 254 if (flag_dump_unnumbered) 255 fprintf (outfile, " #"); 256 else 257 fprintf (outfile, " %d", NOTE_EH_HANDLER (in_rtx)); 258 sawclose = 1; 259 break; 260 261 case NOTE_INSN_BLOCK_BEG: 262 case NOTE_INSN_BLOCK_END: 263 dump_addr (outfile, " ", NOTE_BLOCK (in_rtx)); 264 sawclose = 1; 265 break; 266 267 case NOTE_INSN_BASIC_BLOCK: 268 { 269 basic_block bb = NOTE_BASIC_BLOCK (in_rtx); 270 if (bb != 0) 271 fprintf (outfile, " [bb %d]", bb->index); 272 break; 273 } 274 275 case NOTE_INSN_DELETED_LABEL: 276 case NOTE_INSN_DELETED_DEBUG_LABEL: 277 { 278 const char *label = NOTE_DELETED_LABEL_NAME (in_rtx); 279 if (label) 280 fprintf (outfile, " (\"%s\")", label); 281 else 282 fprintf (outfile, " \"\""); 283 } 284 break; 285 286 case NOTE_INSN_SWITCH_TEXT_SECTIONS: 287 { 288 basic_block bb = NOTE_BASIC_BLOCK (in_rtx); 289 if (bb != 0) 290 fprintf (outfile, " [bb %d]", bb->index); 291 break; 292 } 293 294 case NOTE_INSN_VAR_LOCATION: 295 case NOTE_INSN_CALL_ARG_LOCATION: 296 fputc (' ', outfile); 297 print_rtx (NOTE_VAR_LOCATION (in_rtx)); 298 break; 299 300 case NOTE_INSN_CFI: 301 fputc ('\n', outfile); 302 output_cfi_directive (outfile, NOTE_CFI (in_rtx)); 303 fputc ('\t', outfile); 304 break; 305 306 default: 307 break; 308 } 309 } 310 else if (i == 7 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL) 311 { 312 /* Output the JUMP_LABEL reference. */ 313 fprintf (outfile, "\n%s%*s -> ", print_rtx_head, indent * 2, ""); 314 if (GET_CODE (JUMP_LABEL (in_rtx)) == RETURN) 315 fprintf (outfile, "return"); 316 else if (GET_CODE (JUMP_LABEL (in_rtx)) == SIMPLE_RETURN) 317 fprintf (outfile, "simple_return"); 318 else 319 fprintf (outfile, "%d", INSN_UID (JUMP_LABEL (in_rtx))); 320 } 321 else if (i == 0 && GET_CODE (in_rtx) == VALUE) 322 { 323 cselib_val *val = CSELIB_VAL_PTR (in_rtx); 324 325 fprintf (outfile, " %u:%u", val->uid, val->hash); 326 dump_addr (outfile, " @", in_rtx); 327 dump_addr (outfile, "/", (void*)val); 328 } 329 else if (i == 0 && GET_CODE (in_rtx) == DEBUG_EXPR) 330 { 331 fprintf (outfile, " D#%i", 332 DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (in_rtx))); 333 } 334 else if (i == 0 && GET_CODE (in_rtx) == ENTRY_VALUE) 335 { 336 indent += 2; 337 if (!sawclose) 338 fprintf (outfile, " "); 339 print_rtx (ENTRY_VALUE_EXP (in_rtx)); 340 indent -= 2; 341 } 342#endif 343 break; 344 345 case 'e': 346 do_e: 347 indent += 2; 348 if (i == 6 && INSN_P (in_rtx)) 349 /* Put REG_NOTES on their own line. */ 350 fprintf (outfile, "\n%s%*s", 351 print_rtx_head, indent * 2, ""); 352 if (!sawclose) 353 fprintf (outfile, " "); 354 if (i == 7 && CALL_P (in_rtx)) 355 { 356 in_call_function_usage = true; 357 print_rtx (XEXP (in_rtx, i)); 358 in_call_function_usage = false; 359 } 360 else 361 print_rtx (XEXP (in_rtx, i)); 362 indent -= 2; 363 break; 364 365 case 'E': 366 case 'V': 367 indent += 2; 368 if (sawclose) 369 { 370 fprintf (outfile, "\n%s%*s", 371 print_rtx_head, indent * 2, ""); 372 sawclose = 0; 373 } 374 fputs (" [", outfile); 375 if (NULL != XVEC (in_rtx, i)) 376 { 377 indent += 2; 378 if (XVECLEN (in_rtx, i)) 379 sawclose = 1; 380 381 for (j = 0; j < XVECLEN (in_rtx, i); j++) 382 print_rtx (XVECEXP (in_rtx, i, j)); 383 384 indent -= 2; 385 } 386 if (sawclose) 387 fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, ""); 388 389 fputs ("]", outfile); 390 sawclose = 1; 391 indent -= 2; 392 break; 393 394 case 'w': 395 if (! flag_simple) 396 fprintf (outfile, " "); 397 fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, i)); 398 if (! flag_simple) 399 fprintf (outfile, " [" HOST_WIDE_INT_PRINT_HEX "]", 400 (unsigned HOST_WIDE_INT) XWINT (in_rtx, i)); 401 break; 402 403 case 'i': 404 if (i == 4 && INSN_P (in_rtx)) 405 { 406#ifndef GENERATOR_FILE 407 const rtx_insn *in_insn = as_a <const rtx_insn *> (in_rtx); 408 409 /* Pretty-print insn locations. Ignore scoping as it is mostly 410 redundant with line number information and do not print anything 411 when there is no location information available. */ 412 if (INSN_HAS_LOCATION (in_insn)) 413 { 414 expanded_location xloc = insn_location (in_insn); 415 fprintf (outfile, " %s:%i", xloc.file, xloc.line); 416 } 417#endif 418 } 419 else if (i == 6 && GET_CODE (in_rtx) == ASM_OPERANDS) 420 { 421#ifndef GENERATOR_FILE 422 if (ASM_OPERANDS_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION) 423 fprintf (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 (i == 1 && GET_CODE (in_rtx) == ASM_INPUT) 429 { 430#ifndef GENERATOR_FILE 431 if (ASM_INPUT_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION) 432 fprintf (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 (i == 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 (outfile, " %d", XINT (in_rtx, i)); 444 } 445#if !defined(GENERATOR_FILE) && NUM_UNSPECV_VALUES > 0 446 else if (i == 1 447 && GET_CODE (in_rtx) == UNSPEC_VOLATILE 448 && XINT (in_rtx, 1) >= 0 449 && XINT (in_rtx, 1) < NUM_UNSPECV_VALUES) 450 fprintf (outfile, " %s", unspecv_strings[XINT (in_rtx, 1)]); 451#endif 452#if !defined(GENERATOR_FILE) && NUM_UNSPEC_VALUES > 0 453 else if (i == 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 (outfile, " %s", unspec_strings[XINT (in_rtx, 1)]); 459#endif 460 else 461 { 462 int value = XINT (in_rtx, i); 463 const char *name; 464 465#ifndef GENERATOR_FILE 466 if (REG_P (in_rtx) && (unsigned) value < FIRST_PSEUDO_REGISTER) 467 fprintf (outfile, " %d %s", value, reg_names[value]); 468 else if (REG_P (in_rtx) 469 && (unsigned) value <= LAST_VIRTUAL_REGISTER) 470 { 471 if (value == VIRTUAL_INCOMING_ARGS_REGNUM) 472 fprintf (outfile, " %d virtual-incoming-args", value); 473 else if (value == VIRTUAL_STACK_VARS_REGNUM) 474 fprintf (outfile, " %d virtual-stack-vars", value); 475 else if (value == VIRTUAL_STACK_DYNAMIC_REGNUM) 476 fprintf (outfile, " %d virtual-stack-dynamic", value); 477 else if (value == VIRTUAL_OUTGOING_ARGS_REGNUM) 478 fprintf (outfile, " %d virtual-outgoing-args", value); 479 else if (value == VIRTUAL_CFA_REGNUM) 480 fprintf (outfile, " %d virtual-cfa", value); 481 else if (value == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM) 482 fprintf (outfile, " %d virtual-preferred-stack-boundary", 483 value); 484 else 485 fprintf (outfile, " %d virtual-reg-%d", value, 486 value-FIRST_VIRTUAL_REGISTER); 487 } 488 else 489#endif 490 if (flag_dump_unnumbered 491 && (is_insn || NOTE_P (in_rtx))) 492 fputc ('#', outfile); 493 else 494 fprintf (outfile, " %d", value); 495 496#ifndef GENERATOR_FILE 497 if (REG_P (in_rtx) && REG_ATTRS (in_rtx)) 498 { 499 fputs (" [", outfile); 500 if (ORIGINAL_REGNO (in_rtx) != REGNO (in_rtx)) 501 fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx)); 502 if (REG_EXPR (in_rtx)) 503 print_mem_expr (outfile, REG_EXPR (in_rtx)); 504 505 if (REG_OFFSET (in_rtx)) 506 fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, 507 REG_OFFSET (in_rtx)); 508 fputs (" ]", outfile); 509 } 510 if (REG_P (in_rtx) && REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx)) 511 fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx)); 512#endif 513 514 if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i) 515 && XINT (in_rtx, i) >= 0 516 && (name = get_insn_name (XINT (in_rtx, i))) != NULL) 517 fprintf (outfile, " {%s}", name); 518 sawclose = 0; 519 } 520 break; 521 522 /* Print NOTE_INSN names rather than integer codes. */ 523 524 case 'n': 525 fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i))); 526 sawclose = 0; 527 break; 528 529 case 'u': 530 if (XEXP (in_rtx, i) != NULL) 531 { 532 rtx sub = XEXP (in_rtx, i); 533 enum rtx_code subc = GET_CODE (sub); 534 535 if (GET_CODE (in_rtx) == LABEL_REF) 536 { 537 if (subc == NOTE 538 && NOTE_KIND (sub) == NOTE_INSN_DELETED_LABEL) 539 { 540 if (flag_dump_unnumbered) 541 fprintf (outfile, " [# deleted]"); 542 else 543 fprintf (outfile, " [%d deleted]", INSN_UID (sub)); 544 sawclose = 0; 545 break; 546 } 547 548 if (subc != CODE_LABEL) 549 goto do_e; 550 } 551 552 if (flag_dump_unnumbered 553 || (flag_dump_unnumbered_links && (i == 1 || i == 2) 554 && (INSN_P (in_rtx) || NOTE_P (in_rtx) 555 || LABEL_P (in_rtx) || BARRIER_P (in_rtx)))) 556 fputs (" #", outfile); 557 else 558 fprintf (outfile, " %d", INSN_UID (sub)); 559 } 560 else 561 fputs (" 0", outfile); 562 sawclose = 0; 563 break; 564 565 case 't': 566#ifndef GENERATOR_FILE 567 if (i == 0 && GET_CODE (in_rtx) == DEBUG_IMPLICIT_PTR) 568 print_mem_expr (outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx)); 569 else if (i == 0 && GET_CODE (in_rtx) == DEBUG_PARAMETER_REF) 570 print_mem_expr (outfile, DEBUG_PARAMETER_REF_DECL (in_rtx)); 571 else 572 dump_addr (outfile, " ", XTREE (in_rtx, i)); 573#endif 574 break; 575 576 case '*': 577 fputs (" Unknown", outfile); 578 sawclose = 0; 579 break; 580 581 case 'B': 582#ifndef GENERATOR_FILE 583 if (XBBDEF (in_rtx, i)) 584 fprintf (outfile, " %i", XBBDEF (in_rtx, i)->index); 585#endif 586 break; 587 588 default: 589 gcc_unreachable (); 590 } 591 592 switch (GET_CODE (in_rtx)) 593 { 594#ifndef GENERATOR_FILE 595 case MEM: 596 if (__builtin_expect (final_insns_dump_p, false)) 597 fprintf (outfile, " ["); 598 else 599 fprintf (outfile, " [" HOST_WIDE_INT_PRINT_DEC, 600 (HOST_WIDE_INT) MEM_ALIAS_SET (in_rtx)); 601 602 if (MEM_EXPR (in_rtx)) 603 print_mem_expr (outfile, MEM_EXPR (in_rtx)); 604 else 605 fputc (' ', outfile); 606 607 if (MEM_OFFSET_KNOWN_P (in_rtx)) 608 fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, MEM_OFFSET (in_rtx)); 609 610 if (MEM_SIZE_KNOWN_P (in_rtx)) 611 fprintf (outfile, " S" HOST_WIDE_INT_PRINT_DEC, MEM_SIZE (in_rtx)); 612 613 if (MEM_ALIGN (in_rtx) != 1) 614 fprintf (outfile, " A%u", MEM_ALIGN (in_rtx)); 615 616 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (in_rtx))) 617 fprintf (outfile, " AS%u", MEM_ADDR_SPACE (in_rtx)); 618 619 fputc (']', outfile); 620 break; 621 622 case CONST_DOUBLE: 623 if (FLOAT_MODE_P (GET_MODE (in_rtx))) 624 { 625 char s[60]; 626 627 real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx), 628 sizeof (s), 0, 1); 629 fprintf (outfile, " %s", s); 630 631 real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx), 632 sizeof (s), 0, 1); 633 fprintf (outfile, " [%s]", s); 634 } 635 break; 636 637 case CONST_WIDE_INT: 638 fprintf (outfile, " "); 639 cwi_output_hex (outfile, in_rtx); 640 break; 641#endif 642 643 case CODE_LABEL: 644 fprintf (outfile, " [%d uses]", LABEL_NUSES (in_rtx)); 645 switch (LABEL_KIND (in_rtx)) 646 { 647 case LABEL_NORMAL: break; 648 case LABEL_STATIC_ENTRY: fputs (" [entry]", outfile); break; 649 case LABEL_GLOBAL_ENTRY: fputs (" [global entry]", outfile); break; 650 case LABEL_WEAK_ENTRY: fputs (" [weak entry]", outfile); break; 651 default: gcc_unreachable (); 652 } 653 break; 654 655 default: 656 break; 657 } 658 659 fputc (')', outfile); 660 sawclose = 1; 661} 662 663/* Print an rtx on the current line of FILE. Initially indent IND 664 characters. */ 665 666void 667print_inline_rtx (FILE *outf, const_rtx x, int ind) 668{ 669 int oldsaw = sawclose; 670 int oldindent = indent; 671 672 sawclose = 0; 673 indent = ind; 674 outfile = outf; 675 print_rtx (x); 676 sawclose = oldsaw; 677 indent = oldindent; 678} 679 680/* Call this function from the debugger to see what X looks like. */ 681 682DEBUG_FUNCTION void 683debug_rtx (const_rtx x) 684{ 685 outfile = stderr; 686 sawclose = 0; 687 print_rtx (x); 688 fprintf (stderr, "\n"); 689} 690 691/* Dump rtx REF. */ 692 693DEBUG_FUNCTION void 694debug (const rtx_def &ref) 695{ 696 debug_rtx (&ref); 697} 698 699DEBUG_FUNCTION void 700debug (const rtx_def *ptr) 701{ 702 if (ptr) 703 debug (*ptr); 704 else 705 fprintf (stderr, "<nil>\n"); 706} 707 708/* Count of rtx's to print with debug_rtx_list. 709 This global exists because gdb user defined commands have no arguments. */ 710 711DEBUG_VARIABLE int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */ 712 713/* Call this function to print list from X on. 714 715 N is a count of the rtx's to print. Positive values print from the specified 716 rtx_insn on. Negative values print a window around the rtx_insn. 717 EG: -5 prints 2 rtx_insn's on either side (in addition to the specified 718 rtx_insn). */ 719 720DEBUG_FUNCTION void 721debug_rtx_list (const rtx_insn *x, int n) 722{ 723 int i,count; 724 const rtx_insn *insn; 725 726 count = n == 0 ? 1 : n < 0 ? -n : n; 727 728 /* If we are printing a window, back up to the start. */ 729 730 if (n < 0) 731 for (i = count / 2; i > 0; i--) 732 { 733 if (PREV_INSN (x) == 0) 734 break; 735 x = PREV_INSN (x); 736 } 737 738 for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn)) 739 { 740 debug_rtx (insn); 741 fprintf (stderr, "\n"); 742 } 743} 744 745/* Call this function to print an rtx_insn list from START to END 746 inclusive. */ 747 748DEBUG_FUNCTION void 749debug_rtx_range (const rtx_insn *start, const rtx_insn *end) 750{ 751 while (1) 752 { 753 debug_rtx (start); 754 fprintf (stderr, "\n"); 755 if (!start || start == end) 756 break; 757 start = NEXT_INSN (start); 758 } 759} 760 761/* Call this function to search an rtx_insn list to find one with insn uid UID, 762 and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT. 763 The found insn is returned to enable further debugging analysis. */ 764 765DEBUG_FUNCTION const_rtx 766debug_rtx_find (const rtx_insn *x, int uid) 767{ 768 while (x != 0 && INSN_UID (x) != uid) 769 x = NEXT_INSN (x); 770 if (x != 0) 771 { 772 debug_rtx_list (x, debug_rtx_count); 773 return x; 774 } 775 else 776 { 777 fprintf (stderr, "insn uid %d not found\n", uid); 778 return 0; 779 } 780} 781 782/* External entry point for printing a chain of insns 783 starting with RTX_FIRST onto file OUTF. 784 A blank line separates insns. 785 786 If RTX_FIRST is not an insn, then it alone is printed, with no newline. */ 787 788void 789print_rtl (FILE *outf, const_rtx rtx_first) 790{ 791 const rtx_insn *tmp_rtx; 792 793 outfile = outf; 794 sawclose = 0; 795 796 if (rtx_first == 0) 797 { 798 fputs (print_rtx_head, outf); 799 fputs ("(nil)\n", outf); 800 } 801 else 802 switch (GET_CODE (rtx_first)) 803 { 804 case INSN: 805 case JUMP_INSN: 806 case CALL_INSN: 807 case NOTE: 808 case CODE_LABEL: 809 case JUMP_TABLE_DATA: 810 case BARRIER: 811 for (tmp_rtx = as_a <const rtx_insn *> (rtx_first); 812 tmp_rtx != 0; 813 tmp_rtx = NEXT_INSN (tmp_rtx)) 814 { 815 fputs (print_rtx_head, outfile); 816 print_rtx (tmp_rtx); 817 fprintf (outfile, "\n"); 818 } 819 break; 820 821 default: 822 fputs (print_rtx_head, outfile); 823 print_rtx (rtx_first); 824 } 825} 826 827/* Like print_rtx, except specify a file. */ 828/* Return nonzero if we actually printed anything. */ 829 830int 831print_rtl_single (FILE *outf, const_rtx x) 832{ 833 return print_rtl_single_with_indent (outf, x, 0); 834} 835 836/* Like print_rtl_single, except specify a file and indentation. */ 837 838int 839print_rtl_single_with_indent (FILE *outf, const_rtx x, int ind) 840{ 841 int old_indent = indent; 842 char *s_indent = (char *) alloca ((size_t) ind + 1); 843 memset ((void *) s_indent, ' ', (size_t) ind); 844 s_indent[ind] = '\0'; 845 846 indent = ind; 847 outfile = outf; 848 sawclose = 0; 849 fputs (s_indent, outfile); 850 fputs (print_rtx_head, outfile); 851 print_rtx (x); 852 putc ('\n', outf); 853 indent = old_indent; 854 return 1; 855} 856 857 858/* Like print_rtl except without all the detail; for example, 859 if RTX is a CONST_INT then print in decimal format. */ 860 861void 862print_simple_rtl (FILE *outf, const_rtx x) 863{ 864 flag_simple = 1; 865 print_rtl (outf, x); 866 flag_simple = 0; 867} 868