|
|
1.1 root 1: /* Analyze RTL for C-Compiler 1.1.1.4 ! root 2: Copyright (C) 1987, 1988, 1991, 1992, 1993 Free Software Foundation, Inc. 1.1 root 3: 4: This file is part of GNU CC. 5: 6: GNU CC is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU CC is distributed in the hope that it will be useful, 12: but WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14: GNU General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU CC; see the file COPYING. If not, write to 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 19: 20: 21: #include "config.h" 22: #include "rtl.h" 23: 24: void note_stores (); 25: int reg_set_p (); 26: 27: /* Bit flags that specify the machine subtype we are compiling for. 28: Bits are tested using macros TARGET_... defined in the tm.h file 29: and set by `-m...' switches. Must be defined in rtlanal.c. */ 30: 31: int target_flags; 32: 33: /* Return 1 if the value of X is unstable 34: (would be different at a different point in the program). 35: The frame pointer, arg pointer, etc. are considered stable 36: (within one function) and so is anything marked `unchanging'. */ 37: 38: int 39: rtx_unstable_p (x) 40: rtx x; 41: { 42: register RTX_CODE code = GET_CODE (x); 43: register int i; 44: register char *fmt; 45: 46: if (code == MEM) 47: return ! RTX_UNCHANGING_P (x); 48: 49: if (code == QUEUED) 50: return 1; 51: 52: if (code == CONST || code == CONST_INT) 53: return 0; 54: 55: if (code == REG) 56: return ! (REGNO (x) == FRAME_POINTER_REGNUM 1.1.1.4 ! root 57: || REGNO (x) == HARD_FRAME_POINTER_REGNUM 1.1 root 58: || REGNO (x) == ARG_POINTER_REGNUM 59: || RTX_UNCHANGING_P (x)); 60: 61: fmt = GET_RTX_FORMAT (code); 62: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 63: if (fmt[i] == 'e') 64: if (rtx_unstable_p (XEXP (x, i))) 65: return 1; 66: return 0; 67: } 68: 69: /* Return 1 if X has a value that can vary even between two 70: executions of the program. 0 means X can be compared reliably 71: against certain constants or near-constants. 72: The frame pointer and the arg pointer are considered constant. */ 73: 74: int 75: rtx_varies_p (x) 76: rtx x; 77: { 78: register RTX_CODE code = GET_CODE (x); 79: register int i; 80: register char *fmt; 81: 82: switch (code) 83: { 84: case MEM: 85: case QUEUED: 86: return 1; 87: 88: case CONST: 89: case CONST_INT: 90: case CONST_DOUBLE: 91: case SYMBOL_REF: 92: case LABEL_REF: 93: return 0; 94: 95: case REG: 96: /* Note that we have to test for the actual rtx used for the frame 97: and arg pointers and not just the register number in case we have 98: eliminated the frame and/or arg pointer and are using it 99: for pseudos. */ 1.1.1.4 ! root 100: return ! (x == frame_pointer_rtx || x == hard_frame_pointer_rtx ! 101: || x == arg_pointer_rtx); 1.1 root 102: 103: case LO_SUM: 104: /* The operand 0 of a LO_SUM is considered constant 105: (in fact is it related specifically to operand 1). */ 106: return rtx_varies_p (XEXP (x, 1)); 107: } 108: 109: fmt = GET_RTX_FORMAT (code); 110: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 111: if (fmt[i] == 'e') 112: if (rtx_varies_p (XEXP (x, i))) 113: return 1; 114: return 0; 115: } 116: 117: /* Return 0 if the use of X as an address in a MEM can cause a trap. */ 118: 119: int 120: rtx_addr_can_trap_p (x) 121: register rtx x; 122: { 123: register enum rtx_code code = GET_CODE (x); 124: 125: switch (code) 126: { 127: case SYMBOL_REF: 128: case LABEL_REF: 129: /* SYMBOL_REF is problematic due to the possible presence of 130: a #pragma weak, but to say that loads from symbols can trap is 131: *very* costly. It's not at all clear what's best here. For 132: now, we ignore the impact of #pragma weak. */ 133: return 0; 134: 135: case REG: 136: /* As in rtx_varies_p, we have to use the actual rtx, not reg number. */ 1.1.1.4 ! root 137: return ! (x == frame_pointer_rtx || x == hard_frame_pointer_rtx ! 138: || x == stack_pointer_rtx || x == arg_pointer_rtx); 1.1 root 139: 140: case CONST: 141: return rtx_addr_can_trap_p (XEXP (x, 0)); 142: 143: case PLUS: 144: /* An address is assumed not to trap if it is an address that can't 145: trap plus a constant integer. */ 146: return (rtx_addr_can_trap_p (XEXP (x, 0)) 147: || GET_CODE (XEXP (x, 1)) != CONST_INT); 148: 149: case LO_SUM: 150: return rtx_addr_can_trap_p (XEXP (x, 1)); 151: } 152: 153: /* If it isn't one of the case above, it can cause a trap. */ 154: return 1; 155: } 156: 157: /* Return 1 if X refers to a memory location whose address 158: cannot be compared reliably with constant addresses, 159: or if X refers to a BLKmode memory object. */ 160: 161: int 162: rtx_addr_varies_p (x) 163: rtx x; 164: { 165: register enum rtx_code code; 166: register int i; 167: register char *fmt; 168: 169: if (x == 0) 170: return 0; 171: 172: code = GET_CODE (x); 173: if (code == MEM) 174: return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0)); 175: 176: fmt = GET_RTX_FORMAT (code); 177: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 178: if (fmt[i] == 'e') 179: if (rtx_addr_varies_p (XEXP (x, i))) 180: return 1; 181: return 0; 182: } 183: 184: /* Return the value of the integer term in X, if one is apparent; 185: otherwise return 0. 186: Only obvious integer terms are detected. 187: This is used in cse.c with the `related_value' field.*/ 188: 1.1.1.2 root 189: HOST_WIDE_INT 1.1 root 190: get_integer_term (x) 191: rtx x; 192: { 193: if (GET_CODE (x) == CONST) 194: x = XEXP (x, 0); 195: 196: if (GET_CODE (x) == MINUS 197: && GET_CODE (XEXP (x, 1)) == CONST_INT) 198: return - INTVAL (XEXP (x, 1)); 199: if (GET_CODE (x) == PLUS 200: && GET_CODE (XEXP (x, 1)) == CONST_INT) 201: return INTVAL (XEXP (x, 1)); 202: return 0; 203: } 204: 205: /* If X is a constant, return the value sans apparent integer term; 206: otherwise return 0. 207: Only obvious integer terms are detected. */ 208: 209: rtx 210: get_related_value (x) 211: rtx x; 212: { 213: if (GET_CODE (x) != CONST) 214: return 0; 215: x = XEXP (x, 0); 216: if (GET_CODE (x) == PLUS 217: && GET_CODE (XEXP (x, 1)) == CONST_INT) 218: return XEXP (x, 0); 219: else if (GET_CODE (x) == MINUS 220: && GET_CODE (XEXP (x, 1)) == CONST_INT) 221: return XEXP (x, 0); 222: return 0; 223: } 224: 225: /* Nonzero if register REG appears somewhere within IN. 226: Also works if REG is not a register; in this case it checks 227: for a subexpression of IN that is Lisp "equal" to REG. */ 228: 229: int 230: reg_mentioned_p (reg, in) 231: register rtx reg, in; 232: { 233: register char *fmt; 234: register int i; 235: register enum rtx_code code; 236: 237: if (in == 0) 238: return 0; 239: 240: if (reg == in) 241: return 1; 242: 243: if (GET_CODE (in) == LABEL_REF) 244: return reg == XEXP (in, 0); 245: 246: code = GET_CODE (in); 247: 248: switch (code) 249: { 250: /* Compare registers by number. */ 251: case REG: 252: return GET_CODE (reg) == REG && REGNO (in) == REGNO (reg); 253: 254: /* These codes have no constituent expressions 255: and are unique. */ 256: case SCRATCH: 257: case CC0: 258: case PC: 259: return 0; 260: 261: case CONST_INT: 262: return GET_CODE (reg) == CONST_INT && INTVAL (in) == INTVAL (reg); 263: 264: case CONST_DOUBLE: 265: /* These are kept unique for a given value. */ 266: return 0; 267: } 268: 269: if (GET_CODE (reg) == code && rtx_equal_p (reg, in)) 270: return 1; 271: 272: fmt = GET_RTX_FORMAT (code); 273: 274: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 275: { 276: if (fmt[i] == 'E') 277: { 278: register int j; 279: for (j = XVECLEN (in, i) - 1; j >= 0; j--) 280: if (reg_mentioned_p (reg, XVECEXP (in, i, j))) 281: return 1; 282: } 283: else if (fmt[i] == 'e' 284: && reg_mentioned_p (reg, XEXP (in, i))) 285: return 1; 286: } 287: return 0; 288: } 289: 290: /* Return 1 if in between BEG and END, exclusive of BEG and END, there is 291: no CODE_LABEL insn. */ 292: 293: int 294: no_labels_between_p (beg, end) 295: rtx beg, end; 296: { 297: register rtx p; 298: for (p = NEXT_INSN (beg); p != end; p = NEXT_INSN (p)) 299: if (GET_CODE (p) == CODE_LABEL) 300: return 0; 301: return 1; 302: } 303: 304: /* Nonzero if register REG is used in an insn between 305: FROM_INSN and TO_INSN (exclusive of those two). */ 306: 307: int 308: reg_used_between_p (reg, from_insn, to_insn) 309: rtx reg, from_insn, to_insn; 310: { 311: register rtx insn; 312: 313: if (from_insn == to_insn) 314: return 0; 315: 316: for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn)) 317: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' 318: && reg_overlap_mentioned_p (reg, PATTERN (insn))) 319: return 1; 320: return 0; 321: } 322: 323: /* Nonzero if the old value of X, a register, is referenced in BODY. If X 324: is entirely replaced by a new value and the only use is as a SET_DEST, 325: we do not consider it a reference. */ 326: 327: int 328: reg_referenced_p (x, body) 329: rtx x; 330: rtx body; 331: { 332: int i; 333: 334: switch (GET_CODE (body)) 335: { 336: case SET: 337: if (reg_overlap_mentioned_p (x, SET_SRC (body))) 338: return 1; 339: 340: /* If the destination is anything other than CC0, PC, a REG or a SUBREG 341: of a REG that occupies all of the REG, the insn references X if 342: it is mentioned in the destination. */ 343: if (GET_CODE (SET_DEST (body)) != CC0 344: && GET_CODE (SET_DEST (body)) != PC 345: && GET_CODE (SET_DEST (body)) != REG 346: && ! (GET_CODE (SET_DEST (body)) == SUBREG 347: && GET_CODE (SUBREG_REG (SET_DEST (body))) == REG 348: && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (body)))) 349: + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) 350: == ((GET_MODE_SIZE (GET_MODE (SET_DEST (body))) 351: + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))) 352: && reg_overlap_mentioned_p (x, SET_DEST (body))) 353: return 1; 354: break; 355: 356: case ASM_OPERANDS: 357: for (i = ASM_OPERANDS_INPUT_LENGTH (body) - 1; i >= 0; i--) 358: if (reg_overlap_mentioned_p (x, ASM_OPERANDS_INPUT (body, i))) 359: return 1; 360: break; 361: 362: case CALL: 363: case USE: 364: return reg_overlap_mentioned_p (x, body); 365: 366: case TRAP_IF: 367: return reg_overlap_mentioned_p (x, TRAP_CONDITION (body)); 368: 369: case UNSPEC: 370: case UNSPEC_VOLATILE: 371: case PARALLEL: 372: for (i = XVECLEN (body, 0) - 1; i >= 0; i--) 373: if (reg_referenced_p (x, XVECEXP (body, 0, i))) 374: return 1; 375: break; 376: } 377: 378: return 0; 379: } 380: 381: /* Nonzero if register REG is referenced in an insn between 382: FROM_INSN and TO_INSN (exclusive of those two). Sets of REG do 383: not count. */ 384: 385: int 386: reg_referenced_between_p (reg, from_insn, to_insn) 387: rtx reg, from_insn, to_insn; 388: { 389: register rtx insn; 390: 391: if (from_insn == to_insn) 392: return 0; 393: 394: for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn)) 395: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' 396: && reg_referenced_p (reg, PATTERN (insn))) 397: return 1; 398: return 0; 399: } 400: 401: /* Nonzero if register REG is set or clobbered in an insn between 402: FROM_INSN and TO_INSN (exclusive of those two). */ 403: 404: int 405: reg_set_between_p (reg, from_insn, to_insn) 406: rtx reg, from_insn, to_insn; 407: { 408: register rtx insn; 409: 410: if (from_insn == to_insn) 411: return 0; 412: 413: for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn)) 414: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' 415: && reg_set_p (reg, insn)) 416: return 1; 417: return 0; 418: } 419: 420: /* Internals of reg_set_between_p. */ 421: 422: static rtx reg_set_reg; 423: static int reg_set_flag; 424: 425: void 426: reg_set_p_1 (x) 427: rtx x; 428: { 429: /* We don't want to return 1 if X is a MEM that contains a register 430: within REG_SET_REG. */ 431: 432: if ((GET_CODE (x) != MEM) 433: && reg_overlap_mentioned_p (reg_set_reg, x)) 434: reg_set_flag = 1; 435: } 436: 437: int 438: reg_set_p (reg, insn) 439: rtx reg, insn; 440: { 441: rtx body = insn; 442: 443: /* We can be passed an insn or part of one. If we are passed an insn, 444: check if a side-effect of the insn clobbers REG. */ 445: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') 446: { 447: if (FIND_REG_INC_NOTE (insn, reg) 448: || (GET_CODE (insn) == CALL_INSN 449: /* We'd like to test call_used_regs here, but rtlanal.c can't 450: reference that variable due to its use in genattrtab. So 451: we'll just be more conservative. */ 452: && ((GET_CODE (reg) == REG 453: && REGNO (reg) < FIRST_PSEUDO_REGISTER) 454: || GET_CODE (reg) == MEM))) 455: return 1; 456: 457: body = PATTERN (insn); 458: } 459: 460: reg_set_reg = reg; 461: reg_set_flag = 0; 462: note_stores (body, reg_set_p_1); 463: return reg_set_flag; 464: } 465: 466: /* Similar to reg_set_between_p, but check all registers in X. Return 0 467: only if none of them are modified between START and END. Return 1 if 468: X contains a MEM; this routine does not perform any memory aliasing. */ 469: 470: int 471: modified_between_p (x, start, end) 472: rtx x; 473: rtx start, end; 474: { 475: enum rtx_code code = GET_CODE (x); 476: char *fmt; 1.1.1.4 ! root 477: int i, j; 1.1 root 478: 479: switch (code) 480: { 481: case CONST_INT: 482: case CONST_DOUBLE: 483: case CONST: 484: case SYMBOL_REF: 485: case LABEL_REF: 486: return 0; 487: 488: case PC: 489: case CC0: 490: return 1; 491: 492: case MEM: 493: /* If the memory is not constant, assume it is modified. If it is 494: constant, we still have to check the address. */ 495: if (! RTX_UNCHANGING_P (x)) 496: return 1; 497: break; 498: 499: case REG: 500: return reg_set_between_p (x, start, end); 501: } 502: 503: fmt = GET_RTX_FORMAT (code); 504: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1.1.1.4 ! root 505: { ! 506: if (fmt[i] == 'e' && modified_between_p (XEXP (x, i), start, end)) ! 507: return 1; ! 508: ! 509: if (fmt[i] == 'E') ! 510: for (j = XVECLEN (x, i) - 1; j >= 0; j--) ! 511: if (modified_between_p (XVECEXP (x, i, j), start, end)) ! 512: return 1; ! 513: } ! 514: ! 515: return 0; ! 516: } ! 517: ! 518: /* Similar to reg_set_p, but check all registers in X. Return 0 only if none ! 519: of them are modified in INSN. Return 1 if X contains a MEM; this routine ! 520: does not perform any memory aliasing. */ ! 521: ! 522: int ! 523: modified_in_p (x, insn) ! 524: rtx x; ! 525: rtx insn; ! 526: { ! 527: enum rtx_code code = GET_CODE (x); ! 528: char *fmt; ! 529: int i, j; ! 530: ! 531: switch (code) ! 532: { ! 533: case CONST_INT: ! 534: case CONST_DOUBLE: ! 535: case CONST: ! 536: case SYMBOL_REF: ! 537: case LABEL_REF: ! 538: return 0; ! 539: ! 540: case PC: ! 541: case CC0: 1.1 root 542: return 1; 543: 1.1.1.4 ! root 544: case MEM: ! 545: /* If the memory is not constant, assume it is modified. If it is ! 546: constant, we still have to check the address. */ ! 547: if (! RTX_UNCHANGING_P (x)) ! 548: return 1; ! 549: break; ! 550: ! 551: case REG: ! 552: return reg_set_p (x, insn); ! 553: } ! 554: ! 555: fmt = GET_RTX_FORMAT (code); ! 556: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) ! 557: { ! 558: if (fmt[i] == 'e' && modified_in_p (XEXP (x, i), insn)) ! 559: return 1; ! 560: ! 561: if (fmt[i] == 'E') ! 562: for (j = XVECLEN (x, i) - 1; j >= 0; j--) ! 563: if (modified_in_p (XVECEXP (x, i, j), insn)) ! 564: return 1; ! 565: } ! 566: 1.1 root 567: return 0; 568: } 569: 570: /* Given an INSN, return a SET expression if this insn has only a single SET. 571: It may also have CLOBBERs, USEs, or SET whose output 572: will not be used, which we ignore. */ 573: 574: rtx 575: single_set (insn) 576: rtx insn; 577: { 578: rtx set; 579: int i; 580: 581: if (GET_RTX_CLASS (GET_CODE (insn)) != 'i') 582: return 0; 583: 584: if (GET_CODE (PATTERN (insn)) == SET) 585: return PATTERN (insn); 586: 587: else if (GET_CODE (PATTERN (insn)) == PARALLEL) 588: { 589: for (i = 0, set = 0; i < XVECLEN (PATTERN (insn), 0); i++) 590: if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET 1.1.1.2 root 591: && (! find_reg_note (insn, REG_UNUSED, 592: SET_DEST (XVECEXP (PATTERN (insn), 0, i))) 593: || side_effects_p (XVECEXP (PATTERN (insn), 0, i)))) 1.1 root 594: { 595: if (set) 596: return 0; 597: else 598: set = XVECEXP (PATTERN (insn), 0, i); 599: } 600: return set; 601: } 602: 603: return 0; 604: } 605: 606: /* Return the last thing that X was assigned from before *PINSN. Verify that 607: the object is not modified up to VALID_TO. If it was, if we hit 608: a partial assignment to X, or hit a CODE_LABEL first, return X. If we 609: found an assignment, update *PINSN to point to it. */ 610: 611: rtx 612: find_last_value (x, pinsn, valid_to) 613: rtx x; 614: rtx *pinsn; 615: rtx valid_to; 616: { 617: rtx p; 618: 619: for (p = PREV_INSN (*pinsn); p && GET_CODE (p) != CODE_LABEL; 620: p = PREV_INSN (p)) 621: if (GET_RTX_CLASS (GET_CODE (p)) == 'i') 622: { 623: rtx set = single_set (p); 1.1.1.2 root 624: rtx note = find_reg_note (p, REG_EQUAL, NULL_RTX); 1.1 root 625: 626: if (set && rtx_equal_p (x, SET_DEST (set))) 627: { 628: rtx src = SET_SRC (set); 629: 630: if (note && GET_CODE (XEXP (note, 0)) != EXPR_LIST) 631: src = XEXP (note, 0); 632: 633: if (! modified_between_p (src, PREV_INSN (p), valid_to) 634: /* Reject hard registers because we don't usually want 635: to use them; we'd rather use a pseudo. */ 636: && ! (GET_CODE (src) == REG 637: && REGNO (src) < FIRST_PSEUDO_REGISTER)) 638: { 639: *pinsn = p; 640: return src; 641: } 642: } 643: 644: /* If set in non-simple way, we don't have a value. */ 645: if (reg_set_p (x, p)) 646: break; 647: } 648: 649: return x; 650: } 651: 652: /* Return nonzero if register in range [REGNO, ENDREGNO) 653: appears either explicitly or implicitly in X 654: other than being stored into. 655: 656: References contained within the substructure at LOC do not count. 657: LOC may be zero, meaning don't ignore anything. */ 658: 659: int 660: refers_to_regno_p (regno, endregno, x, loc) 661: int regno, endregno; 662: rtx x; 663: rtx *loc; 664: { 665: register int i; 666: register RTX_CODE code; 667: register char *fmt; 668: 669: repeat: 670: /* The contents of a REG_NONNEG note is always zero, so we must come here 671: upon repeat in case the last REG_NOTE is a REG_NONNEG note. */ 672: if (x == 0) 673: return 0; 674: 675: code = GET_CODE (x); 676: 677: switch (code) 678: { 679: case REG: 680: i = REGNO (x); 1.1.1.4 ! root 681: ! 682: /* If we modifying the stack, frame, or argument pointer, it will ! 683: clobber a virtual register. In fact, we could be more precise, ! 684: but it isn't worth it. */ ! 685: if ((i == STACK_POINTER_REGNUM ! 686: #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM ! 687: || i == ARG_POINTER_REGNUM ! 688: #endif ! 689: || i == FRAME_POINTER_REGNUM) ! 690: && regno >= FIRST_VIRTUAL_REGISTER && regno <= LAST_VIRTUAL_REGISTER) ! 691: return 1; ! 692: 1.1 root 693: return (endregno > i 694: && regno < i + (i < FIRST_PSEUDO_REGISTER 695: ? HARD_REGNO_NREGS (i, GET_MODE (x)) 696: : 1)); 697: 698: case SUBREG: 699: /* If this is a SUBREG of a hard reg, we can see exactly which 700: registers are being modified. Otherwise, handle normally. */ 701: if (GET_CODE (SUBREG_REG (x)) == REG 702: && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER) 703: { 704: int inner_regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x); 705: int inner_endregno 706: = inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER 707: ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1); 708: 709: return endregno > inner_regno && regno < inner_endregno; 710: } 711: break; 712: 713: case CLOBBER: 714: case SET: 715: if (&SET_DEST (x) != loc 716: /* Note setting a SUBREG counts as referring to the REG it is in for 717: a pseudo but not for hard registers since we can 718: treat each word individually. */ 719: && ((GET_CODE (SET_DEST (x)) == SUBREG 720: && loc != &SUBREG_REG (SET_DEST (x)) 721: && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG 722: && REGNO (SUBREG_REG (SET_DEST (x))) >= FIRST_PSEUDO_REGISTER 723: && refers_to_regno_p (regno, endregno, 724: SUBREG_REG (SET_DEST (x)), loc)) 725: || (GET_CODE (SET_DEST (x)) != REG 726: && refers_to_regno_p (regno, endregno, SET_DEST (x), loc)))) 727: return 1; 728: 729: if (code == CLOBBER || loc == &SET_SRC (x)) 730: return 0; 731: x = SET_SRC (x); 732: goto repeat; 733: } 734: 735: /* X does not match, so try its subexpressions. */ 736: 737: fmt = GET_RTX_FORMAT (code); 738: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 739: { 740: if (fmt[i] == 'e' && loc != &XEXP (x, i)) 741: { 742: if (i == 0) 743: { 744: x = XEXP (x, 0); 745: goto repeat; 746: } 747: else 748: if (refers_to_regno_p (regno, endregno, XEXP (x, i), loc)) 749: return 1; 750: } 751: else if (fmt[i] == 'E') 752: { 753: register int j; 754: for (j = XVECLEN (x, i) - 1; j >=0; j--) 755: if (loc != &XVECEXP (x, i, j) 756: && refers_to_regno_p (regno, endregno, XVECEXP (x, i, j), loc)) 757: return 1; 758: } 759: } 760: return 0; 761: } 762: 763: /* Nonzero if modifying X will affect IN. If X is a register or a SUBREG, 764: we check if any register number in X conflicts with the relevant register 765: numbers. If X is a constant, return 0. If X is a MEM, return 1 iff IN 766: contains a MEM (we don't bother checking for memory addresses that can't 767: conflict because we expect this to be a rare case. */ 768: 769: int 770: reg_overlap_mentioned_p (x, in) 771: rtx x, in; 772: { 773: int regno, endregno; 774: 775: if (GET_CODE (x) == SUBREG) 776: { 777: regno = REGNO (SUBREG_REG (x)); 778: if (regno < FIRST_PSEUDO_REGISTER) 779: regno += SUBREG_WORD (x); 780: } 781: else if (GET_CODE (x) == REG) 782: regno = REGNO (x); 783: else if (CONSTANT_P (x)) 784: return 0; 785: else if (GET_CODE (x) == MEM) 786: { 787: char *fmt; 788: int i; 789: 790: if (GET_CODE (in) == MEM) 791: return 1; 792: 793: fmt = GET_RTX_FORMAT (GET_CODE (in)); 794: 795: for (i = GET_RTX_LENGTH (GET_CODE (in)) - 1; i >= 0; i--) 796: if (fmt[i] == 'e' && reg_overlap_mentioned_p (x, XEXP (in, i))) 797: return 1; 798: 799: return 0; 800: } 801: else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC 802: || GET_CODE (x) == CC0) 803: return reg_mentioned_p (x, in); 804: else 805: abort (); 806: 807: endregno = regno + (regno < FIRST_PSEUDO_REGISTER 808: ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1); 809: 1.1.1.2 root 810: return refers_to_regno_p (regno, endregno, in, NULL_PTR); 1.1 root 811: } 812: 813: /* Used for communications between the next few functions. */ 814: 815: static int reg_set_last_unknown; 816: static rtx reg_set_last_value; 817: static int reg_set_last_first_regno, reg_set_last_last_regno; 818: 819: /* Called via note_stores from reg_set_last. */ 820: 821: static void 822: reg_set_last_1 (x, pat) 823: rtx x; 824: rtx pat; 825: { 826: int first, last; 827: 828: /* If X is not a register, or is not one in the range we care 829: about, ignore. */ 830: if (GET_CODE (x) != REG) 831: return; 832: 833: first = REGNO (x); 834: last = first + (first < FIRST_PSEUDO_REGISTER 835: ? HARD_REGNO_NREGS (first, GET_MODE (x)) : 1); 836: 837: if (first >= reg_set_last_last_regno 838: || last <= reg_set_last_first_regno) 839: return; 840: 841: /* If this is a CLOBBER or is some complex LHS, or doesn't modify 842: exactly the registers we care about, show we don't know the value. */ 843: if (GET_CODE (pat) == CLOBBER || SET_DEST (pat) != x 844: || first != reg_set_last_first_regno 845: || last != reg_set_last_last_regno) 846: reg_set_last_unknown = 1; 847: else 848: reg_set_last_value = SET_SRC (pat); 849: } 850: 851: /* Return the last value to which REG was set prior to INSN. If we can't 852: find it easily, return 0. 853: 1.1.1.2 root 854: We only return a REG, SUBREG, or constant because it is too hard to 855: check if a MEM remains unchanged. */ 1.1 root 856: 857: rtx 858: reg_set_last (x, insn) 859: rtx x; 860: rtx insn; 861: { 862: rtx orig_insn = insn; 863: 864: reg_set_last_first_regno = REGNO (x); 865: 866: reg_set_last_last_regno 867: = reg_set_last_first_regno 868: + (reg_set_last_first_regno < FIRST_PSEUDO_REGISTER 869: ? HARD_REGNO_NREGS (reg_set_last_first_regno, GET_MODE (x)) : 1); 870: 871: reg_set_last_unknown = 0; 872: reg_set_last_value = 0; 873: 874: /* Scan backwards until reg_set_last_1 changed one of the above flags. 875: Stop when we reach a label or X is a hard reg and we reach a 876: CALL_INSN (if reg_set_last_last_regno is a hard reg). 877: 878: If we find a set of X, ensure that its SET_SRC remains unchanged. */ 879: 1.1.1.3 root 880: /* We compare with <= here, because reg_set_last_last_regno 881: is actually the number of the first reg *not* in X. */ 1.1 root 882: for (; 883: insn && GET_CODE (insn) != CODE_LABEL 884: && ! (GET_CODE (insn) == CALL_INSN 885: && reg_set_last_last_regno <= FIRST_PSEUDO_REGISTER); 886: insn = PREV_INSN (insn)) 887: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') 888: { 889: note_stores (PATTERN (insn), reg_set_last_1); 890: if (reg_set_last_unknown) 891: return 0; 892: else if (reg_set_last_value) 893: { 894: if (CONSTANT_P (reg_set_last_value) 1.1.1.2 root 895: || ((GET_CODE (reg_set_last_value) == REG 896: || GET_CODE (reg_set_last_value) == SUBREG) 1.1 root 897: && ! reg_set_between_p (reg_set_last_value, 898: NEXT_INSN (insn), orig_insn))) 899: return reg_set_last_value; 900: else 901: return 0; 902: } 903: } 904: 905: return 0; 906: } 907: 908: /* This is 1 until after reload pass. */ 909: int rtx_equal_function_value_matters; 910: 911: /* Return 1 if X and Y are identical-looking rtx's. 912: This is the Lisp function EQUAL for rtx arguments. */ 913: 914: int 915: rtx_equal_p (x, y) 916: rtx x, y; 917: { 918: register int i; 919: register int j; 920: register enum rtx_code code; 921: register char *fmt; 922: 923: if (x == y) 924: return 1; 925: if (x == 0 || y == 0) 926: return 0; 927: 928: code = GET_CODE (x); 929: /* Rtx's of different codes cannot be equal. */ 930: if (code != GET_CODE (y)) 931: return 0; 932: 933: /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. 934: (REG:SI x) and (REG:HI x) are NOT equivalent. */ 935: 936: if (GET_MODE (x) != GET_MODE (y)) 937: return 0; 938: 939: /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */ 940: 941: if (code == REG) 942: /* Until rtl generation is complete, don't consider a reference to the 943: return register of the current function the same as the return from a 944: called function. This eases the job of function integration. Once the 945: distinction is no longer needed, they can be considered equivalent. */ 946: return (REGNO (x) == REGNO (y) 947: && (! rtx_equal_function_value_matters 948: || REG_FUNCTION_VALUE_P (x) == REG_FUNCTION_VALUE_P (y))); 949: else if (code == LABEL_REF) 950: return XEXP (x, 0) == XEXP (y, 0); 951: else if (code == SYMBOL_REF) 952: return XSTR (x, 0) == XSTR (y, 0); 953: else if (code == SCRATCH || code == CONST_DOUBLE) 954: return 0; 955: 956: /* Compare the elements. If any pair of corresponding elements 957: fail to match, return 0 for the whole things. */ 958: 959: fmt = GET_RTX_FORMAT (code); 960: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 961: { 962: switch (fmt[i]) 963: { 1.1.1.2 root 964: case 'w': 965: if (XWINT (x, i) != XWINT (y, i)) 966: return 0; 967: break; 968: 1.1 root 969: case 'n': 970: case 'i': 971: if (XINT (x, i) != XINT (y, i)) 972: return 0; 973: break; 974: 975: case 'V': 976: case 'E': 977: /* Two vectors must have the same length. */ 978: if (XVECLEN (x, i) != XVECLEN (y, i)) 979: return 0; 980: 981: /* And the corresponding elements must match. */ 982: for (j = 0; j < XVECLEN (x, i); j++) 983: if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0) 984: return 0; 985: break; 986: 987: case 'e': 988: if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0) 989: return 0; 990: break; 991: 992: case 'S': 993: case 's': 994: if (strcmp (XSTR (x, i), XSTR (y, i))) 995: return 0; 996: break; 997: 998: case 'u': 999: /* These are just backpointers, so they don't matter. */ 1000: break; 1001: 1002: case '0': 1003: break; 1004: 1005: /* It is believed that rtx's at this level will never 1006: contain anything but integers and other rtx's, 1007: except for within LABEL_REFs and SYMBOL_REFs. */ 1008: default: 1009: abort (); 1010: } 1011: } 1012: return 1; 1013: } 1014: 1015: /* Call FUN on each register or MEM that is stored into or clobbered by X. 1016: (X would be the pattern of an insn). 1017: FUN receives two arguments: 1018: the REG, MEM, CC0 or PC being stored in or clobbered, 1019: the SET or CLOBBER rtx that does the store. 1020: 1021: If the item being stored in or clobbered is a SUBREG of a hard register, 1022: the SUBREG will be passed. */ 1023: 1024: void 1025: note_stores (x, fun) 1026: register rtx x; 1027: void (*fun) (); 1028: { 1029: if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)) 1030: { 1031: register rtx dest = SET_DEST (x); 1032: while ((GET_CODE (dest) == SUBREG 1033: && (GET_CODE (SUBREG_REG (dest)) != REG 1034: || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER)) 1035: || GET_CODE (dest) == ZERO_EXTRACT 1036: || GET_CODE (dest) == SIGN_EXTRACT 1037: || GET_CODE (dest) == STRICT_LOW_PART) 1038: dest = XEXP (dest, 0); 1039: (*fun) (dest, x); 1040: } 1041: else if (GET_CODE (x) == PARALLEL) 1042: { 1043: register int i; 1044: for (i = XVECLEN (x, 0) - 1; i >= 0; i--) 1045: { 1046: register rtx y = XVECEXP (x, 0, i); 1047: if (GET_CODE (y) == SET || GET_CODE (y) == CLOBBER) 1048: { 1049: register rtx dest = SET_DEST (y); 1050: while ((GET_CODE (dest) == SUBREG 1051: && (GET_CODE (SUBREG_REG (dest)) != REG 1052: || (REGNO (SUBREG_REG (dest)) 1053: >= FIRST_PSEUDO_REGISTER))) 1054: || GET_CODE (dest) == ZERO_EXTRACT 1055: || GET_CODE (dest) == SIGN_EXTRACT 1056: || GET_CODE (dest) == STRICT_LOW_PART) 1057: dest = XEXP (dest, 0); 1058: (*fun) (dest, y); 1059: } 1060: } 1061: } 1062: } 1063: 1064: /* Return nonzero if X's old contents don't survive after INSN. 1065: This will be true if X is (cc0) or if X is a register and 1066: X dies in INSN or because INSN entirely sets X. 1067: 1068: "Entirely set" means set directly and not through a SUBREG, 1069: ZERO_EXTRACT or SIGN_EXTRACT, so no trace of the old contents remains. 1070: Likewise, REG_INC does not count. 1071: 1072: REG may be a hard or pseudo reg. Renumbering is not taken into account, 1073: but for this use that makes no difference, since regs don't overlap 1074: during their lifetimes. Therefore, this function may be used 1075: at any time after deaths have been computed (in flow.c). 1076: 1077: If REG is a hard reg that occupies multiple machine registers, this 1078: function will only return 1 if each of those registers will be replaced 1079: by INSN. */ 1080: 1081: int 1082: dead_or_set_p (insn, x) 1083: rtx insn; 1084: rtx x; 1085: { 1086: register int regno, last_regno; 1087: register int i; 1088: 1089: /* Can't use cc0_rtx below since this file is used by genattrtab.c. */ 1090: if (GET_CODE (x) == CC0) 1091: return 1; 1092: 1093: if (GET_CODE (x) != REG) 1094: abort (); 1095: 1096: regno = REGNO (x); 1097: last_regno = (regno >= FIRST_PSEUDO_REGISTER ? regno 1098: : regno + HARD_REGNO_NREGS (regno, GET_MODE (x)) - 1); 1099: 1100: for (i = regno; i <= last_regno; i++) 1101: if (! dead_or_set_regno_p (insn, i)) 1102: return 0; 1103: 1104: return 1; 1105: } 1106: 1107: /* Utility function for dead_or_set_p to check an individual register. Also 1108: called from flow.c. */ 1109: 1110: int 1111: dead_or_set_regno_p (insn, test_regno) 1112: rtx insn; 1113: int test_regno; 1114: { 1115: int regno, endregno; 1116: rtx link; 1117: 1118: /* See if there is a death note for something that includes TEST_REGNO. */ 1119: for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) 1120: { 1121: if (REG_NOTE_KIND (link) != REG_DEAD || GET_CODE (XEXP (link, 0)) != REG) 1122: continue; 1123: 1124: regno = REGNO (XEXP (link, 0)); 1125: endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1 1126: : regno + HARD_REGNO_NREGS (regno, 1127: GET_MODE (XEXP (link, 0)))); 1128: 1129: if (test_regno >= regno && test_regno < endregno) 1130: return 1; 1131: } 1132: 1133: if (GET_CODE (PATTERN (insn)) == SET) 1134: { 1135: rtx dest = SET_DEST (PATTERN (insn)); 1136: 1137: /* A value is totally replaced if it is the destination or the 1138: destination is a SUBREG of REGNO that does not change the number of 1139: words in it. */ 1140: if (GET_CODE (dest) == SUBREG 1141: && (((GET_MODE_SIZE (GET_MODE (dest)) 1142: + UNITS_PER_WORD - 1) / UNITS_PER_WORD) 1143: == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) 1144: + UNITS_PER_WORD - 1) / UNITS_PER_WORD))) 1145: dest = SUBREG_REG (dest); 1146: 1147: if (GET_CODE (dest) != REG) 1148: return 0; 1149: 1150: regno = REGNO (dest); 1151: endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1 1152: : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest))); 1153: 1154: return (test_regno >= regno && test_regno < endregno); 1155: } 1156: else if (GET_CODE (PATTERN (insn)) == PARALLEL) 1157: { 1158: register int i; 1159: 1160: for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) 1161: { 1162: rtx body = XVECEXP (PATTERN (insn), 0, i); 1163: 1164: if (GET_CODE (body) == SET || GET_CODE (body) == CLOBBER) 1165: { 1166: rtx dest = SET_DEST (body); 1167: 1168: if (GET_CODE (dest) == SUBREG 1169: && (((GET_MODE_SIZE (GET_MODE (dest)) 1170: + UNITS_PER_WORD - 1) / UNITS_PER_WORD) 1171: == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) 1172: + UNITS_PER_WORD - 1) / UNITS_PER_WORD))) 1173: dest = SUBREG_REG (dest); 1174: 1175: if (GET_CODE (dest) != REG) 1176: continue; 1177: 1178: regno = REGNO (dest); 1179: endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1 1180: : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest))); 1181: 1182: if (test_regno >= regno && test_regno < endregno) 1183: return 1; 1184: } 1185: } 1186: } 1187: 1188: return 0; 1189: } 1190: 1191: /* Return the reg-note of kind KIND in insn INSN, if there is one. 1192: If DATUM is nonzero, look for one whose datum is DATUM. */ 1193: 1194: rtx 1195: find_reg_note (insn, kind, datum) 1196: rtx insn; 1197: enum reg_note kind; 1198: rtx datum; 1199: { 1200: register rtx link; 1201: 1202: for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) 1203: if (REG_NOTE_KIND (link) == kind 1204: && (datum == 0 || datum == XEXP (link, 0))) 1205: return link; 1206: return 0; 1207: } 1208: 1209: /* Return the reg-note of kind KIND in insn INSN which applies to register 1.1.1.3 root 1210: number REGNO, if any. Return 0 if there is no such reg-note. Note that 1211: the REGNO of this NOTE need not be REGNO if REGNO is a hard register; 1212: it might be the case that the note overlaps REGNO. */ 1.1 root 1213: 1214: rtx 1215: find_regno_note (insn, kind, regno) 1216: rtx insn; 1217: enum reg_note kind; 1218: int regno; 1219: { 1220: register rtx link; 1221: 1222: for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) 1223: if (REG_NOTE_KIND (link) == kind 1224: /* Verify that it is a register, so that scratch and MEM won't cause a 1225: problem here. */ 1226: && GET_CODE (XEXP (link, 0)) == REG 1.1.1.3 root 1227: && REGNO (XEXP (link, 0)) <= regno 1228: && ((REGNO (XEXP (link, 0)) 1229: + (REGNO (XEXP (link, 0)) >= FIRST_PSEUDO_REGISTER ? 1 1230: : HARD_REGNO_NREGS (REGNO (XEXP (link, 0)), 1231: GET_MODE (XEXP (link, 0))))) 1232: > regno)) 1.1 root 1233: return link; 1234: return 0; 1235: } 1236: 1237: /* Remove register note NOTE from the REG_NOTES of INSN. */ 1238: 1239: void 1240: remove_note (insn, note) 1241: register rtx note; 1242: register rtx insn; 1243: { 1244: register rtx link; 1245: 1246: if (REG_NOTES (insn) == note) 1247: { 1248: REG_NOTES (insn) = XEXP (note, 1); 1249: return; 1250: } 1251: 1252: for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) 1253: if (XEXP (link, 1) == note) 1254: { 1255: XEXP (link, 1) = XEXP (note, 1); 1256: return; 1257: } 1258: 1259: abort (); 1260: } 1261: 1.1.1.4 ! root 1262: /* Nonzero if X contains any volatile instructions. These are instructions ! 1263: which may cause unpredictable machine state instructions, and thus no ! 1264: instructions should be moved or combined across them. This includes ! 1265: only volatile asms and UNSPEC_VOLATILE instructions. */ ! 1266: ! 1267: int ! 1268: volatile_insn_p (x) ! 1269: rtx x; ! 1270: { ! 1271: register RTX_CODE code; ! 1272: ! 1273: code = GET_CODE (x); ! 1274: switch (code) ! 1275: { ! 1276: case LABEL_REF: ! 1277: case SYMBOL_REF: ! 1278: case CONST_INT: ! 1279: case CONST: ! 1280: case CONST_DOUBLE: ! 1281: case CC0: ! 1282: case PC: ! 1283: case REG: ! 1284: case SCRATCH: ! 1285: case CLOBBER: ! 1286: case ASM_INPUT: ! 1287: case ADDR_VEC: ! 1288: case ADDR_DIFF_VEC: ! 1289: case CALL: ! 1290: case MEM: ! 1291: return 0; ! 1292: ! 1293: case UNSPEC_VOLATILE: ! 1294: /* case TRAP_IF: This isn't clear yet. */ ! 1295: return 1; ! 1296: ! 1297: case ASM_OPERANDS: ! 1298: if (MEM_VOLATILE_P (x)) ! 1299: return 1; ! 1300: } ! 1301: ! 1302: /* Recursively scan the operands of this expression. */ ! 1303: ! 1304: { ! 1305: register char *fmt = GET_RTX_FORMAT (code); ! 1306: register int i; ! 1307: ! 1308: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) ! 1309: { ! 1310: if (fmt[i] == 'e') ! 1311: { ! 1312: if (volatile_refs_p (XEXP (x, i))) ! 1313: return 1; ! 1314: } ! 1315: if (fmt[i] == 'E') ! 1316: { ! 1317: register int j; ! 1318: for (j = 0; j < XVECLEN (x, i); j++) ! 1319: if (volatile_refs_p (XVECEXP (x, i, j))) ! 1320: return 1; ! 1321: } ! 1322: } ! 1323: } ! 1324: return 0; ! 1325: } ! 1326: 1.1 root 1327: /* Nonzero if X contains any volatile memory references 1328: UNSPEC_VOLATILE operations or volatile ASM_OPERANDS expressions. */ 1329: 1330: int 1331: volatile_refs_p (x) 1332: rtx x; 1333: { 1334: register RTX_CODE code; 1335: 1336: code = GET_CODE (x); 1337: switch (code) 1338: { 1339: case LABEL_REF: 1340: case SYMBOL_REF: 1341: case CONST_INT: 1342: case CONST: 1343: case CONST_DOUBLE: 1344: case CC0: 1345: case PC: 1346: case REG: 1347: case SCRATCH: 1348: case CLOBBER: 1349: case ASM_INPUT: 1350: case ADDR_VEC: 1351: case ADDR_DIFF_VEC: 1352: return 0; 1353: 1354: case CALL: 1355: case UNSPEC_VOLATILE: 1356: /* case TRAP_IF: This isn't clear yet. */ 1357: return 1; 1358: 1359: case MEM: 1360: case ASM_OPERANDS: 1361: if (MEM_VOLATILE_P (x)) 1362: return 1; 1363: } 1364: 1365: /* Recursively scan the operands of this expression. */ 1366: 1367: { 1368: register char *fmt = GET_RTX_FORMAT (code); 1369: register int i; 1370: 1371: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1372: { 1373: if (fmt[i] == 'e') 1374: { 1375: if (volatile_refs_p (XEXP (x, i))) 1376: return 1; 1377: } 1378: if (fmt[i] == 'E') 1379: { 1380: register int j; 1381: for (j = 0; j < XVECLEN (x, i); j++) 1382: if (volatile_refs_p (XVECEXP (x, i, j))) 1383: return 1; 1384: } 1385: } 1386: } 1387: return 0; 1388: } 1389: 1390: /* Similar to above, except that it also rejects register pre- and post- 1391: incrementing. */ 1392: 1393: int 1394: side_effects_p (x) 1395: rtx x; 1396: { 1397: register RTX_CODE code; 1398: 1399: code = GET_CODE (x); 1400: switch (code) 1401: { 1402: case LABEL_REF: 1403: case SYMBOL_REF: 1404: case CONST_INT: 1405: case CONST: 1406: case CONST_DOUBLE: 1407: case CC0: 1408: case PC: 1409: case REG: 1410: case SCRATCH: 1411: case ASM_INPUT: 1412: case ADDR_VEC: 1413: case ADDR_DIFF_VEC: 1414: return 0; 1415: 1416: case CLOBBER: 1417: /* Reject CLOBBER with a non-VOID mode. These are made by combine.c 1418: when some combination can't be done. If we see one, don't think 1419: that we can simplify the expression. */ 1420: return (GET_MODE (x) != VOIDmode); 1421: 1422: case PRE_INC: 1423: case PRE_DEC: 1424: case POST_INC: 1425: case POST_DEC: 1426: case CALL: 1427: case UNSPEC_VOLATILE: 1428: /* case TRAP_IF: This isn't clear yet. */ 1429: return 1; 1430: 1431: case MEM: 1432: case ASM_OPERANDS: 1433: if (MEM_VOLATILE_P (x)) 1434: return 1; 1435: } 1436: 1437: /* Recursively scan the operands of this expression. */ 1438: 1439: { 1440: register char *fmt = GET_RTX_FORMAT (code); 1441: register int i; 1442: 1443: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1444: { 1445: if (fmt[i] == 'e') 1446: { 1447: if (side_effects_p (XEXP (x, i))) 1448: return 1; 1449: } 1450: if (fmt[i] == 'E') 1451: { 1452: register int j; 1453: for (j = 0; j < XVECLEN (x, i); j++) 1454: if (side_effects_p (XVECEXP (x, i, j))) 1455: return 1; 1456: } 1457: } 1458: } 1459: return 0; 1460: } 1461: 1462: /* Return nonzero if evaluating rtx X might cause a trap. */ 1463: 1464: int 1465: may_trap_p (x) 1466: rtx x; 1467: { 1468: int i; 1469: enum rtx_code code; 1470: char *fmt; 1471: 1472: if (x == 0) 1473: return 0; 1474: code = GET_CODE (x); 1475: switch (code) 1476: { 1477: /* Handle these cases quickly. */ 1478: case CONST_INT: 1479: case CONST_DOUBLE: 1480: case SYMBOL_REF: 1481: case LABEL_REF: 1482: case CONST: 1483: case PC: 1484: case CC0: 1485: case REG: 1486: case SCRATCH: 1487: return 0; 1488: 1489: /* Conditional trap can trap! */ 1490: case UNSPEC_VOLATILE: 1491: case TRAP_IF: 1492: return 1; 1493: 1494: /* Memory ref can trap unless it's a static var or a stack slot. */ 1495: case MEM: 1496: return rtx_addr_can_trap_p (XEXP (x, 0)); 1497: 1498: /* Division by a non-constant might trap. */ 1499: case DIV: 1500: case MOD: 1501: case UDIV: 1502: case UMOD: 1503: if (! CONSTANT_P (XEXP (x, 1))) 1504: return 1; 1505: /* This was const0_rtx, but by not using that, 1506: we can link this file into other programs. */ 1507: if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0) 1508: return 1; 1509: default: 1510: /* Any floating arithmetic may trap. */ 1511: if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) 1512: return 1; 1513: } 1514: 1515: fmt = GET_RTX_FORMAT (code); 1516: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1517: { 1518: if (fmt[i] == 'e') 1519: { 1520: if (may_trap_p (XEXP (x, i))) 1521: return 1; 1522: } 1523: else if (fmt[i] == 'E') 1524: { 1525: register int j; 1526: for (j = 0; j < XVECLEN (x, i); j++) 1527: if (may_trap_p (XVECEXP (x, i, j))) 1528: return 1; 1529: } 1530: } 1531: return 0; 1532: } 1533: 1534: /* Return nonzero if X contains a comparison that is not either EQ or NE, 1535: i.e., an inequality. */ 1536: 1537: int 1538: inequality_comparisons_p (x) 1539: rtx x; 1540: { 1541: register char *fmt; 1542: register int len, i; 1543: register enum rtx_code code = GET_CODE (x); 1544: 1545: switch (code) 1546: { 1547: case REG: 1548: case SCRATCH: 1549: case PC: 1550: case CC0: 1551: case CONST_INT: 1552: case CONST_DOUBLE: 1553: case CONST: 1554: case LABEL_REF: 1555: case SYMBOL_REF: 1556: return 0; 1557: 1558: case LT: 1559: case LTU: 1560: case GT: 1561: case GTU: 1562: case LE: 1563: case LEU: 1564: case GE: 1565: case GEU: 1566: return 1; 1567: } 1568: 1569: len = GET_RTX_LENGTH (code); 1570: fmt = GET_RTX_FORMAT (code); 1571: 1572: for (i = 0; i < len; i++) 1573: { 1574: if (fmt[i] == 'e') 1575: { 1576: if (inequality_comparisons_p (XEXP (x, i))) 1577: return 1; 1578: } 1579: else if (fmt[i] == 'E') 1580: { 1581: register int j; 1582: for (j = XVECLEN (x, i) - 1; j >= 0; j--) 1583: if (inequality_comparisons_p (XVECEXP (x, i, j))) 1584: return 1; 1585: } 1586: } 1587: 1588: return 0; 1589: } 1590: 1591: /* Replace any occurrence of FROM in X with TO. 1592: 1593: Note that copying is not done so X must not be shared unless all copies 1594: are to be modified. */ 1595: 1596: rtx 1597: replace_rtx (x, from, to) 1598: rtx x, from, to; 1599: { 1600: register int i, j; 1601: register char *fmt; 1602: 1603: if (x == from) 1604: return to; 1605: 1606: /* Allow this function to make replacements in EXPR_LISTs. */ 1607: if (x == 0) 1608: return 0; 1609: 1610: fmt = GET_RTX_FORMAT (GET_CODE (x)); 1611: for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) 1612: { 1613: if (fmt[i] == 'e') 1614: XEXP (x, i) = replace_rtx (XEXP (x, i), from, to); 1615: else if (fmt[i] == 'E') 1616: for (j = XVECLEN (x, i) - 1; j >= 0; j--) 1617: XVECEXP (x, i, j) = replace_rtx (XVECEXP (x, i, j), from, to); 1618: } 1619: 1620: return x; 1621: } 1622: 1623: /* Throughout the rtx X, replace many registers according to REG_MAP. 1624: Return the replacement for X (which may be X with altered contents). 1625: REG_MAP[R] is the replacement for register R, or 0 for don't replace. 1626: NREGS is the length of REG_MAP; regs >= NREGS are not mapped. 1627: 1628: We only support REG_MAP entries of REG or SUBREG. Also, hard registers 1629: should not be mapped to pseudos or vice versa since validate_change 1630: is not called. 1631: 1632: If REPLACE_DEST is 1, replacements are also done in destinations; 1633: otherwise, only sources are replaced. */ 1634: 1635: rtx 1636: replace_regs (x, reg_map, nregs, replace_dest) 1637: rtx x; 1638: rtx *reg_map; 1639: int nregs; 1640: int replace_dest; 1641: { 1642: register enum rtx_code code; 1643: register int i; 1644: register char *fmt; 1645: 1646: if (x == 0) 1647: return x; 1648: 1649: code = GET_CODE (x); 1650: switch (code) 1651: { 1652: case SCRATCH: 1653: case PC: 1654: case CC0: 1655: case CONST_INT: 1656: case CONST_DOUBLE: 1657: case CONST: 1658: case SYMBOL_REF: 1659: case LABEL_REF: 1660: return x; 1661: 1662: case REG: 1663: /* Verify that the register has an entry before trying to access it. */ 1664: if (REGNO (x) < nregs && reg_map[REGNO (x)] != 0) 1665: return reg_map[REGNO (x)]; 1666: return x; 1667: 1668: case SUBREG: 1669: /* Prevent making nested SUBREGs. */ 1670: if (GET_CODE (SUBREG_REG (x)) == REG && REGNO (SUBREG_REG (x)) < nregs 1671: && reg_map[REGNO (SUBREG_REG (x))] != 0 1672: && GET_CODE (reg_map[REGNO (SUBREG_REG (x))]) == SUBREG) 1673: { 1674: rtx map_val = reg_map[REGNO (SUBREG_REG (x))]; 1675: rtx map_inner = SUBREG_REG (map_val); 1676: 1677: if (GET_MODE (x) == GET_MODE (map_inner)) 1678: return map_inner; 1679: else 1680: { 1681: /* We cannot call gen_rtx here since we may be linked with 1682: genattrtab.c. */ 1683: /* Let's try clobbering the incoming SUBREG and see 1684: if this is really safe. */ 1685: SUBREG_REG (x) = map_inner; 1686: SUBREG_WORD (x) += SUBREG_WORD (map_val); 1687: return x; 1688: #if 0 1689: rtx new = rtx_alloc (SUBREG); 1690: PUT_MODE (new, GET_MODE (x)); 1691: SUBREG_REG (new) = map_inner; 1692: SUBREG_WORD (new) = SUBREG_WORD (x) + SUBREG_WORD (map_val); 1693: #endif 1694: } 1695: } 1696: break; 1697: 1698: case SET: 1699: if (replace_dest) 1700: SET_DEST (x) = replace_regs (SET_DEST (x), reg_map, nregs, 0); 1701: 1702: else if (GET_CODE (SET_DEST (x)) == MEM 1703: || GET_CODE (SET_DEST (x)) == STRICT_LOW_PART) 1704: /* Even if we are not to replace destinations, replace register if it 1705: is CONTAINED in destination (destination is memory or 1706: STRICT_LOW_PART). */ 1707: XEXP (SET_DEST (x), 0) = replace_regs (XEXP (SET_DEST (x), 0), 1708: reg_map, nregs, 0); 1709: else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT) 1710: /* Similarly, for ZERO_EXTRACT we replace all operands. */ 1711: break; 1712: 1713: SET_SRC (x) = replace_regs (SET_SRC (x), reg_map, nregs, 0); 1714: return x; 1715: } 1716: 1717: fmt = GET_RTX_FORMAT (code); 1718: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1719: { 1720: if (fmt[i] == 'e') 1721: XEXP (x, i) = replace_regs (XEXP (x, i), reg_map, nregs, replace_dest); 1722: if (fmt[i] == 'E') 1723: { 1724: register int j; 1725: for (j = 0; j < XVECLEN (x, i); j++) 1726: XVECEXP (x, i, j) = replace_regs (XVECEXP (x, i, j), reg_map, 1727: nregs, replace_dest); 1728: } 1729: } 1730: return x; 1731: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.