|
|
1.1 ! root 1: /* Analyze RTL for C-Compiler ! 2: Copyright (C) 1987, 1988, 1991, 1992, 1993 Free Software Foundation, Inc. ! 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 ! 57: || REGNO (x) == HARD_FRAME_POINTER_REGNUM ! 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. */ ! 100: return ! (x == frame_pointer_rtx || x == hard_frame_pointer_rtx ! 101: || x == arg_pointer_rtx); ! 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. */ ! 137: return ! (x == frame_pointer_rtx || x == hard_frame_pointer_rtx ! 138: || x == stack_pointer_rtx || x == arg_pointer_rtx); ! 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: ! 189: HOST_WIDE_INT ! 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; ! 477: int i, j; ! 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--) ! 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: ! 542: return 1; ! 543: ! 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: ! 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 ! 591: && (! find_reg_note (insn, REG_UNUSED, ! 592: SET_DEST (XVECEXP (PATTERN (insn), 0, i))) ! 593: || side_effects_p (XVECEXP (PATTERN (insn), 0, i)))) ! 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); ! 624: rtx note = find_reg_note (p, REG_EQUAL, NULL_RTX); ! 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); ! 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: ! 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: ! 810: return refers_to_regno_p (regno, endregno, in, NULL_PTR); ! 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: ! 854: We only return a REG, SUBREG, or constant because it is too hard to ! 855: check if a MEM remains unchanged. */ ! 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: ! 880: /* We compare with <= here, because reg_set_last_last_regno ! 881: is actually the number of the first reg *not* in X. */ ! 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) ! 895: || ((GET_CODE (reg_set_last_value) == REG ! 896: || GET_CODE (reg_set_last_value) == SUBREG) ! 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: { ! 964: case 'w': ! 965: if (XWINT (x, i) != XWINT (y, i)) ! 966: return 0; ! 967: break; ! 968: ! 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 ! 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. */ ! 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 ! 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)) ! 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: ! 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: ! 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.