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