1 /* RTL utility routines. 2 Copyright (C) 1987-2020 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 #ifdef GENERATOR_FILE 33 # include "errors.h" 34 #else 35 # include "rtlhash.h" 36 # include "diagnostic-core.h" 37 #endif 38 39 40 /* Indexed by rtx code, gives number of operands for an rtx with that code. 41 Does NOT include rtx header data (code and links). */ 42 43 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) sizeof FORMAT - 1 , 44 45 const unsigned char rtx_length[NUM_RTX_CODE] = { 46 #include "rtl.def" 47 }; 48 49 #undef DEF_RTL_EXPR 50 51 /* Indexed by rtx code, gives the name of that kind of rtx, as a C string. */ 52 53 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME , 54 55 const char * const rtx_name[NUM_RTX_CODE] = { 56 #include "rtl.def" /* rtl expressions are documented here */ 57 }; 58 59 #undef DEF_RTL_EXPR 60 61 /* Indexed by rtx code, gives a sequence of operand-types for 62 rtx's of that code. The sequence is a C string in which 63 each character describes one operand. */ 64 65 const char * const rtx_format[NUM_RTX_CODE] = { 66 /* "*" undefined. 67 can cause a warning message 68 "0" field is unused (or used in a phase-dependent manner) 69 prints nothing 70 "i" an integer 71 prints the integer 72 "n" like "i", but prints entries from `note_insn_name' 73 "w" an integer of width HOST_BITS_PER_WIDE_INT 74 prints the integer 75 "s" a pointer to a string 76 prints the string 77 "S" like "s", but optional: 78 the containing rtx may end before this operand 79 "T" like "s", but treated specially by the RTL reader; 80 only found in machine description patterns. 81 "e" a pointer to an rtl expression 82 prints the expression 83 "E" a pointer to a vector that points to a number of rtl expressions 84 prints a list of the rtl expressions 85 "V" like "E", but optional: 86 the containing rtx may end before this operand 87 "u" a pointer to another insn 88 prints the uid of the insn. 89 "b" is a pointer to a bitmap header. 90 "B" is a basic block pointer. 91 "t" is a tree pointer. 92 "r" a register. 93 "p" is a poly_uint16 offset. */ 94 95 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT , 96 #include "rtl.def" /* rtl expressions are defined here */ 97 #undef DEF_RTL_EXPR 98 }; 99 100 /* Indexed by rtx code, gives a character representing the "class" of 101 that rtx code. See rtl.def for documentation on the defined classes. */ 102 103 const enum rtx_class rtx_class[NUM_RTX_CODE] = { 104 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) CLASS, 105 #include "rtl.def" /* rtl expressions are defined here */ 106 #undef DEF_RTL_EXPR 107 }; 108 109 /* Whether rtxs with the given code store data in the hwint field. */ 110 111 #define RTX_CODE_HWINT_P_1(ENUM) \ 112 ((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE \ 113 || (ENUM) == CONST_FIXED || (ENUM) == CONST_WIDE_INT) 114 #ifdef GENERATOR_FILE 115 #define RTX_CODE_HWINT_P(ENUM) \ 116 (RTX_CODE_HWINT_P_1 (ENUM) || (ENUM) == EQ_ATTR_ALT) 117 #else 118 #define RTX_CODE_HWINT_P RTX_CODE_HWINT_P_1 119 #endif 120 121 /* Indexed by rtx code, gives the size of the rtx in bytes. */ 122 123 const unsigned char rtx_code_size[NUM_RTX_CODE] = { 124 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) \ 125 (RTX_CODE_HWINT_P (ENUM) \ 126 ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT) \ 127 : (ENUM) == REG \ 128 ? RTX_HDR_SIZE + sizeof (reg_info) \ 129 : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)), 130 131 #include "rtl.def" 132 #undef DEF_RTL_EXPR 133 }; 134 135 /* Names for kinds of NOTEs and REG_NOTEs. */ 136 137 const char * const note_insn_name[NOTE_INSN_MAX] = 138 { 139 #define DEF_INSN_NOTE(NAME) #NAME, 140 #include "insn-notes.def" 141 #undef DEF_INSN_NOTE 142 }; 143 144 const char * const reg_note_name[REG_NOTE_MAX] = 145 { 146 #define DEF_REG_NOTE(NAME) #NAME, 147 #include "reg-notes.def" 148 #undef DEF_REG_NOTE 149 }; 150 151 static size_t rtx_alloc_counts[(int) LAST_AND_UNUSED_RTX_CODE]; 152 static size_t rtx_alloc_sizes[(int) LAST_AND_UNUSED_RTX_CODE]; 153 static size_t rtvec_alloc_counts; 154 static size_t rtvec_alloc_sizes; 155 156 157 /* Allocate an rtx vector of N elements. 158 Store the length, and initialize all elements to zero. */ 159 160 rtvec 161 rtvec_alloc (int n) 162 { 163 rtvec rt; 164 165 rt = ggc_alloc_rtvec_sized (n); 166 /* Clear out the vector. */ 167 memset (&rt->elem[0], 0, n * sizeof (rtx)); 168 169 PUT_NUM_ELEM (rt, n); 170 171 if (GATHER_STATISTICS) 172 { 173 rtvec_alloc_counts++; 174 rtvec_alloc_sizes += n * sizeof (rtx); 175 } 176 177 return rt; 178 } 179 180 /* Create a bitwise copy of VEC. */ 181 182 rtvec 183 shallow_copy_rtvec (rtvec vec) 184 { 185 rtvec newvec; 186 int n; 187 188 n = GET_NUM_ELEM (vec); 189 newvec = rtvec_alloc (n); 190 memcpy (&newvec->elem[0], &vec->elem[0], sizeof (rtx) * n); 191 return newvec; 192 } 193 194 /* Return the number of bytes occupied by rtx value X. */ 195 196 unsigned int 197 rtx_size (const_rtx x) 198 { 199 if (CONST_WIDE_INT_P (x)) 200 return (RTX_HDR_SIZE 201 + sizeof (struct hwivec_def) 202 + ((CONST_WIDE_INT_NUNITS (x) - 1) 203 * sizeof (HOST_WIDE_INT))); 204 if (CONST_POLY_INT_P (x)) 205 return (RTX_HDR_SIZE 206 + sizeof (struct const_poly_int_def) 207 + CONST_POLY_INT_COEFFS (x).extra_size ()); 208 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_HAS_BLOCK_INFO_P (x)) 209 return RTX_HDR_SIZE + sizeof (struct block_symbol); 210 return RTX_CODE_SIZE (GET_CODE (x)); 211 } 212 213 /* Allocate an rtx of code CODE with EXTRA bytes in it. The CODE is 214 stored in the rtx; all the rest is initialized to zero. */ 215 216 rtx 217 rtx_alloc_stat_v (RTX_CODE code MEM_STAT_DECL, int extra) 218 { 219 rtx rt = ggc_alloc_rtx_def_stat (RTX_CODE_SIZE (code) + extra 220 PASS_MEM_STAT); 221 222 rtx_init (rt, code); 223 224 if (GATHER_STATISTICS) 225 { 226 rtx_alloc_counts[code]++; 227 rtx_alloc_sizes[code] += RTX_CODE_SIZE (code); 228 } 229 230 return rt; 231 } 232 233 /* Allocate an rtx of code CODE. The CODE is stored in the rtx; 234 all the rest is initialized to zero. */ 235 236 rtx 237 rtx_alloc (RTX_CODE code MEM_STAT_DECL) 238 { 239 return rtx_alloc_stat_v (code PASS_MEM_STAT, 0); 240 } 241 242 /* Write the wide constant X to OUTFILE. */ 243 244 void 245 cwi_output_hex (FILE *outfile, const_rtx x) 246 { 247 int i = CWI_GET_NUM_ELEM (x); 248 gcc_assert (i > 0); 249 if (CWI_ELT (x, i - 1) == 0) 250 /* The HOST_WIDE_INT_PRINT_HEX prepends a 0x only if the val is 251 non zero. We want all numbers to have a 0x prefix. */ 252 fprintf (outfile, "0x"); 253 fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, CWI_ELT (x, --i)); 254 while (--i >= 0) 255 fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX, CWI_ELT (x, i)); 256 } 257 258 259 /* Return true if ORIG is a sharable CONST. */ 260 261 bool 262 shared_const_p (const_rtx orig) 263 { 264 gcc_assert (GET_CODE (orig) == CONST); 265 266 /* CONST can be shared if it contains a SYMBOL_REF. If it contains 267 a LABEL_REF, it isn't sharable. */ 268 poly_int64 offset; 269 return (GET_CODE (XEXP (orig, 0)) == PLUS 270 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF 271 && poly_int_rtx_p (XEXP (XEXP (orig, 0), 1), &offset)); 272 } 273 274 275 /* Create a new copy of an rtx. 276 Recursively copies the operands of the rtx, 277 except for those few rtx codes that are sharable. */ 278 279 rtx 280 copy_rtx (rtx orig) 281 { 282 rtx copy; 283 int i, j; 284 RTX_CODE code; 285 const char *format_ptr; 286 287 code = GET_CODE (orig); 288 289 switch (code) 290 { 291 case REG: 292 case DEBUG_EXPR: 293 case VALUE: 294 CASE_CONST_ANY: 295 case SYMBOL_REF: 296 case CODE_LABEL: 297 case PC: 298 case CC0: 299 case RETURN: 300 case SIMPLE_RETURN: 301 case SCRATCH: 302 /* SCRATCH must be shared because they represent distinct values. */ 303 return orig; 304 case CLOBBER: 305 /* Share clobbers of hard registers (like cc0), but do not share pseudo reg 306 clobbers or clobbers of hard registers that originated as pseudos. 307 This is needed to allow safe register renaming. */ 308 if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER 309 && ORIGINAL_REGNO (XEXP (orig, 0)) == REGNO (XEXP (orig, 0))) 310 return orig; 311 break; 312 313 case CONST: 314 if (shared_const_p (orig)) 315 return orig; 316 break; 317 318 /* A MEM with a constant address is not sharable. The problem is that 319 the constant address may need to be reloaded. If the mem is shared, 320 then reloading one copy of this mem will cause all copies to appear 321 to have been reloaded. */ 322 323 default: 324 break; 325 } 326 327 /* Copy the various flags, fields, and other information. We assume 328 that all fields need copying, and then clear the fields that should 329 not be copied. That is the sensible default behavior, and forces 330 us to explicitly document why we are *not* copying a flag. */ 331 copy = shallow_copy_rtx (orig); 332 333 format_ptr = GET_RTX_FORMAT (GET_CODE (copy)); 334 335 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++) 336 switch (*format_ptr++) 337 { 338 case 'e': 339 if (XEXP (orig, i) != NULL) 340 XEXP (copy, i) = copy_rtx (XEXP (orig, i)); 341 break; 342 343 case 'E': 344 case 'V': 345 if (XVEC (orig, i) != NULL) 346 { 347 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i)); 348 for (j = 0; j < XVECLEN (copy, i); j++) 349 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j)); 350 } 351 break; 352 353 case 't': 354 case 'w': 355 case 'i': 356 case 'p': 357 case 's': 358 case 'S': 359 case 'T': 360 case 'u': 361 case 'B': 362 case '0': 363 /* These are left unchanged. */ 364 break; 365 366 default: 367 gcc_unreachable (); 368 } 369 return copy; 370 } 371 372 /* Create a new copy of an rtx. Only copy just one level. */ 373 374 rtx 375 shallow_copy_rtx (const_rtx orig MEM_STAT_DECL) 376 { 377 const unsigned int size = rtx_size (orig); 378 rtx const copy = ggc_alloc_rtx_def_stat (size PASS_MEM_STAT); 379 memcpy (copy, orig, size); 380 switch (GET_CODE (orig)) 381 { 382 /* RTX codes copy_rtx_if_shared_1 considers are shareable, 383 the used flag is often used for other purposes. */ 384 case REG: 385 case DEBUG_EXPR: 386 case VALUE: 387 CASE_CONST_ANY: 388 case SYMBOL_REF: 389 case CODE_LABEL: 390 case PC: 391 case CC0: 392 case RETURN: 393 case SIMPLE_RETURN: 394 case SCRATCH: 395 break; 396 default: 397 /* For all other RTXes clear the used flag on the copy. */ 398 RTX_FLAG (copy, used) = 0; 399 break; 400 } 401 return copy; 402 } 403 404 /* Nonzero when we are generating CONCATs. */ 405 int generating_concat_p; 406 407 /* Nonzero when we are expanding trees to RTL. */ 408 int currently_expanding_to_rtl; 409 410 411 412 /* Same as rtx_equal_p, but call CB on each pair of rtx if CB is not NULL. 413 When the callback returns true, we continue with the new pair. 414 Whenever changing this function check if rtx_equal_p below doesn't need 415 changing as well. */ 416 417 int 418 rtx_equal_p_cb (const_rtx x, const_rtx y, rtx_equal_p_callback_function cb) 419 { 420 int i; 421 int j; 422 enum rtx_code code; 423 const char *fmt; 424 rtx nx, ny; 425 426 if (x == y) 427 return 1; 428 if (x == 0 || y == 0) 429 return 0; 430 431 /* Invoke the callback first. */ 432 if (cb != NULL 433 && ((*cb) (&x, &y, &nx, &ny))) 434 return rtx_equal_p_cb (nx, ny, cb); 435 436 code = GET_CODE (x); 437 /* Rtx's of different codes cannot be equal. */ 438 if (code != GET_CODE (y)) 439 return 0; 440 441 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. 442 (REG:SI x) and (REG:HI x) are NOT equivalent. */ 443 444 if (GET_MODE (x) != GET_MODE (y)) 445 return 0; 446 447 /* MEMs referring to different address space are not equivalent. */ 448 if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y)) 449 return 0; 450 451 /* Some RTL can be compared nonrecursively. */ 452 switch (code) 453 { 454 case REG: 455 return (REGNO (x) == REGNO (y)); 456 457 case LABEL_REF: 458 return label_ref_label (x) == label_ref_label (y); 459 460 case SYMBOL_REF: 461 return XSTR (x, 0) == XSTR (y, 0); 462 463 case DEBUG_EXPR: 464 case VALUE: 465 case SCRATCH: 466 CASE_CONST_UNIQUE: 467 return 0; 468 469 case CONST_VECTOR: 470 if (!same_vector_encodings_p (x, y)) 471 return false; 472 break; 473 474 case DEBUG_IMPLICIT_PTR: 475 return DEBUG_IMPLICIT_PTR_DECL (x) 476 == DEBUG_IMPLICIT_PTR_DECL (y); 477 478 case DEBUG_PARAMETER_REF: 479 return DEBUG_PARAMETER_REF_DECL (x) 480 == DEBUG_PARAMETER_REF_DECL (y); 481 482 case ENTRY_VALUE: 483 return rtx_equal_p_cb (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y), cb); 484 485 default: 486 break; 487 } 488 489 /* Compare the elements. If any pair of corresponding elements 490 fail to match, return 0 for the whole thing. */ 491 492 fmt = GET_RTX_FORMAT (code); 493 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 494 { 495 switch (fmt[i]) 496 { 497 case 'w': 498 if (XWINT (x, i) != XWINT (y, i)) 499 return 0; 500 break; 501 502 case 'n': 503 case 'i': 504 if (XINT (x, i) != XINT (y, i)) 505 { 506 #ifndef GENERATOR_FILE 507 if (((code == ASM_OPERANDS && i == 6) 508 || (code == ASM_INPUT && i == 1)) 509 && XINT (x, i) == XINT (y, i)) 510 break; 511 #endif 512 return 0; 513 } 514 break; 515 516 case 'p': 517 if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y))) 518 return 0; 519 break; 520 521 case 'V': 522 case 'E': 523 /* Two vectors must have the same length. */ 524 if (XVECLEN (x, i) != XVECLEN (y, i)) 525 return 0; 526 527 /* And the corresponding elements must match. */ 528 for (j = 0; j < XVECLEN (x, i); j++) 529 if (rtx_equal_p_cb (XVECEXP (x, i, j), 530 XVECEXP (y, i, j), cb) == 0) 531 return 0; 532 break; 533 534 case 'e': 535 if (rtx_equal_p_cb (XEXP (x, i), XEXP (y, i), cb) == 0) 536 return 0; 537 break; 538 539 case 'S': 540 case 's': 541 if ((XSTR (x, i) || XSTR (y, i)) 542 && (! XSTR (x, i) || ! XSTR (y, i) 543 || strcmp (XSTR (x, i), XSTR (y, i)))) 544 return 0; 545 break; 546 547 case 'u': 548 /* These are just backpointers, so they don't matter. */ 549 break; 550 551 case '0': 552 case 't': 553 break; 554 555 /* It is believed that rtx's at this level will never 556 contain anything but integers and other rtx's, 557 except for within LABEL_REFs and SYMBOL_REFs. */ 558 default: 559 gcc_unreachable (); 560 } 561 } 562 return 1; 563 } 564 565 /* Return 1 if X and Y are identical-looking rtx's. 566 This is the Lisp function EQUAL for rtx arguments. 567 Whenever changing this function check if rtx_equal_p_cb above doesn't need 568 changing as well. */ 569 570 int 571 rtx_equal_p (const_rtx x, const_rtx y) 572 { 573 int i; 574 int j; 575 enum rtx_code code; 576 const char *fmt; 577 578 if (x == y) 579 return 1; 580 if (x == 0 || y == 0) 581 return 0; 582 583 code = GET_CODE (x); 584 /* Rtx's of different codes cannot be equal. */ 585 if (code != GET_CODE (y)) 586 return 0; 587 588 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. 589 (REG:SI x) and (REG:HI x) are NOT equivalent. */ 590 591 if (GET_MODE (x) != GET_MODE (y)) 592 return 0; 593 594 /* MEMs referring to different address space are not equivalent. */ 595 if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y)) 596 return 0; 597 598 /* Some RTL can be compared nonrecursively. */ 599 switch (code) 600 { 601 case REG: 602 return (REGNO (x) == REGNO (y)); 603 604 case LABEL_REF: 605 return label_ref_label (x) == label_ref_label (y); 606 607 case SYMBOL_REF: 608 return XSTR (x, 0) == XSTR (y, 0); 609 610 case DEBUG_EXPR: 611 case VALUE: 612 case SCRATCH: 613 CASE_CONST_UNIQUE: 614 return 0; 615 616 case CONST_VECTOR: 617 if (!same_vector_encodings_p (x, y)) 618 return false; 619 break; 620 621 case DEBUG_IMPLICIT_PTR: 622 return DEBUG_IMPLICIT_PTR_DECL (x) 623 == DEBUG_IMPLICIT_PTR_DECL (y); 624 625 case DEBUG_PARAMETER_REF: 626 return DEBUG_PARAMETER_REF_DECL (x) 627 == DEBUG_PARAMETER_REF_DECL (y); 628 629 case ENTRY_VALUE: 630 return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y)); 631 632 default: 633 break; 634 } 635 636 /* Compare the elements. If any pair of corresponding elements 637 fail to match, return 0 for the whole thing. */ 638 639 fmt = GET_RTX_FORMAT (code); 640 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 641 { 642 switch (fmt[i]) 643 { 644 case 'w': 645 if (XWINT (x, i) != XWINT (y, i)) 646 return 0; 647 break; 648 649 case 'n': 650 case 'i': 651 if (XINT (x, i) != XINT (y, i)) 652 { 653 #ifndef GENERATOR_FILE 654 if (((code == ASM_OPERANDS && i == 6) 655 || (code == ASM_INPUT && i == 1)) 656 && XINT (x, i) == XINT (y, i)) 657 break; 658 #endif 659 return 0; 660 } 661 break; 662 663 case 'p': 664 if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y))) 665 return 0; 666 break; 667 668 case 'V': 669 case 'E': 670 /* Two vectors must have the same length. */ 671 if (XVECLEN (x, i) != XVECLEN (y, i)) 672 return 0; 673 674 /* And the corresponding elements must match. */ 675 for (j = 0; j < XVECLEN (x, i); j++) 676 if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0) 677 return 0; 678 break; 679 680 case 'e': 681 if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0) 682 return 0; 683 break; 684 685 case 'S': 686 case 's': 687 if ((XSTR (x, i) || XSTR (y, i)) 688 && (! XSTR (x, i) || ! XSTR (y, i) 689 || strcmp (XSTR (x, i), XSTR (y, i)))) 690 return 0; 691 break; 692 693 case 'u': 694 /* These are just backpointers, so they don't matter. */ 695 break; 696 697 case '0': 698 case 't': 699 break; 700 701 /* It is believed that rtx's at this level will never 702 contain anything but integers and other rtx's, 703 except for within LABEL_REFs and SYMBOL_REFs. */ 704 default: 705 gcc_unreachable (); 706 } 707 } 708 return 1; 709 } 710 711 /* Return true if all elements of VEC are equal. */ 712 713 bool 714 rtvec_all_equal_p (const_rtvec vec) 715 { 716 const_rtx first = RTVEC_ELT (vec, 0); 717 /* Optimize the important special case of a vector of constants. 718 The main use of this function is to detect whether every element 719 of CONST_VECTOR is the same. */ 720 switch (GET_CODE (first)) 721 { 722 CASE_CONST_UNIQUE: 723 for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i) 724 if (first != RTVEC_ELT (vec, i)) 725 return false; 726 return true; 727 728 default: 729 for (int i = 1, n = GET_NUM_ELEM (vec); i < n; ++i) 730 if (!rtx_equal_p (first, RTVEC_ELT (vec, i))) 731 return false; 732 return true; 733 } 734 } 735 736 /* Return an indication of which type of insn should have X as a body. 737 In generator files, this can be UNKNOWN if the answer is only known 738 at (GCC) runtime. Otherwise the value is CODE_LABEL, INSN, CALL_INSN 739 or JUMP_INSN. */ 740 741 enum rtx_code 742 classify_insn (rtx x) 743 { 744 if (LABEL_P (x)) 745 return CODE_LABEL; 746 if (GET_CODE (x) == CALL) 747 return CALL_INSN; 748 if (ANY_RETURN_P (x)) 749 return JUMP_INSN; 750 if (GET_CODE (x) == ASM_OPERANDS && ASM_OPERANDS_LABEL_LENGTH (x)) 751 return JUMP_INSN; 752 if (GET_CODE (x) == SET) 753 { 754 if (GET_CODE (SET_DEST (x)) == PC) 755 return JUMP_INSN; 756 else if (GET_CODE (SET_SRC (x)) == CALL) 757 return CALL_INSN; 758 else 759 return INSN; 760 } 761 if (GET_CODE (x) == PARALLEL) 762 { 763 int j; 764 bool has_return_p = false; 765 for (j = XVECLEN (x, 0) - 1; j >= 0; j--) 766 if (GET_CODE (XVECEXP (x, 0, j)) == CALL) 767 return CALL_INSN; 768 else if (ANY_RETURN_P (XVECEXP (x, 0, j))) 769 has_return_p = true; 770 else if (GET_CODE (XVECEXP (x, 0, j)) == SET 771 && GET_CODE (SET_DEST (XVECEXP (x, 0, j))) == PC) 772 return JUMP_INSN; 773 else if (GET_CODE (XVECEXP (x, 0, j)) == SET 774 && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL) 775 return CALL_INSN; 776 if (has_return_p) 777 return JUMP_INSN; 778 if (GET_CODE (XVECEXP (x, 0, 0)) == ASM_OPERANDS 779 && ASM_OPERANDS_LABEL_LENGTH (XVECEXP (x, 0, 0))) 780 return JUMP_INSN; 781 } 782 #ifdef GENERATOR_FILE 783 if (GET_CODE (x) == MATCH_OPERAND 784 || GET_CODE (x) == MATCH_OPERATOR 785 || GET_CODE (x) == MATCH_PARALLEL 786 || GET_CODE (x) == MATCH_OP_DUP 787 || GET_CODE (x) == MATCH_DUP 788 || GET_CODE (x) == PARALLEL) 789 return UNKNOWN; 790 #endif 791 return INSN; 792 } 793 794 /* Comparator of indices based on rtx_alloc_counts. */ 795 796 static int 797 rtx_count_cmp (const void *p1, const void *p2) 798 { 799 const unsigned *n1 = (const unsigned *)p1; 800 const unsigned *n2 = (const unsigned *)p2; 801 802 return rtx_alloc_counts[*n1] - rtx_alloc_counts[*n2]; 803 } 804 805 void 806 dump_rtx_statistics (void) 807 { 808 int total_counts = 0; 809 int total_sizes = 0; 810 811 if (! GATHER_STATISTICS) 812 { 813 fprintf (stderr, "No RTX statistics\n"); 814 return; 815 } 816 817 fprintf (stderr, "\nRTX Kind Count Bytes\n"); 818 fprintf (stderr, "-------------------------------------------\n"); 819 820 auto_vec<unsigned> indices (LAST_AND_UNUSED_RTX_CODE); 821 for (unsigned i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++) 822 indices.quick_push (i); 823 indices.qsort (rtx_count_cmp); 824 825 for (unsigned i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++) 826 { 827 unsigned j = indices[i]; 828 if (rtx_alloc_counts[j]) 829 { 830 fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n", 831 GET_RTX_NAME (j), 832 SIZE_AMOUNT (rtx_alloc_counts[j]), 833 SIZE_AMOUNT (rtx_alloc_sizes[j])); 834 total_counts += rtx_alloc_counts[j]; 835 total_sizes += rtx_alloc_sizes[j]; 836 } 837 } 838 839 if (rtvec_alloc_counts) 840 { 841 fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n", "rtvec", 842 SIZE_AMOUNT (rtvec_alloc_counts), 843 SIZE_AMOUNT (rtvec_alloc_sizes)); 844 total_counts += rtvec_alloc_counts; 845 total_sizes += rtvec_alloc_sizes; 846 } 847 fprintf (stderr, "-----------------------------------------------\n"); 848 fprintf (stderr, "%-24s " PRsa (6) " " PRsa (9) "\n", 849 "Total", SIZE_AMOUNT (total_counts), 850 SIZE_AMOUNT (total_sizes)); 851 fprintf (stderr, "-----------------------------------------------\n"); 852 } 853 854 #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007) 855 void 856 rtl_check_failed_bounds (const_rtx r, int n, const char *file, int line, 857 const char *func) 858 { 859 internal_error 860 ("RTL check: access of elt %d of '%s' with last elt %d in %s, at %s:%d", 861 n, GET_RTX_NAME (GET_CODE (r)), GET_RTX_LENGTH (GET_CODE (r)) - 1, 862 func, trim_filename (file), line); 863 } 864 865 void 866 rtl_check_failed_type1 (const_rtx r, int n, int c1, const char *file, int line, 867 const char *func) 868 { 869 internal_error 870 ("RTL check: expected elt %d type '%c', have '%c' (rtx %s) in %s, at %s:%d", 871 n, c1, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)), 872 func, trim_filename (file), line); 873 } 874 875 void 876 rtl_check_failed_type2 (const_rtx r, int n, int c1, int c2, const char *file, 877 int line, const char *func) 878 { 879 internal_error 880 ("RTL check: expected elt %d type '%c' or '%c', have '%c' (rtx %s) in %s, at %s:%d", 881 n, c1, c2, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)), 882 func, trim_filename (file), line); 883 } 884 885 void 886 rtl_check_failed_code1 (const_rtx r, enum rtx_code code, const char *file, 887 int line, const char *func) 888 { 889 internal_error ("RTL check: expected code '%s', have '%s' in %s, at %s:%d", 890 GET_RTX_NAME (code), GET_RTX_NAME (GET_CODE (r)), func, 891 trim_filename (file), line); 892 } 893 894 void 895 rtl_check_failed_code2 (const_rtx r, enum rtx_code code1, enum rtx_code code2, 896 const char *file, int line, const char *func) 897 { 898 internal_error 899 ("RTL check: expected code '%s' or '%s', have '%s' in %s, at %s:%d", 900 GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (GET_CODE (r)), 901 func, trim_filename (file), line); 902 } 903 904 void 905 rtl_check_failed_code3 (const_rtx r, enum rtx_code code1, enum rtx_code code2, 906 enum rtx_code code3, const char *file, int line, 907 const char *func) 908 { 909 internal_error 910 ("RTL check: expected code '%s', '%s' or '%s', have '%s' in %s, at %s:%d", 911 GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (code3), 912 GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line); 913 } 914 915 void 916 rtl_check_failed_code_mode (const_rtx r, enum rtx_code code, machine_mode mode, 917 bool not_mode, const char *file, int line, 918 const char *func) 919 { 920 internal_error ((not_mode 921 ? ("RTL check: expected code '%s' and not mode '%s', " 922 "have code '%s' and mode '%s' in %s, at %s:%d") 923 : ("RTL check: expected code '%s' and mode '%s', " 924 "have code '%s' and mode '%s' in %s, at %s:%d")), 925 GET_RTX_NAME (code), GET_MODE_NAME (mode), 926 GET_RTX_NAME (GET_CODE (r)), GET_MODE_NAME (GET_MODE (r)), 927 func, trim_filename (file), line); 928 } 929 930 /* Report that line LINE of FILE tried to access the block symbol fields 931 of a non-block symbol. FUNC is the function that contains the line. */ 932 933 void 934 rtl_check_failed_block_symbol (const char *file, int line, const char *func) 935 { 936 internal_error 937 ("RTL check: attempt to treat non-block symbol as a block symbol " 938 "in %s, at %s:%d", func, trim_filename (file), line); 939 } 940 941 /* XXX Maybe print the vector? */ 942 void 943 cwi_check_failed_bounds (const_rtx x, int n, const char *file, int line, 944 const char *func) 945 { 946 internal_error 947 ("RTL check: access of hwi elt %d of vector with last elt %d in %s, at %s:%d", 948 n, CWI_GET_NUM_ELEM (x) - 1, func, trim_filename (file), line); 949 } 950 951 /* XXX Maybe print the vector? */ 952 void 953 rtvec_check_failed_bounds (const_rtvec r, int n, const char *file, int line, 954 const char *func) 955 { 956 internal_error 957 ("RTL check: access of elt %d of vector with last elt %d in %s, at %s:%d", 958 n, GET_NUM_ELEM (r) - 1, func, trim_filename (file), line); 959 } 960 #endif /* ENABLE_RTL_CHECKING */ 961 962 #if defined ENABLE_RTL_FLAG_CHECKING 963 void 964 rtl_check_failed_flag (const char *name, const_rtx r, const char *file, 965 int line, const char *func) 966 { 967 internal_error 968 ("RTL flag check: %s used with unexpected rtx code '%s' in %s, at %s:%d", 969 name, GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line); 970 } 971 #endif /* ENABLE_RTL_FLAG_CHECKING */ 972